如何在合并音频和视频时循环音频

时间:2017-01-14 06:06:40

标签: ios swift audio video merge

我按照此代码合并音频和视频文件。它很棒。假设,音频长度为5秒,视频长度为20秒。当我在导出的视频中合并这些文件时,5秒后没有声音。这很明显,因为我的音频长度为5秒。但是可以在整个视频会话中循环运行音频。

var finalVideoURL = NSURL()
var finalVideoName = String()

func mergeAudio&VideoFiles(videoUrl:NSURL, audioUrl:NSURL){
    let mixComposition : AVMutableComposition = AVMutableComposition()
    var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
    var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
    let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
    //start merge
    let aVideoAsset : AVAsset = AVAsset(url: videoUrl as URL)
    let aAudioAsset : AVAsset = AVAsset(url: audioUrl as URL)
    mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
    mutableCompositionAudioTrack.append( mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
    let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
    let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0]
    do{
        try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero)
        try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero)
    }catch{

    }
    totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration )
    let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition()
    mutableVideoComposition.frameDuration = CMTimeMake(1, 30)
    mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720)
    finalVideoURL = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/FinalVideo.mp4")
    finalVideoName = "FinalVideo.mp4"
    let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
    assetExport.outputFileType = AVFileTypeMPEG4
    assetExport.outputURL = finalVideoURL as URL
    assetExport.shouldOptimizeForNetworkUse = true
    assetExport.exportAsynchronously { () -> Void in
        switch assetExport.status {
        case AVAssetExportSessionStatus.completed:
            print("Export movie to document directory from trimmed audio and mutable video complete :)")
        case  AVAssetExportSessionStatus.failed:
            print("failed \(assetExport.error)")
        case AVAssetExportSessionStatus.cancelled:
            print("cancelled \(assetExport.error)")
        default:
            print("complete")
        }
    }
}

1 个答案:

答案 0 :(得分:3)

很久以前有人问过它,但它肯定可以在将来帮助某个人, 您可以通过多次插入AVAssetTrack的时间范围来做到这一点:

let vDuration = aVideoAsset.duration
let audioAssetTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
do {
    var currentDuration = CMTime.zero
    while currentDuration < vDuration {
        let restTime = CMTimeSubtract(vDuration, currentDuration)
        let maxTime = CMTimeMinimum(aAudioAsset.duration, restTime)
        try audioAssetTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: maxTime),
                                          of: aAudioAsset.tracks(withMediaType: .audio)[0],
                                          at: currentDuration)
        currentDuration = CMTimeAdd(currentDuration, aAudioAsset.duration)
    }
} catch {
     print("Failed to load audio track")
     continue
}