0

I've setup an AVQueuePlayer named player in my viewDidLoad method. I also have a UIbutton method which plays that sequence.

here is my view did load method

AVPlayerItem *firstSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"first" ofType:@"mp3"]]];
AVPlayerItem *secondSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"second" ofType:@"mp3"]]];
AVPlayerItem *thirdSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"third" ofType:@"mp3"]]];

player = [AVQueuePlayer queuePlayerWithItems:[NSArray arrayWithObjects:firstSound, secondSound, thirdSound,  nil]];

and here is my button's method

-(IBAction)sequencePlay:(id)sender {[player play];}

pressing the button only produces the sequence of sounds once, when the view is first loaded. when i click the button again nothing happens. however if i navigate to another view controller and back to this view controller, it will work the first time i press the button again but as before, it only works for the first click.

update: doing the setup in the button instead of the viewDidLoad method was the key as according to the first answer to solve my problem.

My mp3 files are small, each file is just one word being spoken. I have a UIPickerView setup with 3 columns, and depending on which rows are selected, it will play those specific words in sequence when the button is pressed. Any good advice on how i may accomplish that?

i'm currently trying to do this but get an error

-(IBAction)sequencePlay:(id)sender 
{
NSString *sayFirst = _firstRowWord.description;

AVPlayerItem *firstSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:sayFirst.description ofType:@"mp3"]]];

i get the following error * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSURL initFileURLWithPath:]: nil string parameter'

the description of the firstRowWord is the same exact name as the mp3 file i want to play

  • AVQueuePlayer only plays the sequence once by design. Other people have run into this problem as well, [and the answer to this duplicate question likely will help you out](http://stackoverflow.com/questions/11155983/replay-items-in-avqueueplayer-after-last). – Michael Dautermann Sep 07 '13 at 21:25

1 Answers1

2

You could try using the sequencePlay: method to setup the AVQueuePlayer there. So:

-(IBAction)sequencePlay:(id)sender {
AVPlayerItem *firstSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:@"first" ofType:@"mp3"]]];
AVPlayerItem *secondSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"second" ofType:@"mp3"]]];
AVPlayerItem *thirdSound = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"third" ofType:@"mp3"]]];

player = [AVQueuePlayer queuePlayerWithItems:[NSArray arrayWithObjects:firstSound, secondSound, thirdSound,  nil]];
[player play];
}

If you are concerned about the performance of this you could use the actionAtItemEnd property to repopulate the Player. Hope this helped!

user1628311
  • 166
  • 1
  • 3
  • 12
  • -1 -- This **does not** fix the problem. It just moves the setup of the AVQueuePlayer to the sequencePlay method. The original poster will still have the problem of the instance of AVQueuePlayer not being repeatable. – Michael Dautermann Sep 07 '13 at 21:28
  • Yeah, I thought about it a second time. It creates the player only in the sequencePlay and then ARC should clean up (& release) that object the next time AVQueuePlayer is created. – Michael Dautermann Sep 07 '13 at 21:31
  • yeah, I don't know what the performance is like so using the actionAtItemEnd property may be better – user1628311 Sep 07 '13 at 21:32
  • this solves my issue, thank you. i initially attempted doing it this way but was having trouble getting it to play sound. however this approach is working now. My mp3 files are small, each file is just one word being spoken. I have a UIPickerView setup with 3 columns, and depending on which rows are selected, it will play those specific words in sequence when the button is pressed. Any good advice on how i may accomplish that? – lifefriends Sep 08 '13 at 06:08
  • set up an IBOutlet to the pickerview and then in the sequencePlay method use the selectedRowInComponent: method of the pickerview to get the index of the specified component. Then figure out what file the integer corresponds to e.g if an array if your datasource do array[valuereturnedfromselectedrowmethod]. Once you have the object in the array map it to the right file. Hope this made sense. – user1628311 Sep 08 '13 at 09:13