swift 在Swift中使用AVFoundation修剪视频

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift 在Swift中使用AVFoundation修剪视频相关的知识,希望对你有一定的参考价值。

//
//  TrimVideo.swift
//  VideoLab
//
//  Created by Adam Jensen on 3/28/15.
//  Copyright (c) 2015 Adam Jensen. All rights reserved.
//

import AVFoundation
import Foundation

typealias TrimCompletion = (NSError?) -> ()

typealias TrimPoints = [(CMTime, CMTime)]

func verifyPresetForAsset(preset: String, asset: AVAsset) -> Bool {
    let compatiblePresets = AVAssetExportSession.exportPresetsCompatibleWithAsset(asset) as! [String]
    let filteredPresets = compatiblePresets.filter { $0 == preset }
    
    return filteredPresets.count > 0 || preset == AVAssetExportPresetPassthrough
}

func removeFileAtURLIfExists(url: NSURL) {
    if let filePath = url.path {
        let fileManager = NSFileManager.defaultManager()
        if fileManager.fileExistsAtPath(filePath) {
            var error: NSError?
            
            if !fileManager.removeItemAtPath(filePath, error: &error) {
                NSLog("Couldn't remove existing destination file: \(error)")
            }
        }
    }
}

func trimVideo(sourceURL: NSURL, destinationURL: NSURL, trimPoints: TrimPoints, completion: TrimCompletion?) {
    assert(sourceURL.fileURL)
    assert(destinationURL.fileURL)
    
    let options = [ AVURLAssetPreferPreciseDurationAndTimingKey: true ]
    let asset = AVURLAsset(URL: sourceURL, options: options)
    let preferredPreset = AVAssetExportPresetPassthrough
    if verifyPresetForAsset(preferredPreset, asset) {
        let composition = AVMutableComposition()
        let videoCompTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
        let audioCompTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
        
        let assetVideoTrack: AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first as! AVAssetTrack
        let assetAudioTrack: AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first as! AVAssetTrack
        
        var compError: NSError?
        
        var accumulatedTime = kCMTimeZero
        for (startTimeForCurrentSlice, endTimeForCurrentSlice) in trimPoints {
            let durationOfCurrentSlice = CMTimeSubtract(endTimeForCurrentSlice, startTimeForCurrentSlice)
            let timeRangeForCurrentSlice = CMTimeRangeMake(startTimeForCurrentSlice, durationOfCurrentSlice)
            
            videoCompTrack.insertTimeRange(timeRangeForCurrentSlice, ofTrack: assetVideoTrack, atTime: accumulatedTime, error: &compError)
            audioCompTrack.insertTimeRange(timeRangeForCurrentSlice, ofTrack: assetAudioTrack, atTime: accumulatedTime, error: &compError)
            
            if compError != nil {
                NSLog("error during composition: \(compError)")
                if let completion = completion {
                    completion(compError)
                }
            }
            
            accumulatedTime = CMTimeAdd(accumulatedTime, durationOfCurrentSlice)
        }
        
        let exportSession = AVAssetExportSession(asset: composition, presetName: preferredPreset)
        exportSession.outputURL = destinationURL
        exportSession.outputFileType = AVFileTypeAppleM4V
        exportSession.shouldOptimizeForNetworkUse = true
        
        removeFileAtURLIfExists(destinationURL)
        
        exportSession.exportAsynchronouslyWithCompletionHandler({ () -> Void in
            if let completion = completion {
                completion(exportSession.error)
            }
        })
    } else {
        NSLog("Could not find a suitable export preset for the input video")
        let error = NSError(domain: "org.linuxguy.VideoLab", code: -1, userInfo: nil)
        if let completion = completion {
            completion(error)
        }
    }
}

let sourceURL = NSURL(fileURLWithPath: "/Users/acj/scratch/TestVideo.mp4")
let destinationURL = NSURL(fileURLWithPath: "/Users/acj/scratch/TrimmedVideo.mp4")

let sem = dispatch_semaphore_create(0)

if let sourceURL = sourceURL, destinationURL = destinationURL {
    let timeScale: Int32 = 1000
    
    let trimPoints = [(CMTimeMake(2000, timeScale), CMTimeMake(5000, timeScale)),
                      (CMTimeMake(20500, timeScale), CMTimeMake(23000, timeScale)),
                      (CMTimeMake(60000, timeScale), CMTimeMake(65000, timeScale))]
    
    trimVideo(sourceURL, destinationURL, trimPoints) { error in
        if let error = error {
            NSLog("Failure: \(error)")
        } else {
            NSLog("Success")
        }
        
        dispatch_semaphore_signal(sem)
    }
} else {
    NSLog("error: Please check the source and destination paths.")
}

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER)

以上是关于swift 在Swift中使用AVFoundation修剪视频的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 项目中使用 Objective C 类中的 Swift 类

在 Swift 项目中使用 Objective C 类中的 Swift 类

swift 在swift中使用javascriptcore

swift 在swift中使用枚举练习

swift 在Swift中使用日期,日历。

swift 在Swift中使用AVFoundation修剪视频