ios - Swift 3 iOS - 与 AVAudioPlayer 同步暂停

标签 ios swift swift3 avaudioplayer

我正在使用 AVAudioPlayer在播放器风格的界面(播放/暂停/停止)中播放一组同步的 MP3 文件。我知道我可以使用 play(atTime:) 同步播放它们但我的问题是,如何同步暂停它们?目前,要暂停它们,我正在使用:

for (_, audioTrackPlayer) in audioTrackPlayers.enumerated() {
    audioTrackPlayer.pause()
}

当然,他们都一个接一个地停下来。没有等效的 pause(atTime:) 函数。那么如何实现暂停的精确同步呢?

编辑 - 额外信息

在马特询问它有多引人注目之后,我得到了一些数据。暂停 5 首轨道需要将近半秒的时间。为了表明这一点,我在暂停循环之后添加了一个单独的循环,以报告每个轨道上的当前时间,并且还在暂停之前添加了几个循环 - 以供引用并显示它们在开始时是同步的。

Loop benchmark, 0: 3.2118820861678
Loop benchmark, 0: 3.21580498866213
Loop benchmark, 0: 3.21888888888889
Loop benchmark, 0: 3.22126984126984
Loop benchmark, 0: 3.22328798185941

Before pause, 0: 3.22560090702948
Before pause, 1: 3.22750566893424
Before pause, 2: 3.22975056689342
Before pause, 3: 3.23185941043084
Before pause, 4: 3.23439909297052

After pause, 0: 3.35040816326531
After pause, 1: 3.46598639455782
After pause, 2: 3.56979591836735
After pause, 3: 3.67455782312925
After pause, 4: 3.77895691609977

所以在暂停之前轨道是同步的,时间差异只是由于循环的每次迭代所花费的 3 或 4 毫秒。停顿后,每首轨道之间大约有十分之一秒。

引用代码:

for _ in 0..<5 {
    print ("Loop benchmark, 0: \(audioTrackPlayers[0].currentTime)")
}
for (index, audioTrackPlayer) in audioTrackPlayers.enumerated() {
    print ("Before pause, \(index): \(audioTrackPlayer.currentTime)")
}
for audioTrackPlayer in audioTrackPlayers {
    audioTrackPlayer.pause()
}
for (index, audioTrackPlayer) in audioTrackPlayers.enumerated() {
    print ("After pause, \(index): \(audioTrackPlayer.currentTime)")
}

最佳答案

我已通过在停止或暂停音轨之前将所有音轨的音量设置为 0 来部分解决此问题。这让用户在音频方面有“即时响应”的感觉,因此主要解决了这个问题。不需要花半秒钟来暂停轨道仍然很好,所以我不接受这个答案,但它确实以可用的方式解决了问题。

示例代码(我用来演示这一点的简化版本),包括重置 currentTime 值以匹配延迟暂停后匹配的必要代码。 truncatingRemainder 是必需的,因为这些都是循环音频。

// Set volumes of all audio tracks to 0, so delay on pause is not noticed
for audioTrackPlayer in audioTrackPlayers {
    audioTrackPlayer.volume = 0
}
// Pause audio track players
for audioTrackPlayer in audioTrackPlayers {
    audioTrackPlayer.pause()
}
// Update the currentTime values so they all match
for index in 1..<audioTrackPlayers.count {
    audioTrackPlayers[index].currentTime = audioTrackPlayers[0].currentTime.truncatingRemainder(dividingBy: audioTrackPlayers[index].duration)
}
// Reset the volumes now the tracks are paused
for audioTrackPlayer in audioTrackPlayers {
    audioTrackPlayer.volume = 1
}

关于ios - Swift 3 iOS - 与 AVAudioPlayer 同步暂停,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41082363/

相关文章:

ios - 我们可以在单个 Watchkit 应用程序中创建多个 glance 界面吗?

iOS13 UIViewController isModalInPresentation 在 ObjectiveC 中没有 setter 所以无法设置?

iOS 7 - UICollectionElementKindSectionHeader 应用程序崩溃 ('UICollectionView dataSource is not set')

ios - 如何将 CGRect 的大小增加一定的百分比值?

ios - SpriteKit 淡出

swift - 在 switch 之外访问 swift 枚举案例?

ios - 关闭应用程序并在 appstart 上启动 webview

ios - 单击表格 View 内的按钮

swift - Xcode 8 测试版 6 : AnyObject replaced by Any: where is classForCoder?

ios - 如何使用 Swift 3 在本地化条件下更改按钮字体大小