合并视频但AVAssetExportSession永远不会完成

时间:2015-09-27 14:39:41

标签: ios video swift2 avassetexportsession

尝试将一些视频合并在一起并将它们作为单个文件导出,从查看教程/示例看,一切似乎都是正确的但是我的AVAssetExportSession似乎永远不会完整,我的视频文件永远不会导出,任何有关的帮助我非常感激,这是一个非常明显的错误。

以下是合并视频的功能

注意循环中的'视频'是一个成员变量if a == a ( echo they are the same. echo yes, they are. ) else ( echo they are different, echo not the same. ) ,它会在调用merge之前填充(我会检查它)。

var videos = [AVAsset]()

下面显示了在调用private func merge() { // Create AVMutableComposition to contain all AVMutableComposition tracks var mix_composition = AVMutableComposition() var total_time_seconds = 0.0 var tracks = [AVCompositionTrack]() // Loop over videos and create tracks, keep incrementing total duration for video in videos { // Create the composition track for this video let track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) // Add video duration to total time total_time_seconds = total_time_seconds + video.duration.seconds // Add track to array of tracks tracks.append(track) // Add time range to track do { try track.insertTimeRange(CMTimeRangeMake(kCMTimeZero, video.duration), ofTrack: video.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: video.duration) } catch _ { } } // Set total time let preferred_time_scale: Int32 = 600; let total_time = CMTimeMakeWithSeconds(total_time_seconds, preferred_time_scale) // Create main instrcution for video composition let main_instruction = AVMutableVideoCompositionInstruction() main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, total_time) // Create array to hold instructions var layer_instructions = [AVVideoCompositionLayerInstruction]() // Ensure we have the same number of tracks as videos if videos.count == tracks.count { // Loop number of videos and tracks for var index = 0; index < videos.count; ++index { // Create compositioninstruction for each track let instruction = videoCompositionInstructionForTrack(tracks[index], asset: videos[index]) if(index == 0) { instruction.setOpacity(0.0, atTime: videos[index].duration) } // Add instruction to instructions array layer_instructions.append(instruction) } } // Set tack instructions to main instruction main_instruction.layerInstructions = layer_instructions let main_composition = AVMutableVideoComposition() main_composition.instructions = [main_instruction] main_composition.frameDuration = CMTimeMake(1, 30) main_composition.renderSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height) // Get path for Final video in the current project directory let documents_url = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] let final_url = documents_url.URLByAppendingPathComponent("TEST.mp4") // Create AV Export Session let exporter = AVAssetExportSession(asset: mix_composition, presetName: AVAssetExportPresetHighestQuality) exporter!.outputURL = final_url exporter!.outputFileType = AVFileTypeMPEG4 exporter!.shouldOptimizeForNetworkUse = true exporter!.videoComposition = main_composition // Perform the Export exporter!.exportAsynchronouslyWithCompletionHandler() { dispatch_async(dispatch_get_main_queue(), { () -> Void in self.exportDidFinish(exporter!) }) } } 时调用的exportDidFinished函数。我进入这个函数,但没有任何事情发生,因为会话状态永远不会完成。

exportAsynchronouslyWithCompletionHandler

打印会话状态显示4是失败的,所以我打印了session.error并得到了这个,但我不确定它意味着什么,任何帮助都会很棒

func exportDidFinish(session: AVAssetExportSession)
{
    if session.status == AVAssetExportSessionStatus.Completed
    {
        let outputURL = session.outputURL
        let library = ALAssetsLibrary()
        if library.videoAtPathIsCompatibleWithSavedPhotosAlbum(outputURL)
        {
            library.writeVideoAtPathToSavedPhotosAlbum(outputURL,
                completionBlock: { (assetURL:NSURL!, error:NSError!) -> Void in
                    if error != nil
                    {
                        let alert = UIAlertView(title: "Error", message: "Video Not Saved", delegate: nil, cancelButtonTitle: "OK")
                        alert.show()

                    }
                    else
                    {
                        let alert = UIAlertView(title: "Success", message: "Video Saved", delegate: nil, cancelButtonTitle: "OK")
                        alert.show()
                    }
            })
        }
    }
}

1 个答案:

答案 0 :(得分:3)

如果调用exportDidFinish但没有任何反应,则会话的状态不是AVAssetExportSessionStatus.Completed。它可能是AVAssetExportSessionStatus.Failed或其他一些值。检查这些值,如果确实失败,请检查session.error属性以获取更多信息。

编辑:如果您希望一个又一个视频播放,请只创建一个AVMutableCompositionTrack。请参阅下面的相关更改:

    ...
    var mix_composition = AVMutableComposition()

    // Create the composition track for the videos
    let track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

    //keep track of total time
    var totalTime = kCMTimeZero

    for video in videos
    {
        // Add time range to track
        do
        {
            let videoTrack = video.tracksWithMediaType(AVMediaTypeVideo)[0]
            let videoDuration = videoTrack.duration
            let timeRange = CMTimeRangeMake(kCMTimeZero,videoDuration)

            try track.insertTimeRange(timeRange, ofTrack: videoTrack, atTime: totalTime)

            totalTime = CMTimeAdd(totalTime,videoDuration)
        }
        catch _
        {
        }
    }

    // Create main instruction for video composition
    let main_instruction = AVMutableVideoCompositionInstruction()
    main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, totalTime)

    // Create array to hold instructions
    var layer_instructions = [AVVideoCompositionLayerInstruction]()

    // Create layer instruction
    let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)

    // Add it to the array
    layer_instructions.append(layerInstruction)

    ...

您还需要将renderSize调整为适当的值。您的视频大小可能与屏幕大小不同。