With Swift, I am getting a video from avcapturefileoutput, but I want to speed it up say 2x speed. How can I do this?
CodePudding user response:
/* play video twice as fast */
document.querySelector('video').defaultPlaybackRate = 2.0;
document.querySelector('video').play();
CodePudding user response:
This is all I needed:
speedVideoTrack?.scaleTimeRange(assetTimeRange, toDuration: newDuration)
speedAudioTrack?.scaleTimeRange(assetTimeRange, toDuration: newDuration)
Full speed adjusting func:
private func speedUpVideo(url: URL, completion: @escaping (_ url: URL) -> Void) {
do {
let asset = AVAsset(url: url)
guard let videoTrack = asset.tracks(withMediaType: .video).first else { return }
guard let audioTrack = asset.tracks(withMediaType: .audio).first else { return }
let speedComposition = AVMutableComposition()
let speedVideoTrack = speedComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
let speedAudioTrack = speedComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
speedVideoTrack?.preferredTransform = videoTrack.preferredTransform
let assetTimeRange = CMTimeRange(start: .zero, duration: asset.duration)
try speedVideoTrack?.insertTimeRange(assetTimeRange, of: videoTrack, at: .zero)
try speedAudioTrack?.insertTimeRange(assetTimeRange, of: audioTrack, at: .zero)
let newDuration = CMTimeMultiplyByFloat64(assetTimeRange.duration, multiplier: 0.5)
speedVideoTrack?.scaleTimeRange(assetTimeRange, toDuration: newDuration)
speedAudioTrack?.scaleTimeRange(assetTimeRange, toDuration: newDuration)
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long
let date = dateFormatter.string(from: NSDate() as Date)
let savePath = (documentDirectory as NSString).appendingPathComponent("storySocial-\(date).mp4")
let url = NSURL(fileURLWithPath: savePath)
guard let exporter = AVAssetExportSession(asset: speedComposition, presetName: AVAssetExportPreset1920x1080) else { return }
exporter.outputURL = url as URL
exporter.outputFileType = .mp4
exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronously {
guard let url = exporter.outputURL else {
print("ERROR")
return
}
completion(url)
}
} catch {
print("ERRRRROOORRRR")
}
}
The two lines above are responsible for adjusting the speed of a track, everything else conforms to the necessary protocols. I also want to put emphasis that I am already familiar with AVMutableComposition, and if you want to use this solution I recommend doing some research first on it, there are a lot of small quirks that make it work, as you can see it takes quite a few lines just to adjust the speed.ss