导出视频始终失败

时间:2015-12-04 11:45:32

标签: ios swift avfoundation

我正在尝试使用录制的语音复合视频。所以我做了这样的代码

func saveMediaCompaundWithMovie(videoAsset: AVAsset) {
    let url = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sample", ofType: "mov")!)
    let videoAsset = AVAsset(URL: url)

    let mutableComposition = AVMutableComposition()
    let videoCompositionTrack = mutableComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
    let videoAssetTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo).first
    let range = CMTimeRange(start: kCMTimeZero, duration: videoAssetTrack!.timeRange.duration)
    do { try videoCompositionTrack.insertTimeRange(range, ofTrack: videoAssetTrack!, atTime: kCMTimeZero) } catch {}
    let videoSize = videoAssetTrack?.naturalSize

    let audioCompositionTrack = mutableComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
    let audioAsset = AVAsset(URL: self.recorder.url)  //MARK: self.recorder.url is voice data.And I checked this data is correctly played.
    let audioAssetTrack = audioAsset.tracksWithMediaType(AVMediaTypeAudio).first
    let maxDuration = audioAssetTrack!.timeRange.duration
    do { try audioCompositionTrack.insertTimeRange(range, ofTrack: audioAssetTrack!, atTime: kCMTimeZero) } catch {}

    let exporter = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPresetHighestQuality)
    let documents = NSFileManager.defaultManager().URLsForDirectory(.DocumentationDirectory, inDomains: .UserDomainMask)[0].path
    let fileName = NSURL(string: documents!)?.URLByAppendingPathComponent("compound").URLByAppendingPathExtension("mov")
    exporter?.outputURL = fileName

    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRange(start: kCMTimeZero, duration: maxDuration)
    let videoComp = AVMutableVideoComposition()
    videoComp.renderSize = videoSize!
    videoComp.frameDuration = CMTimeMake(1, 30)
    videoComp.instructions = [instruction]

    exporter?.outputFileType = AVFileTypeQuickTimeMovie
    exporter?.shouldOptimizeForNetworkUse = true
    exporter?.videoComposition = videoComp
    exporter?.timeRange = range
    exporter?.exportAsynchronouslyWithCompletionHandler({ () -> Void in
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            switch (exporter!.status) {
            case AVAssetExportSessionStatus.Completed:
                print("suceed to save")
                break
            case AVAssetExportSessionStatus.Cancelled:
                print("canceled")
                break
            case AVAssetExportSessionStatus.Failed:
                print("failed")
                print(exporter?.error?.localizedDescription)
                print(exporter?.error?.userInfo.description)
                print(exporter?.error?.localizedFailureReason)
                print(exporter?.error?.localizedRecoverySuggestion)
                break
            default:
                break;
            }
        })
    })

}

然后总是AVAssetExportSessionStatus失败。控制台日志就是那样

failed
Optional("Operation Stopped")
Optional("[NSLocalizedDescription: Operation Stopped,          NSLocalizedFailureReason: The video could not be composed.]")
Optional("The video could not be composed.")

有人会注意到错误吗?我希望你的帮助。 谢谢。

1 个答案:

答案 0 :(得分:0)

尝试替换此行

let fileName = NSURL(string: documents!)?.URLByAppendingPathComponent("compound").URLByAppendingPathExtension("mov")

用这个

let fileName = URL(fileURLWithPath: (documents?.appending("/compound.MOV"))!)

我遇到了同样的问题。以这种方式设置输出URL使其工作。但不确定其根本原因。