【问题标题】:multi track mp3 playback for iOS applicationiOS 应用程序的多轨 mp3 播放
【发布时间】:2012-10-15 19:48:03
【问题描述】:

我正在做一个应用程序,它涉及以多轨格式(鼓、人声、吉他、钢琴等)播放歌曲。我不需要对每个音轨进行任何花哨的音频处理,我需要做的就是播放、暂停和静音/取消静音每个音轨。

我一直在使用多个 AVAudioPlayer 实例,但在执行设备测试时,我注意到曲目在第一次播放时播放时非常不同步。此外,当我暂停并播放曲目时,它们会继续变得更加不同步。经过一番研究,我意识到 AVAudioplayer 的延迟太长,不适用于我的应用程序。

在我的应用程序中,我基本上有一个 NSArray 的 AVAudioPlayers,我会循环播放每个播放器或暂停/停止每个播放器,我确信这是导致它在设备上不同步的原因。

看起来苹果的音频混音器对我来说很好用,但是当我尝试实现它时,我得到一个我无法弄清楚的 EXC_BAD_ACCESS 错误。

我知道答案是使用 OpenAL 或音频单元,但当我需要做的只是同时播放大约 5 个 .mp3 曲目时,似乎没有必要花几周时间来学习这些。有没有人对如何做到这一点有任何建议?谢谢

【问题讨论】:

  • OpenAL 不支持开箱即用的 MP3。

标签: objective-c ios core-audio openal audiounit


【解决方案1】:

感谢 admsyn 的建议,我能够想出一个解决方案。

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 方法时,它们都会同步播放,暂停 unpausing 也会使它们保持同步。希望这对尝试保持轨道同步的其他人有所帮助。

【讨论】:

    【解决方案2】:

    如果您向每个 AVAudioPlayer 发出单独的 play 消息,则消息完全有可能在不同的时间到达,或者 AVAudioPlayer 完成它们的预热阶段彼此不同步。您应该使用playAtTime:deviceCurrentTime 属性来实现正确的同步。注意deviceCurrentTime的描述:

    在调用 playAtTime: 实例方法时使用此属性指示“现在”。通过将多个音频播放器配置为在与 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
    }
    

    【讨论】:

    • admsyn - 感谢您的评论。这个方法其实我已经试过了。第一次播放曲目时效果很好。问题是当曲目暂停或停止时,它们似乎在每个曲目停止之间都有延迟,所以当我暂停所有曲目并播放它们几次时,它严重不同步。如果只有 stopAtTime 方法:(
    【解决方案3】:

    如果您能够将文件解码到磁盘,那么音频单元可能是提供最佳延迟的解决方案。如果您决定使用这样的架构,您还应该查看 Novocaine:

    https://github.com/alexbw/novocaine

    该框架解决了处理音频单元的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多