AVAudioPlayer - проигрывание нескольких аудио файлов в последовательности - PullRequest
6 голосов
/ 07 марта 2009

Я хочу воспроизвести несколько файлов MP3, последовательно (один за другим), используя AVAudioPlayer. Я попробовал, и он останавливается после воспроизведения первого MP3. Однако, если я зайду в отладчик, он работает нормально .. какие-нибудь идеи? Я где-то читал, AVAudioPlayer воспроизводит аудио в фоновом режиме ... как мне предотвратить это? Vas

Ответы [ 5 ]

10 голосов
/ 23 августа 2012

Я думаю, AVQueuePlayer (подкласс AVPlayer) выполняет именно эту работу (воспроизводит последовательность элементов) начиная с iOS 4.1 http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVQueuePlayer_Class/Reference/Reference.html

Однако я сам не пробовал, но обязательно попробую.

4 голосов
/ 02 августа 2009

Используйте один AVAudioPlayer на звук.

3 голосов
/ 10 апреля 2012

Ну, ваш пример кода не сработал для меня. Тааак, я решил ответить фиксированной версией:

Looper.h:

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

@interface Looper : NSObject <AVAudioPlayerDelegate> {
    AVAudioPlayer* player;
    NSArray* fileNameQueue;
    int index;
}

@property (nonatomic, retain) AVAudioPlayer* player;
@property (nonatomic, retain) NSArray* fileNameQueue;

- (id)initWithFileNameQueue:(NSArray*)queue;
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void)play:(int)i;
- (void)stop;

@end

Looper.m:

#import "Looper.h"
@implementation Looper
@synthesize player, fileNameQueue;

- (id)initWithFileNameQueue:(NSArray*)queue {
    if ((self = [super init])) {
        self.fileNameQueue = queue;
        index = 0;
        [self play:index];
    }
    return self;
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    if (index < fileNameQueue.count) {
        [self play:index];
    } else {
        //reached end of queue
    }
}

- (void)play:(int)i {
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[fileNameQueue objectAtIndex:i] ofType:nil]] error:nil];
    [player release];
    player.delegate = self;
    [player prepareToPlay];
    [player play];    
    index++;
}

- (void)stop {
    if (self.player.playing) [player stop];
}

- (void)dealloc {
    self.fileNameQueue = nil;
    self.player = nil;        
    [super dealloc];
}

@end

А вот как бы я это назвал:

 Looper * looper = [[Looper alloc] initWithFileNameQueue:[NSArray arrayWithObjects: audioFile, audioFile2, nil ]];

У меня есть чуть более года опыта разработки iPhone / iPad с использованием Objective-C, поэтому не стесняйтесь отвечать дополнительной критикой.

1 голос
/ 29 апреля 2016

Рекомендуется заранее инициализировать, подготовить элементы и поставить очередь в очередь, например, с помощью метода viewDidLoad.

Если вы работаете в Swift,

    override func viewDidLoad() {
        super.viewDidLoad()
        let item0 = AVPlayerItem.init(URL: NSBundle.mainBundle().URLForResource("url", withExtension: "wav")!)

        let item1 = AVPlayerItem.init(URL: NSBundle.mainBundle().URLForResource("dog", withExtension: "aifc")!)
        let item2 = AVPlayerItem.init(URL: NSBundle.mainBundle().URLForResource("GreatJob", withExtension: "wav")!)


        let itemsToPlay:[AVPlayerItem] = [item0, item1, item2] 
        queuePlayer = AVQueuePlayer.init(items: itemsToPlay)
    }

и затем, когда происходит событие,

 queuePlayer.play()

Обратите внимание, что если вы используете очередь, у вас все еще могут быть некоторые промежутки между звуками.

Вы можете найти версию Objective-C в вопросе Как сделать что-то, когда AVQueuePlayer заканчивает последний элемент игрока

Надеюсь, это поможет.

1 голос
/ 20 июля 2011

Я реализовал класс для обработки этого.

Для использования просто сделайте что-то вроде этого:

[looper playAudioFiles:[NSArray arrayWithObjects:
    @"add.mp3",
    [NSString stringWithFormat:@"%d.mp3", numeral1.tag],
    @"and.mp3",
    [NSString stringWithFormat:@"%d.mp3", numeral2.tag],
    nil
]];

Looper.m

#import "Looper.h"
@implementation Looper
@synthesize player, fileNameQueue;

- (id)initWithFileNameQueue:(NSArray*)queue {
    if ((self = [super init])) {
        self.fileNameQueue = queue;
        index = 0;
        [self play:index];
    }
    return self;
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    if (index < fileNameQueue.count) {
        [self play:index];
    } else {
        //reached end of queue
    }
}

- (void)play:(int)i {
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[fileNameQueue objectAtIndex:i] ofType:nil]] error:nil];
    [player release];
    player.delegate = self;
    [player prepareToPlay];
    [player play];    
    index++;
}

- (void)stop {
    if (self.player.playing) [player stop];
}

- (void)dealloc {
    self.fileNameQueue = nil;
    self.player = nil;        
    [super dealloc];
}

@end

Looper.h

#import <Foundation/Foundation.h>


@interface Looper : NSObject <AVAudioPlayerDelegate> {
    AVAudioPlayer* player;
    NSArray* fileNameQueue;
    int index;
}

@property (nonatomic, retain) AVAudioPlayer* player;
@property (nonatomic, retain) NSArray* fileNameQueue;

- (id)initWithFileNameQueue:(NSArray*)queue;
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void)play:(int)i;
- (void)stop;


@end
...