2017-06-28 93 views
0

目标:我需要循环播放音频文件的任意切片。使用AVFoundation类播放的音频文件的参考部分

目前的解决方案:使用MPMusicPlayerController :: systemMusicPlayer和定时器

  • 一可行的解​​决方案。这基本上工作,但有几个问题。首先,在改变切片的位置/持续时间的某个时刻,UI将锁定(具体地,触摸输入)。奇怪的是,它会在执行完所有代码之后发生1秒,但由于我无法控制其中的大部分代码,因此我最终认为它不是一个可行的解决方案。
  • 第二个解决方案目前使用相同的基本设置,除了我使用AVFoundation :: AVAudioPlayer。我只开始实施,但我已经注意到这种循环是相当不一致的。

我目前处于第二个解决方案循环的地步,但还没有到达测试UI是否锁定的地步。

问题:我一直在寻找通过AVFoundation可用的方法和有想法:“这将有可能引用的音频文件和环路,改变块需要的精确块” 。我找不到,我认为这可能是由于我缺乏正确搜索它的术语,是这类事情的任何例子。

如果可能,我想使用内置框架。

回答

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() 

这是最基本的功能,它可以让我failr轻易改变歌曲的当前部分通过

compAudioTrack.segments.removeAll() 
    try! compAudioTrack.insertTimeRange(timeRangeToInsert, of: currentAudioTrack, at: CMTimeMake(0, 1)) 
    qPlayer.insert(playerItem, after: nil)