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
相关产品推荐
相关产品推荐

