如何使用 AVAudioPlayer 连续播放多个音频文件?

Posted

技术标签:

【中文标题】如何使用 AVAudioPlayer 连续播放多个音频文件?【英文标题】:How to play multiple audio files in a row with AVAudioPlayer? 【发布时间】:2011-11-12 02:56:27 【问题描述】:

我的应用中有 5 首歌曲,我想用 AVAudioPlayer 依次播放。

有这方面的例子吗?我怎样才能做到这一点?

任何示例代码将不胜感激!

谢谢!

【问题讨论】:

很难找到有关这方面的任何信息... 【参考方案1】:

AVQueuePlayer 适用于这种情况。

AVQueuePlayer 是 AVPlayer 的子类,用于按顺序播放多个项目。

【讨论】:

【参考方案2】:

您可以使用更适合此用例的 AVQueuePlayer 而不是 AVAudioPlayer,正如 Ken 所建议的那样。 这是您可以使用的一些代码:

@interface AVSound : NSObject 

@property (nonatomic, retain) AVQueuePlayer* queuePlayer;

- (void)addToPlaylist:(NSString*)pathForResource ofType:(NSString*)ofType;
- (void)playQueue;

@end

@implementation AVSound
- (void)addToPlaylist:(NSString*)pathForResource ofType:(NSString*)ofType

    // Path to the audio file
    NSString *path = [[NSBundle mainBundle] pathForResource:pathForResource ofType:ofType];

    // If we can access the file...
    if ([[NSFileManager defaultManager] fileExistsAtPath:path])
    

        AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:path]];

        if (_queuePlayer == nil) 
            _queuePlayer = [[AVQueuePlayer alloc] initWithPlayerItem:item];
        else
            [_queuePlayer insertItem:item afterItem:nil];
        
    




- (void)playQueue

    [_queuePlayer play];

@end

然后使用它: 在你的接口文件中:

@property (strong, nonatomic) AVSound *pageSound;

在你的实现文件中:

- (void)addAudio:(Book*)book pageNum:(int)pageNum


    NSString *soundFileEven = [NSString stringWithFormat:@"%02d", pageNum-1];
    NSString *soundPathEven = [NSString stringWithFormat:@"%@_%@", book.productId,     soundFileEven];
    NSString *soundFileOdd = [NSString stringWithFormat:@"%02d", pageNum];
    NSString *soundPathOdd = [NSString stringWithFormat:@"%@_%@", book.productId, soundFileOdd];

    if (_pageSound == nil) 
        _pageSound = [[AVSound alloc]init];
        _pageSound.player.volume = 0.5;
    

    [_pageSound clearQueue];

    [_pageSound addToPlaylist:soundPathEven ofType:@"mp3"];
    [_pageSound addToPlaylist:soundPathOdd ofType:@"mp3"];
    [_pageSound playQueue];

HTH

【讨论】:

【参考方案3】:

为您想要制作的每首歌曲制作一个 AVPlayer

NSURL *url = [NSURL URLWithString:pathToYourFile]; AVPlayer *audioPlayer = [[AVPlayer alloc] initWithURL:url]; [audioPlayer play];

您可以在播放器结束时收到通知。设置播放器时勾选AVPlayerItemDidPlayToEndTimeNotification

  audioPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(playerItemDidReachEnd:)
                                               name:AVPlayerItemDidPlayToEndTimeNotification
                                             object:[audioPlayer currentItem]];

这将防止播放器在结束时暂停。

在通知中:

- (void)playerItemDidReachEnd:(NSNotification *)notification

    // start your next song here

您可以在收到当前播放歌曲已播放完毕的通知后立即开始播放下一首歌曲。维护一些在选择器调用中持久的计数器。这样使用counter % [songs count] 会给你一个无限循环播放列表:)

释放播放器时不要忘记取消注册通知。

【讨论】:

我在 playerItemDidReachEnd 中放了什么? audioPlayer2 播放?如果我有 5 首歌曲呢? 是的,你可以这样做。我上面的代码是理论上的。它可以但不能保证。但这个想法似乎可行......【参考方案4】:

很遗憾,AVAudioPlayer 只能播放一个文件。要播放两个文件,您必须终止 AVAudioPlayer 的第一个实例并重新创建它第二次(可以使用- (id)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError 启动它)。这种方法的问题是在第一个文件完成播放和第二个文件开始播放之间有一点延迟。如果您想摆脱这种延迟,您必须深入研究Core Audio 并提出一个更复杂的解决方案。

【讨论】:

我认为有办法。看看我的答案。 AVPlayer 有一个通知选择器,它告诉我们当前播放的歌曲何时结束。这样我们就可以在当前完成后立即播放下一首歌曲。这可能行得通。 我实际上为 iPhone 和 iPad 制作了一个广播应用程序。我知道从 ios 4.2 开始,尝试使用 AVAudioPlayer 连续播放两个文件时仍然存在延迟。我什至尝试使用prepareToPlay 方法准备一个单独的 AVAudioPlayer,并在第一个完成后立即开始播放第二个,但仍有一点延迟。如果您不介意声音之间的轻微延迟,那没什么大不了的,但是如果您想在两个文件之间完全连续播放,我认为 AVAudioPlayer 不是要走的路。 无法想象在尝试使用通知时会有明显的差距,除非音频文件本身在结尾处有白噪声或一些空白噪声。这样AVAudioPlayer 仍然可以播放,但用户认为存在差距。仍然很想知道为什么会这样...... 差距来自 AVAudioPlayer 准备播放音频文件

以上是关于如何使用 AVAudioPlayer 连续播放多个音频文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 AVAudioPlayer 播放多个音频文件

如何在 AVAudioplayer 中播放多个文件

使用 AVAudioPlayer 同时播放多个声音

如何在 AVAudioPlayer 中循环播放多个音频文件?

AVAudioPlayer 消除声音文件之间的一秒停顿

Swift 3 多个 AVAudioPlayer