我有一个 .wav 格式的简单音频文件(音频文件经过完美剪切以循环播放)。我尝试了不同的方法来循环它。我的第一次尝试只是简单地使用 AVPlayer 和 NSNotification 来检测 audioItem 何时结束以在零处寻找时间并再次播放。但是,显然存在差距。
我一直在网上查看不同的解决方案,发现有人使用 AVQueuePlayer 进行切换: Looping AVPlayer seamlessly
但是,在实现时,这仍然会产生差距。
这是我当前的通知代码:
weak var weakSelf = self
NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: nil, queue: nil, usingBlock: {(note: NSNotification) -> Void in
if weakSelf?.currentQueuePlayer.currentItem == weakSelf?.currentAudioItemOne {
weakSelf?.currentQueuePlayer.insertItem((weakSelf?.currentAudioItemTwo)!, afterItem: nil)
weakSelf?.currentAudioItemTwo.seekToTime(kCMTimeZero)
} else {
weakSelf?.currentQueuePlayer.insertItem((weakSelf?.currentAudioItemOne)!, afterItem: nil)
weakSelf?.currentAudioItemOne.seekToTime(kCMTimeZero)
}
})
这是我设置当前 QueuePlayer 的代码。
let audioPlayerItem = AVPlayerItem(URL: url)
currentAudioItemOne = audioPlayerItem
currentAudioItemTwo = audioPlayerItem
currentQueuePlayer = AVQueuePlayer()
currentQueuePlayer.insertItem(currentAudioItemOne, afterItem: nil)
currentQueuePlayer.play()
几天来我一直在研究这个问题。任何线索或尝试的新事物将不胜感激。到目前为止我唯一没有尝试过的是低质量的音频文件。这些 .wav 文件都超过 1mb,并且怀疑文件大小可能会影响无缝循环。
编辑:
使用 AVPlayerLooper 创建“运行机”效果:
let url = URL(fileURLWithPath: path)
let audioPlayerItem = AVPlayerItem(url: url)
currentAudioItemOne = audioPlayerItem
currentQueuePlayer = AVQueuePlayer()
currentAudioPlayerLayer = AVPlayerLayer(player: currentQueuePlayer)
currentAudioLooper = AVPlayerLooper(player: currentQueuePlayer, templateItem: currentAudioItemOne)
currentQueuePlayer.play()
编辑 2:
关于我的一个 wav 文件的 afinfo:
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer
no channel layout.
estimated duration: 11.302336 sec
audio bytes: 1993732
audio packets: 498433
bit rate: 1411200 bits per second
packet size upper bound: 4
maximum packet size: 4
audio data file offset: 44
not optimized
source bit depth: I16
----
最佳答案
您在当前解决方案中插入项目的时间太晚了。您需要排队多个初始项目,因此总有一个准备就绪的 AVPlayerItem
。
这被称为 AVPlayerQueue
“运行机模式” better described in this WWDC 2016 session .如果你的目标是 iOS 10,你可以使用新的 AVPlayerLooper
类来为你做这件事(也在同一个链接中描述)。 Apple 还提供了 sample project它提供了两种策略的示例。
较低级别的解决方案包括将音频缓冲区排队到 AVAudioEngine
实例或使用 AudioQueue
或自己将缓冲区与 AudioUnit
混合在一起.
关于ios - 我正在尝试使用 AVQueuePlayer 创建无缝音频循环,但是,我不知道为什么循环之间会有一个小的无声停顿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39441621/