【问题标题】:Issue while merging Video & Audio iOS swift4合并视频和音频iOS swift 4时出现问题
【发布时间】:2019-08-31 12:35:42
【问题描述】:
2019-04-10 10:49:51.590008+0500 VTKaraokeView[869:1039603] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'

您好 iOS 大师!我正在合并视频和音频文件(.mp4 和 .mp3 文件)...

背景和问题陈述:-

当我正在开发像卡拉 OK 这样的应用程序时...我正在录制带有背景音乐的视频,然后将录制的视频和背景音乐合并到新的 newVideo.mp4 文件中,然后播放.newVideo.mp4 进入 AVPlayerViewController... 因为这很完美,但问题是当我录制的视频超过近 10 秒时,我就会遇到上述异常。并且此异常发生在这一行 let aAudioOfVideoTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeAudio)[0]

func mergeFilesWithUrl(videoUrl: URL, audioUrl:URL)
{
    let savePathUrl : NSURL = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/newVideo.mp4")

    do { // delete old video
        try FileManager.default.removeItem(at: savePathUrl as URL)
    } catch { print(error.localizedDescription) }


    let mixComposition : AVMutableComposition = AVMutableComposition()
    var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
    var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
    var mutableCompositionAudioOfVideoTrack : [AVMutableCompositionTrack] = []
    let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()

    //start merge
    let aVideoAsset : AVAsset = AVAsset(url: videoUrl)
    let aAudioAsset : AVAsset = AVAsset(url: audioUrl)

    mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
    mutableCompositionAudioTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
    mutableCompositionAudioOfVideoTrack.append( mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))

    let aAudioOfVideoTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeAudio)[0] // HERE i'm getting Error...Index Array Out Of Bound... 
    let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
    let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0]

    do{
        try mutableCompositionAudioOfVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioOfVideoTrack , at: kCMTimeZero)
        try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero)

        //In my case my audio file is longer then video file so i took videoAsset duration
        //instead of audioAsset duration

        try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero)

        //Use this instead above line if your audiofile and video file's playing durations are same

        //            try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), ofTrack: aAudioAssetTrack, atTime: 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)//CGSize(1280,720)




    finalPath = savePathUrl.absoluteString

    let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
    assetExport.outputFileType = AVFileTypeMPEG4
    assetExport.outputURL = savePathUrl as URL
    assetExport.shouldOptimizeForNetworkUse = true

    assetExport.exportAsynchronously { () -> Void in
        switch assetExport.status {

        case AVAssetExportSessionStatus.completed:
            print("success")
        case  AVAssetExportSessionStatus.failed:
            print("failed \(assetExport.error)")
        case AVAssetExportSessionStatus.cancelled:
            print("cancelled \(assetExport.error)")
        default:
            print("complete")
        }
    }


}

【问题讨论】:

  • 在访问之前检查您的数组计数
  • 如果录制的视频几乎小于 10 秒,则 ARRAY COUNT 为 1,如果超过 10/12 秒,则 ARRAY COUNT 为 0...所以为什么会崩溃...
  • 我不确定记录的时间,但是由于数组为空而发生,您需要搜索有关记录问题
  • 是的,我知道它的发生是由于阵列...但不知道原因...

标签: ios iphone swift3 swift4 avmutablecomposition


【解决方案1】:

花了将近 1 天的时间来解决这个问题,这是解决这个问题的完美解决方案......

经过iOS 8 iPad AVCaptureMovieFileOutput drops / loses / never gets audio track after 13 - 14 seconds of recording的帮助很多...

只需添加这一行,就可以发挥魅力

avCaptureMovieFileOutput.movieFragmentInterval = kCMTimeInvalid

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2021-08-05
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多