Home > Mobile >  How can I change the speed of a video?
How can I change the speed of a video?

Time:05-31

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

  • Related