【问题标题】:AVURLAsset returning empty array-Trying to Concatenate two filesAVURLAsset 返回空数组-尝试连接两个文件
【发布时间】:2020-08-27 11:22:06
【问题描述】:

我正在尝试连接两个(多个)音频文件。我在Concatenate Two Audio Files Swift 找到了相关的帖子和​​解决方案

解决办法如下:


func mergeAudioFiles(audioFileUrls: NSArray) {
    let composition = AVMutableComposition()

    for i in 0 ..< audioFileUrls.count {

        let compositionAudioTrack :AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())

        let asset = AVURLAsset(url: (audioFileUrls[i] as! NSURL) as URL)

        let track = asset.tracks(withMediaType: AVMediaTypeAudio)[0]

        let timeRange = CMTimeRange(start: CMTimeMake(0, 600), duration: track.timeRange.duration)

        try! compositionAudioTrack.insertTimeRange(timeRange, of: track, at: composition.duration)
    }

    let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
    self.mergeAudioURL = documentDirectoryURL.appendingPathComponent("FinalAudio.m4a")! as URL as NSURL

    let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)
    assetExport?.outputFileType = AVFileTypeAppleM4A
    assetExport?.outputURL = mergeAudioURL as URL
    assetExport?.exportAsynchronously(completionHandler:
        {
            switch assetExport!.status
            {
            case AVAssetExportSessionStatus.failed:
                print("failed \(assetExport?.error)")
            case AVAssetExportSessionStatus.cancelled:
                print("cancelled \(assetExport?.error)")
            case AVAssetExportSessionStatus.unknown:
                print("unknown\(assetExport?.error)")
            case AVAssetExportSessionStatus.waiting:
                print("waiting\(assetExport?.error)")
            case AVAssetExportSessionStatus.exporting:
                print("exporting\(assetExport?.error)")
            default:
                print("Audio Concatenation Complete")
            }
    })
}

有些参数已经过时了,我使用了 Xcode 的建议修复,导致:

        let composition = AVMutableComposition()

        for i in 0 ..< audioFileUrls.count {

            let compositionAudioTrack :AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: CMPersistentTrackID())!

            let asset : AVURLAsset = AVURLAsset(url: (audioFileUrls[i] as! NSURL) as URL)

            let track : AVAssetTrack = asset.tracks(withMediaType: AVMediaType.audio)[0]

            let timeRange = CMTimeRange(start: CMTimeMake(value: 0, timescale: 600), duration: track.timeRange.duration)
            try! compositionAudioTrack.insertTimeRange(timeRange, of: track, at: composition.duration)
        }

        let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
        self.mergeAudioURL = documentDirectoryURL.appendingPathComponent("FinalAudio.m4a")! as URL as NSURL

        let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)
        assetExport?.outputFileType = AVFileType.m4a
        assetExport?.outputURL = mergeAudioURL as URL
        assetExport?.exportAsynchronously(completionHandler:
            {
                switch assetExport!.status
                {
                case AVAssetExportSessionStatus.failed:
                    print("failed \(assetExport?.error)")
                case AVAssetExportSessionStatus.cancelled:
                    print("cancelled \(assetExport?.error)")
                case AVAssetExportSessionStatus.unknown:
                    print("unknown\(assetExport?.error)")
                case AVAssetExportSessionStatus.waiting:
                    print("waiting\(assetExport?.error)")
                case AVAssetExportSessionStatus.exporting:
                    print("exporting\(assetExport?.error)")
                default:
                    print("Audio Concatenation Complete")
                }
        })

        print("asset url \(mergeAudioURL)")
    }

当我使用我得到的解决方案时

2020-05-11 13:09:14.771381-0600 TimeCapsule[88538:12022916] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'

错误发生在let track = asset.tracks(withMediaType: AVMediaTypeAudio)[0] 行。在该行之前,打印输出显示asset.tracks.count = 0asset.trackGroups.count = 0。当我删除行尾的[0]索引时,以下行会引发错误“track has no member '时间范围'”。我不知道如何将轨道添加到我新创建的资产中,以便我可以使用资产音频持续时间。任何帮助将不胜感激,我假设它只是新 Swift 的过时语法。

【问题讨论】:

  • 确保您的文件有效

标签: swift avmutablecomposition avurlasset


【解决方案1】:

错误很明显

let tracks = asset.tracks(withMediaType: AVMediaTypeAudio)
guard !tracks.isEmpty else { return }
let track = tracks.first!

您尝试连接的文件没有音轨,因此数组为空

【讨论】:

  • 那么如何添加音轨,使其不返回? NSURL 是一个保存的音频文件,所以我不确定如何获取音轨/为什么它不是资产的一部分?
  • 您是否尝试将该 url 上的文件作为音频播放?并检查它是否有效?代码正确问题出在文件中
【解决方案2】:

请注意,每次'url'都会改变沙盒环境,我之前也遇到过这个问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-31
    • 2019-04-03
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 2013-08-29
    相关资源
    最近更新 更多