iOS - swift - 使用AVFoundation合并视频

时间:2014-08-20 11:15:43

标签: ios swift avfoundation avassetexportsession

我试图在一个独特的输出中合并一些视频.mov。导出的文件不可播放,我现在不知道为什么。有人能帮助我吗?

func exportVideo2(path:String, outputPath:String, nMovie:Int) -> Bool{
    var composition = AVMutableComposition()
    let track:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
    var insertTime = kCMTimeZero

    var movie = movieOfProject(path) 
    if movie.count == nMovie{
        for (index,mov) in enumerate(movie){
            let moviePath = path.stringByAppendingPathComponent(mov)
            // moviePath = path to the .mov file 
            println(moviePath)
            let moviePathUrl = NSURL(fileURLWithPath: moviePath)
            let sourceAsset = AVURLAsset(URL: moviePathUrl, options: nil)
            println(sourceAsset)
            let tracks = sourceAsset.tracksWithMediaType(AVMediaTypeVideo)
            println(sourceAsset.playable) // print true
            println(sourceAsset.exportable) // print true
            println(sourceAsset.readable) // print true
            if tracks.count > 0{
                let assetTrack:AVAssetTrack = tracks[0] as AVAssetTrack
                track.insertTimeRange(CMTimeRangeMake(kCMTimeZero,sourceAsset.duration), ofTrack: assetTrack, atTime: insertTime, error: nil)
                insertTime = CMTimeAdd(insertTime, sourceAsset.duration)
            }
        }
        let completeMovie = outputPath.stringByAppendingPathComponent("movie.mov")
        let completeMovieUrl = NSURL(fileURLWithPath: completeMovie)
        var exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
        exporter.outputURL = completeMovieUrl
        exporter.outputFileType = AVFileTypeMPEG4
        exporter.exportAsynchronouslyWithCompletionHandler(nil)
        let ass = AVURLAsset(URL: completeMovieUrl, options: nil)
        println(ass.readable) // print false
        println(ass.exportable) // print false
        println(ass.playable) // print false
        return true
    }else{
        return false
    }
} 

我必须合并的.mov文件都是可读的,所以我认为问题出在输出视频导出的最后一部分。

1 个答案:

答案 0 :(得分:8)

解决。

func exportVideo3(path:String, outputPath:String, nMovie:Int) -> Bool{
    var composition = AVMutableComposition()
    let trackVideo:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())
    let trackAudio:AVMutableCompositionTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
    var insertTime = kCMTimeZero

    var movie = movieOfProject(path)
    if movie.count == nMovie{
        for (index,mov) in enumerate(movie){
            let moviePath = path.stringByAppendingPathComponent(mov)
            let moviePathUrl = NSURL(fileURLWithPath: moviePath)
            let sourceAsset = AVURLAsset(URL: moviePathUrl, options: nil)

            let tracks = sourceAsset.tracksWithMediaType(AVMediaTypeVideo)
            let audios = sourceAsset.tracksWithMediaType(AVMediaTypeAudio)

            if tracks.count > 0{
                let assetTrack:AVAssetTrack = tracks[0] as AVAssetTrack
                trackVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero,sourceAsset.duration), ofTrack: assetTrack, atTime: insertTime, error: nil)
                   let assetTrackAudio:AVAssetTrack = audios[0] as AVAssetTrack
                  trackAudio.insertTimeRange(CMTimeRangeMake(kCMTimeZero,sourceAsset.duration), ofTrack: assetTrackAudio, atTime: insertTime, error: nil)
                insertTime = CMTimeAdd(insertTime, sourceAsset.duration)
            }
        }

        let completeMovie = outputPath.stringByAppendingPathComponent("movie.mov")
        let completeMovieUrl = NSURL(fileURLWithPath: completeMovie)
        var exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)
        exporter.outputURL = completeMovieUrl
        exporter.outputFileType = AVFileTypeMPEG4 //AVFileTypeQuickTimeMovie
        exporter.exportAsynchronouslyWithCompletionHandler({
            switch exporter.status{
            case  AVAssetExportSessionStatus.Failed:
                println("failed \(exporter.error)")
            case AVAssetExportSessionStatus.Cancelled:
                println("cancelled \(exporter.error)")
            default:
                println("complete")
            }
        })
        return true
    }else{
        return false
    }
}