我正在尝试使用录制的语音复合视频。所以我做了这样的代码
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.")
有人会注意到错误吗?我希望你的帮助。 谢谢。
答案 0 :(得分:0)
尝试替换此行
let fileName = NSURL(string: documents!)?.URLByAppendingPathComponent("compound").URLByAppendingPathExtension("mov")
用这个
let fileName = URL(fileURLWithPath: (documents?.appending("/compound.MOV"))!)
我遇到了同样的问题。以这种方式设置输出URL使其工作。但不确定其根本原因。