使用AVFoundation类播放音频文件的参考部分

时间:2017-06-28 22:41:16

标签: ios swift audio avfoundation

目标:我需要循环播放音频文件的任意切片。

当前解决方案:

  • 第一个工作解决方案使用MPMusicPlayerController :: systemMusicPlayer和Timer。这基本上有效,但有一些问题。首先,在改变切片的位置/持续时间的某个时刻,UI将锁定(具体地,触摸输入)。奇怪的是,在我执行完所有代码之后它会发生~1s,但由于我无法控制很多代码,我最终将其归结为不是一个可行的解决方案。
  • 第二种解决方案目前使用相同的基本设置,但我使用的是AVFoundation :: AVAudioPlayer。我刚刚开始实现,但我已经注意到循环是相当不一致的。

我目前正处于第二个解决方案循环的阶段,但尚未达到我可以测试UI是否锁定的程度。

问题:我正在查看AVFoundation中的可用方法,并想到了: “是否可以引用音频文件的精确块并循环,根据需要更改块?“ 。我找不到的东西,我认为这可能是由于我缺乏正确搜索它的命名法,是这样的例子。

我想尽可能使用内置框架。

1 个答案:

答案 0 :(得分:0)

在最终找到一些好的例子之后,我提出了:

let composition = AVMutableComposition()
var playerItem:AVPlayerItem!
var qPlayer:AVQueuePlayer!
var currentAudioTrack:AVAssetTrack!
var compAudioTrack:AVMutableCompositionTrack!
var uurl:URL!
var asset:AVURLAsset!

...

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
    } catch let error {
        print("i am error:", error)
    }
    compAudioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID())
    uurl = (sysMusicPlayer.nowPlayingItem?.assetURL)!
    asset = AVURLAsset(url: uurl)
    currentAudioTrack = asset.tracks(withMediaType: AVMediaTypeAudio)[0]
    assetTimeScale = currentAudioTrack.naturalTimeScale
    let a:CMTime = CMTime(seconds: 10, preferredTimescale: assetTimeScale)
    let b:CMTime = CMTime(seconds: 42, preferredTimescale: assetTimeScale)
    try! compAudioTrack.insertTimeRange(CMTimeRange(start: a, end: b), of: currentAudioTrack, at: CMTimeMake(0, 1))
    playerItem = AVPlayerItem(asset: composition)
    qPlayer = AVQueuePlayer(playerItem: playerItem)
    qPlayer.play()

这是基本功能,让我可以通过

轻松更改歌曲的当前部分
    compAudioTrack.segments.removeAll()
    try! compAudioTrack.insertTimeRange(timeRangeToInsert, of: currentAudioTrack, at: CMTimeMake(0, 1))
    qPlayer.insert(playerItem, after: nil)