我必须将视频转换为慢动作与音频使用帧基方法。以下链接是很多的帮助,这是 反向资产效率
在解决方案中,我可以改变缓冲区的时间戳,实现慢动作视频。
for sample in videoSamples {
var presentationTime = CMSampleBufferGetPresentationTimeStamp(sample)
//Changing Timestamp to achieve slow-motion
presentationTime.timescale = presentationTime.timescale * 2
let imageBufferRef = CMSampleBufferGetImageBuffer(sample)
while !videoWriterInput.isReadyForMoreMediaData {
Thread.sleep(forTimeInterval: 0.1)
}
pixelBufferAdaptor.append(imageBufferRef!, withPresentationTime: presentationTime)
}
对于音频慢动作,我试图改变音频样本的时间戳,但它没有效果。
有什么办法可以解决音频慢动作的问题吗。
如果你有Objective-C的解决方案,欢迎发上来。谢谢。
根据你想要的音频听起来像什么,你可以尝试使用手动喂养苹果的时间间距音频单位与音频样本数据改变其长度,以匹配你的新的时间戳之间的时间。
你可以做一个简单的慢动作,使用 AVMutableComposition
. 正如@hotpaw2所提到的,有不止一种方法可以减慢你的音频--例如你可以降低音调或保持音调不变。这个解决方案似乎是保持音调不变,我没有看到任何改变的方法。也许这就是你想要的。也许不是。
你可以使用 AVAssetExportSession
将慢速视频写入文件,由于 AVMutableComposition
是(也许令人惊讶的)一个子类的 AVAsset
,您可以使用 AVPlayer
即使你没有导出视频的慢动作版本。
let asset = AVURLAsset(url: Bundle.main.url(forResource: "video", withExtension: "mp4")! , options : nil)
let srcVideoTrack = asset.tracks(withMediaType: .video).first!
let srcAudioTrack = asset.tracks(withMediaType: .audio).first!
let sloMoComposition = AVMutableComposition()
let sloMoVideoTrack = sloMoComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)!
let sloMoAudioTrack = sloMoComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)!
let assetTimeRange = CMTimeRange(start: .zero, duration: asset.duration)
try! sloMoVideoTrack.insertTimeRange(assetTimeRange, of: srcVideoTrack, at: .zero)
try! sloMoAudioTrack.insertTimeRange(assetTimeRange, of: srcAudioTrack, at: .zero)
let newDuration = CMTimeMultiplyByFloat64(assetTimeRange.duration, multiplier: 2)
sloMoVideoTrack.scaleTimeRange(assetTimeRange, toDuration: newDuration)
sloMoAudioTrack.scaleTimeRange(assetTimeRange, toDuration: newDuration)
// you can play sloMoComposition in an AVPlayer at this point
// Export to a file using AVAssetExportSession
let exportSession = AVAssetExportSession(asset: sloMoComposition, presetName: AVAssetExportPresetPassthrough)!
exportSession.outputFileType = .mp4
exportSession.outputURL = getDocumentsDirectory().appendingPathComponent("slow-mo-\(Date.timeIntervalSinceReferenceDate).mp4")
exportSession.exportAsynchronously {
assert(exportSession.status == .completed)
print("File in \(exportSession.outputURL!)")
}