我有几个 h.264 quicktime 视频,我想将它们连接成一个带有过渡(淡入/淡出)的视频。以下代码应接受 AVAsset 数组并将它们插入 AVMutableVideoComposition。但我不断从 AVAssetExportSession 得到 -11841!请帮我找出问题所在。
index = Int(0)
let mutableComposition = AVMutableComposition()
var currentTime = kCMTimeZero
// Transition relate
let timeOffsetBetweenVideos = CMTimeMakeWithSeconds(1, 30)
let videoComposition = AVMutableVideoComposition()
var videoCompInstructions: [AVMutableVideoCompositionInstruction] = []
let compositionAudioTrack = mutableComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
var lastCompositionVideoTrack: AVMutableCompositionTrack? = nil
for asset in movieAssets as! [AVAsset] {
// Add video track into composition
let compositionVideoTrack = mutableComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
let videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0]
try compositionVideoTrack.insertTimeRange(videoTrack.timeRange, ofTrack: videoTrack, atTime: currentTime)
compositionVideoTrack.scaleTimeRange(videoTrack.timeRange, toDuration: CMTimeAdd(asset.duration, timeOffsetBetweenVideos))
// Add audio track into composition
let audioTrack = asset.tracksWithMediaType(AVMediaTypeAudio)[0]
try compositionAudioTrack.insertTimeRange(audioTrack.timeRange, ofTrack: audioTrack, atTime: currentTime)
if index > 0 {
let fromLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: lastCompositionVideoTrack!)
let transitionTimeRange = CMTimeRangeMake(currentTime, timeOffsetBetweenVideos)
fromLayerInstruction.setOpacityRampFromStartOpacity(1.0, toEndOpacity: 0.5, timeRange: transitionTimeRange)
let toLayerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: compositionVideoTrack)
toLayerInstruction.setOpacityRampFromStartOpacity(0.5, toEndOpacity: 1.0, timeRange: transitionTimeRange)
let videoCompositionInstruction = AVMutableVideoCompositionInstruction()
videoCompositionInstruction.timeRange = transitionTimeRange
videoCompositionInstruction.layerInstructions = [fromLayerInstruction, toLayerInstruction]
videoCompInstructions.append(videoCompositionInstruction)
}
lastCompositionVideoTrack = compositionVideoTrack
lastVideoTrack = videoTrack
currentTime = CMTimeAdd(currentTime, asset.duration)
++index
}
let exportSesstion = AVAssetExportSession(asset: mutableComposition, presetName: AVAssetExportPresetHighestQuality)
exportSesstion?.outputFileType = AVFileTypeQuickTimeMovie
exportSesstion?.outputURL = retFileUrl
if movieAssets.count > 1 {
videoComposition.instructions = videoCompInstructions
videoComposition.renderSize = mutableComposition.naturalSize
print("frame size: \(mutableComposition.naturalSize)")
videoComposition.renderScale = 1.0
videoComposition.frameDuration = CMTimeMake(1, 30)
exportSesstion?.videoComposition = videoComposition
}
exportSesstion?.exportAsynchronouslyWithCompletionHandler({ () -> Void in
if exportSesstion?.status == AVAssetExportSessionStatus.Completed {
print("Video file exported: \(retFileUrl)")
} else {
print(exportSesstion!.error!)
print("Failed exporting video: \(exportSesstion?.error?.localizedDescription)")
print(exportSesstion?.error?.localizedFailureReason)
}
})