【问题标题】:iOS audio conversion from AVMutableComposition to AVAudioPlayer从 AVMutableComposition 到 AVAudioPlayer 的 iOS 音频转换
【发布时间】:2015-01-13 04:28:00
【问题描述】:

我一直在寻找解决方案,但到目前为止我找不到。

现在我正在使用 AVMutableComposition 创建一个音频文件,并使用 AVAssetExportSession 将其写入磁盘,这样我就可以使用 AVAudioPlayer 加载它并在特定时间播放它。将其写入磁盘需要花费大量时间这一事实会减慢速度,并且在某些情况下会使我的应用程序非常慢。

音频的创建部分花费的时间很少,所以我想知道是否将文件导出到磁盘我可以像 NSData 或其他东西一样导出它,这样我就可以在 AVAudioPlayer 中使用它而无需从磁盘写入/读取


代码 让 soundPath = "temp" let filepath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundPath, ofType: "wav")!)

    var songAsset = AVURLAsset(URL: filepath, options: nil)

    var track = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
    var source: AnyObject = songAsset.tracksWithMediaType(AVMediaTypeAudio)[0]

    var startTime = CMTimeMakeWithSeconds(0, 44100)
    var time_insert = CMTimeMakeWithSeconds(atTime, 44100)
    var trackDuration = songAsset.duration
    var longestTime = CMTimeMake(882000, 44100)
    var timeRange = CMTimeRangeMake(startTime, longestTime)

    var trackMix = AVMutableAudioMixInputParameters(track: track)
    trackMix.setVolume(volume, atTime: startTime)
    audioMixParams.insert(trackMix, atIndex: audioMixParams.count)

    track.insertTimeRange(timeRange, ofTrack: source as AVAssetTrack, atTime: time_insert, error: nil)

这会在一个循环中发生多次,生成一个完整的轨道

终于用上了

    var exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)
    exporter.audioMix = audioMix
    exporter.outputFileType = "com.apple.m4a-audio"
    exporter.outputURL = NSURL(fileURLWithPath: fileName)

    exporter.exportAsynchronouslyWithCompletionHandler({
        switch exporter.status{
        case  AVAssetExportSessionStatus.Failed:
            println("failed \(exporter.error)")
        case AVAssetExportSessionStatus.Cancelled:
            println("cancelled \(exporter.error)")
        default:
            println("complete")
            callback()
        }
    })

导出文件。

然后它会调用一个回调来加载声音并在一段时间内循环播放。

我不使用普通循环属性循环的事实是每个文件的长度可能与 loopDuration 不同

    callback: {

        self.fillSoundArray()
        self.fillSoundArray()
        self.fillSoundArray()
    }


private func fillSoundArray() {
    var currentloop = self.current_loop++

    let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
    var fileName = documentsPath + "/temp.mp4"

    var tempAudio = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: fileName), error: nil)
    if (self.start_time == 0) {
        self.start_time = tempAudio.deviceCurrentTime
    }

    queue.insert(tempAudio, atIndex: queue.count)
    tempAudio.prepareToPlay()
    tempAudio.delegate = self
    tempAudio.playAtTime(start_time + currentloop*self.loopDuration)
}

【问题讨论】:

    标签: ios avaudioplayer avmutablecomposition


    【解决方案1】:

    使用 AVPlayerItem 和 AVPlayer 快速预览您的音频合成

    AVPlayerItem*  previewPlayerItem = [[AVPlayerItem alloc] initWithAsset:mutableCompositionMain 
                                              automaticallyLoadedAssetKeys:@[@"tracks",@"duration"]];
    previewPlayerItem.videoComposition = mutableVideoComposition;
    AVPlayer* previewPlayer = [[AVPlayer alloc] initWithPlayerItem:previewPlayerItem ];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(dismisPreviewPlayer:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:[previewPlayer currentItem]];
    

    【讨论】:

    • 谢谢你的回答,我的问题不是再现音频,是在那之后我必须以一种定时循环播放它(音频长度可能与循环长度不同)这就是为什么我想使用 AVAudioPlayer
    • 我添加了一些代码,希望它不会让它更难理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 2017-10-17
    • 2014-03-18
    • 1970-01-01
    相关资源
    最近更新 更多