AVAudioPlayer を使用して、複数の MP3 ファイルを順番に (次々に) 再生したいと考えています。試してみたところ、最初の MP3 を再生した後に停止します。ただし、デバッガーに入ると、正常に動作します..何かアイデアはありますか? AVAudioPlayer がバックグラウンドでオーディオを再生する場所を読みました..これを防ぐにはどうすればよいですか? ヴァス
5 に答える
AVQueuePlayer
iOS 4.1以降、 (のサブクラスAVPlayer
)はまさにこの仕事(アイテムのシーケンスを再生)
を行うと思います: http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVQueuePlayer_Class/Reference/Reference.html
私は自分で試したことはありませんが、間違いなく試してみます。
サウンドごとに 1 つの AVAudioPlayer を使用します。
さて、あなたのコード例は、そのままでは機能しませんでした。すっごく、私は修正されたバージョンで応答すると思いました:
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 ]];
私は、Objective-C を使用した iPhone/iPad 開発の経験が 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バージョンを見つけることができます
それが役に立てば幸い。
これを処理するクラスを実装しました。
使用するには、次のようにします。
[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