You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS如何实现视频3倍提速且保持原30FPS,将18秒转6秒?

保持30FPS同时加速视频到6秒的解决方案

当然可以实现!你当前的方法之所以会把帧率提升到90FPS,是因为直接缩放时间范围时,原视频的所有帧都被完整保留了——18秒30FPS的视频总共有540帧,塞进6秒里自然就变成了90FPS。要达到6秒时长+30FPS的效果,我们需要让导出过程丢弃多余的帧,只保留每3帧中的1帧,同时压缩时间线。

具体实现步骤

核心思路是:先按你的方式压缩时间范围,再通过AVMutableVideoComposition强制指定输出帧率,让导出器自动采样帧。

import AVFoundation

// 假设你已经有了原视频的asset对象
let asset: AVAsset = // 你的原视频资源

// 1. 创建合成对象和视频轨道
let composition = AVMutableComposition()
guard let sourceVideoTrack = asset.tracks(withMediaType: .video).first else {
    print("找不到视频轨道")
    return
}
let compositionVideoTrack = composition.addMutableTrack(
    withMediaType: .video,
    preferredTrackID: kCMPersistentTrackID_Invalid
)!

// 2. 按你的方法缩放时间范围,将18秒压缩到6秒
let newDuration = CMTimeMultiplyByFloat64(asset.duration, 1/3)
do {
    try compositionVideoTrack.scaleTimeRange(
        CMTimeRangeMake(start: kCMTimeZero, duration: asset.duration),
        toDuration: newDuration
    )
} catch {
    print("缩放时间范围失败:\(error)")
    return
}

// 3. 关键:创建视频合成,强制设置输出帧率为30FPS
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = sourceVideoTrack.naturalSize
videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30) // 每秒30帧

// 添加合成指令
let videoInstruction = AVMutableVideoCompositionInstruction()
videoInstruction.timeRange = CMTimeRangeMake(start: kCMTimeZero, duration: newDuration)
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack)
videoInstruction.layerInstructions = [layerInstruction]
videoComposition.instructions = [videoInstruction]

// 4. 配置导出会话并开始导出
guard let exportSession = AVAssetExportSession(
    asset: composition,
    presetName: AVVideoExportPresetHighestQuality
) else {
    print("创建导出会话失败")
    return
}

exportSession.videoComposition = videoComposition
exportSession.outputFileType = .mp4
exportSession.outputURL = // 替换成你的输出文件URL(比如Documents目录下的路径)

exportSession.exportAsynchronously {
    switch exportSession.status {
    case .completed:
        print("导出成功!")
    case .failed:
        print("导出失败:\(exportSession.error?.localizedDescription ?? "未知错误")")
    case .cancelled:
        print("导出被取消")
    default:
        break
    }
}

额外说明

  • 音频处理:如果你的视频包含音频,用同样的方式缩放音频轨道即可,音频加速后不会有帧率问题,只会播放速度变快(若需要保持音调不变,可以使用AVAudioTimePitchAlgorithm,不过这是额外需求)。
  • 帧率采样逻辑:设置frameDuration后,导出器会自动从压缩后的时间线中按30FPS的间隔采样帧,最终输出的视频总帧数为 6秒 × 30FPS = 180帧,正好是原视频540帧的1/3,完美符合你的需求。

内容的提问来源于stack exchange,提问作者Francisco Alves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:45:03