适用于iOS应用程序的多轨道MP3播放
我正在做一个应用程序,涉及以多轨道格式(鼓,人声,吉他,钢琴等)播放歌曲。 我不需要为每个音轨做任何奇妙的audio处理,我需要做的就是播放,暂停,以及将每个音轨静音/取消静音。
我一直在使用AVAudioPlayer的多个实例,但是在进行设备testing时,我注意到当他们第一次播放时,曲目的播放非常不同步。 此外,当我暂停和播放曲目时,它们将继续失去同步。 经过一些研究后,我意识到AVAudioplayer只是有太多的延迟,不适合我的应用。
在我的应用程序中,我基本上有一个AVArudioPlayers的NSArray,我将循环播放每一个或暂停/停止每一个,我相信这是什么造成它在设备上不同步。
似乎苹果的audio混音器对我来说效果不错,但是当我尝试实现它时,我得到了一个EXC_BAD_ACCESS错误,我找不出来。
我知道答案是使用OpenAL或audio单元,但是当我所需要做的就是同时播放5个.mp3曲目时,似乎没有必要花费数周的时间来学习这些内容。 有没有人有任何build议如何做到这一点? 谢谢
感谢admsyn的build议,我能够想出一个解决scheme。
AVAudioPlayer有一个currentTime属性,返回一个轨道的当前时间,也可以设置。
所以我实现了admsyn所说的startSynchronizedPlayback,然后在停止轨道时添加了以下内容:
-(void) stopAll { int count = [tracksArr count]; for(int i = 0; i < count; i++) { trackModel = [tracksArr objectAtIndex:i] if(i = 0) { currentTime = [trackModel currentTime] } [trackModel stop] [trackModel setCurrentTime:currentTime] } {
这个代码基本上是通过我自己的AVAudioPlayer的轨道数组来循环的,从第一个轨道抓取当前时间,然后设置所有跟踪到那个时间。 现在,当我使用startSynchronizedPlayback方法时,它们全部同步播放,暂停解除暂停同步。 希望这有助于其他人试图保持轨道同步。
如果您正在向每台AVAudioPlayer发送单独的play
消息,则消息很可能在不同的时间到达,或者AVAudioPlayers完成预热阶段而不同步。 您应该使用playAtTime:和deviceCurrentTime属性来实现正确的同步。 请注意deviceCurrentTime的描述:
调用playAtTime:instance方法时,使用此属性来指示“now”。 通过将多个audio播放器configuration为以deviceCurrentTime指定的偏移量进行播放,您可以执行精确同步 – 如该方法的讨论中所述。
还要注意playAtTime:
讨论中的示例代码:
// Before calling this method, instantiate two AVAudioPlayer objects and // assign each of them a sound. - (void) startSynchronizedPlayback { NSTimeInterval shortStartDelay = 0.01; // seconds NSTimeInterval now = player.deviceCurrentTime; [player playAtTime: now + shortStartDelay]; [secondPlayer playAtTime: now + shortStartDelay]; // Here, update state and user interface for each player, as appropriate }
如果您能够将文件解码到磁盘,那么audio单元可能是提供最佳延迟的解决scheme。 如果你决定使用这样的架构,你还应该检查一下Novocaine:
https://github.com/alexbw/novocaine
这个框架需要处理audio单元的很多麻烦。