6

我想使用 AVAudioPlayer 按顺序(一个接一个)播放多个 MP3 文件。我试了一下,播放第一首MP3后就停止了。但是,如果我进入调试器,它工作正常.. 有什么想法吗?我在某处读到 AVAudioPlayer 在后台播放音频..如何防止它这样做?瓦斯

4

5 回答 5

11

我认为AVQueuePlayer(的子类AVPlayer)自 iOS 4.1 起就完成了这项工作(播放一系列项目):http: //developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVQueuePlayer_Class/Reference/Reference.html

但是我自己没有尝试过,但肯定会尝试一下。

于 2012-08-23T11:39:52.037 回答
4

每个声音使用一个 AVAudioPlayer。

于 2009-08-02T15:51:14.517 回答
3

Well, your code example didn't work out of the box for me. Soooo, I figured I'd respond with a fixed version:

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

And here's how I would call it:

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

I only have slightly over a year of experience with iPhone/iPad development using Objective-C so feel free to respond with additional criticism.

于 2012-04-09T20:21:05.950 回答
1

我已经实现了一个类来处理这个问题。

要使用,只需执行以下操作:

[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
于 2011-07-20T05:58:22.710 回答
1

提前初始化、准备项目和排队是个好主意,例如在 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()

请注意,如果您使用队列,则声音之间可能仍然存在一些间隙。

您可以在 AVQueuePlayer 完成最后一个播放项时如何做某事的问题中找到 Objective-C 版本

希望能帮助到你。

于 2016-04-29T09:35:36.690 回答