How to trim the video using AVFoundation

后端 未结 4 1660
醉话见心
醉话见心 2020-12-02 17:51

Iam able to record the video by using AVFoundation or UIImagePickerController. But i am unable to trim the video from one particular second to another particular duration/ti

4条回答
  •  [愿得一人]
    2020-12-02 18:32

    The best solution for swift 4, i have found there. I did fixes it for my needs, but it's really clear and convenience.

    The code:

    import AVFoundation
    import Foundation
    
    extension FileManager {
        func removeFileIfNecessary(at url: URL) throws {
            guard fileExists(atPath: url.path) else {
                return
            }
    
            do {
                try removeItem(at: url)
            }
            catch let error {
                throw TrimError("Couldn't remove existing destination file: \(error)")
            }
        }
    }
    
    struct TrimError: Error {
        let description: String
        let underlyingError: Error?
    
        init(_ description: String, underlyingError: Error? = nil) {
            self.description = "TrimVideo: " + description
            self.underlyingError = underlyingError
        }
    }
    
    extension AVMutableComposition {
        convenience init(asset: AVAsset) {
            self.init()
    
            for track in asset.tracks {
                addMutableTrack(withMediaType: track.mediaType, preferredTrackID: track.trackID)
            }
        }
    
        func trim(timeOffStart: Double) {
            let duration = CMTime(seconds: timeOffStart, preferredTimescale: 1)
            let timeRange = CMTimeRange(start: kCMTimeZero, duration: duration)
    
            for track in tracks {
                track.removeTimeRange(timeRange)
            }
    
            removeTimeRange(timeRange)
        }
    }
    
    extension AVAsset {
        func assetByTrimming(timeOffStart: Double) throws -> AVAsset {
            let duration = CMTime(seconds: timeOffStart, preferredTimescale: 1)
            let timeRange = CMTimeRange(start: kCMTimeZero, duration: duration)
    
            let composition = AVMutableComposition()
    
            do {
                for track in tracks {
                    let compositionTrack = composition.addMutableTrack(withMediaType: track.mediaType, preferredTrackID: track.trackID)
                    try compositionTrack?.insertTimeRange(timeRange, of: track, at: kCMTimeZero)
                }
            } catch let error {
                throw TrimError("error during composition", underlyingError: error)
            }
    
            return composition
        }
    
        func export(to destination: URL) throws {
            guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetPassthrough) else {
                throw TrimError("Could not create an export session")
            }
    
            exportSession.outputURL = destination
            exportSession.outputFileType = AVFileType.m4v
            exportSession.shouldOptimizeForNetworkUse = true
    
            let group = DispatchGroup()
    
            group.enter()
    
            try FileManager.default.removeFileIfNecessary(at: destination)
    
            exportSession.exportAsynchronously {
                group.leave()
            }
    
            group.wait()
    
            if let error = exportSession.error {
                throw TrimError("error during export", underlyingError: error)
            }
        }
    }
    
    func time(_ operation: () throws -> ()) rethrows {
        let start = Date()
    
        try operation()
    
        let end = Date().timeIntervalSince(start)
        print(end)
    
    let sourceURL =  URL(fileURLWithPath: CommandLine.arguments[1])
    let destinationURL = URL(fileURLWithPath: CommandLine.arguments[2])
    
    do {
        try time {
            let asset = AVURLAsset(url: sourceURL)
            let trimmedAsset = try asset.assetByTrimming(timeOffStart: 1.0)
            try trimmedAsset.export(to: destinationURL)
        }
    } catch let error {
        print("

提交回复
热议问题