Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 合并视频但AVAssetExportSession从未完成_Ios_Video_Swift2_Avassetexportsession - Fatal编程技术网

Ios 合并视频但AVAssetExportSession从未完成

Ios 合并视频但AVAssetExportSession从未完成,ios,video,swift2,avassetexportsession,Ios,Video,Swift2,Avassetexportsession,尝试将一些视频合并在一起并将其导出为单个文件,从教程/示例来看,一切似乎都是正确的。然而,我的AVAssetExportSession似乎从未完成,并且我的视频文件从未导出,对于我丢失的一个明显错误的任何帮助,我们将不胜感激 下面是我合并视频的功能 注意循环中的“videos”是一个成员变量var videos=[AVAsset](),它在调用merge之前被填充(我也检查了) private func merge() { // Create AVMutableComposition t

尝试将一些视频合并在一起并将其导出为单个文件,从教程/示例来看,一切似乎都是正确的。然而,我的AVAssetExportSession似乎从未完成,并且我的视频文件从未导出,对于我丢失的一个明显错误的任何帮助,我们将不胜感激

下面是我合并视频的功能

注意循环中的“videos”是一个成员变量
var videos=[AVAsset]()
,它在调用merge之前被填充(我也检查了)

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!)
        })
    }
}
打印会话状态显示它是4,这是失败的,所以我打印了session.error并得到了这个,但我不确定它的意思,任何帮助都会很好

Optional(Error Domain=AVFoundationErrorDomain Code=-11841 "Operation Stopped" UserInfo={NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The video could not be composed.}) 

如果调用了
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)

    ...

您还需要将渲染调整到适当的位置。视频的大小可能与屏幕大小不同

如何实际检查打印状态的值,但它只是说
“AVAssetExportSessionStatus”
print(session!.status.rawValue)。然后打印(session!.error)ok,状态4失败,我得到了这个错误'Optional(error Domain=AVFoundationErrorDomain Code=-11841“操作已停止”UserInfo={NSLocalizedDescription=Operation Stopped,NSLocalizedFailureReason=视频无法合成。}')我今晚会试试,并告诉你这是怎么回事,谢谢你的回答
    ...
    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)

    ...