2009-03-07 12 views
5

Quiero reproducir múltiples archivos MP3, en secuencia (uno después del otro), usando AVAudioPlayer. Lo intenté y se detiene después de reproducir el primer MP3. Sin embargo, si entro en el depurador, funciona bien ... ¿Alguna idea? Leí en algún lado AVAudioPlayer reproduce audio en segundo plano ... ¿cómo evito que haga esto? VasAVAudioPlayer - reproducción de archivos de audio múltiples, en secuencia

+0

Esto necesita una etiqueta iPhoneSDK por favor –

+0

Ayudaría a ver su código. Algo a ver: ¿está usando un AVAudioPlayer por sonido? Cuando reproduce archivos mp3, solo uno puede jugar a la vez, por lo que cualquier vuelta puede no dar los resultados esperados. No estoy seguro de por qué el depurador haría una diferencia a menos que quiera decir en el simulador también.Tal vez el simulador puede reproducir múltiples archivos mp3 al mismo tiempo (ya que es el resultado del hardware de decodificación de mp3 en el iPhone). Bueno, más información nos ayudará a encontrar una solución, así que siéntete libre de publicar código som. –

Respuesta

3

Utilice un AVAudioPlayer por sonido.

1

Implementé una clase para manejar esto.

de usar Simplemente hacer algo como esto:

[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 
3

Bueno, el ejemplo de código no funcionó de la caja para mi Taaaan, pensé que había que responder con una versión fija:

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 

Y es como yo lo llamaría aquí:

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

Tengo solo un poco más de un año de experiencia en el desarrollo de iPhone/iPad con Objective-C, así que no dude en responder con cri adicional ticismo.

10

creo que el AVQueuePlayer (subclase de AVPlayer) hace exactamente este trabajo (reproducir una secuencia de elementos), ya que iOS 4.1: http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVQueuePlayer_Class/Reference/Reference.html

no lo probé yo mismo, pero sin embargo sin duda le dará una oportunidad a ella .

+0

Si bien esta respuesta aborda una alternativa al uso de AVAudioPlayer, es una solución mucho más elegante y 'integrada' que el uso de los ejemplos de código Looper. * Más arriba. Me da vergüenza tener que asignar continuamente una nueva instancia de AVAudioPlayer. Si bien inicialmente adopté ese enfoque, terminé subclasificando AVQueuePlayer, que me dio la funcionalidad que necesitaba para la reproducción secuencial de archivos de audio. Entonces sí, esta es la respuesta correcta. – manderson

1

Es una buena idea inicializar, preparar los elementos y hacer cola antes de tiempo, por ejemplo, en el método viewDidLoad.

Si usted está trabajando en 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) 
    } 

y luego, cuando se produce un evento,

queuePlayer.play() 

Tenga en cuenta que si se utiliza la cola, es posible que aún tienen algunos huecos entre los sonidos.

Puede encontrar la versión de Objective-C en la pregunta How to do something when AVQueuePlayer finishes the last playeritem

espero que ayude.

Cuestiones relacionadas