Swift 3 iOS – 与AVAudioPlayer同步暂停

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

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

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

编辑 – 额外信息

在马特询问有多明显之后,我得到了一些数据。 暂停5个曲目需要几乎半秒的时间。 为了说明这一点,我在暂停循环之后添加了一个单独的循环,以在每个轨道上报告currentTime,并在暂停之前添加了几个循环 – 供参考,并显示它们同步开始。

 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。 这给用户在audio方面的“即时响应”感觉,所以主要解决了这个问题。 不用花半秒钟就可以暂停曲目,所以我不接受这个答案,但它确实以可用的方式解决了这个问题。

示例代码(我用来演示该点的简化版本),包括必要的代码,以便在延迟暂停后使当前时间值重新匹配。 truncatingRemainder是必要的,因为这些都是循环audio。

 // 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 }