Reputation: 13
I have an AVQueuePlayer
property which is set up as below. The NSLog
statements report that the audio should be playing properly (while the app is running) however when testing in the simulator and on the iOS device itself (iPhone 5s iOS 8.1.1) there is no audio playing.
I have confirmed that the device is not muted, and is at full volume. I am using Xcode 6 and iOS 8 SDK. I have import AVFoundation framework in the "Link binaries" section and have imported it into my class.
-(void)viewDidLoad
{
[super viewDidLoad];
[self music];
// other setup code
}
- (void)music
{
music = [[NSMutableArray alloc]initWithArray:@[
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM1"
ofType:@"mp3" ]]],
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM2"
ofType:@"mp3" ]]],
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM3"
ofType:@"mp3" ]]],
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM4"
ofType:@"mp3" ]]],
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM5"
ofType:@"mp3" ]]],
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM6"
ofType:@"mp3" ]]],
[AVPlayerItem playerItemWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:@"BM7"
ofType:@"mp3" ]]]
]];
for(AVPlayerItem *a in music)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:a];
}
[music shuffle];
self.audio = [[AVQueuePlayer alloc]initWithItems:music];
[self.audio play];
NSLog(@"Now playing%@",[self.audio currentItem]);
NSLog(@"%@",self.audio);
}
-(void)playerItemFinished:(NSNotification *)notification
{
if([[self.audio currentItem] isEqual:[music lastObject]])
{
self.audio = nil;
[music shuffle];
self.audio = [[AVQueuePlayer alloc]initWithItems:music];
[self.audio play];
}
}
Upvotes: 0
Views: 591
Reputation: 141
Try to build the array in this way:
music = [[NSMutableArray alloc] initWithArray:@[[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM1" withExtension:@"mp3"]],...]];
Edit:
Anyway, IMHO the most important aspect is to highlight the reason for which withExtension works where ofType doesn't: the first one returns the file URL for the resource identified by the specified name and file extension where -pathForResource:ofType:
returns the full pathname for the resource identified by the specified name and file extension. However, you needed an NSURL object to initialize the AVPlayer
and AVQueuePlayer
is a subclass of AVPlayer you use to play a number of items in sequence.
Upvotes: 1
Reputation: 1108
Well, I've made a code snippet from my comment above, so you could copy-paste it to your project.
I've basically made 2 changes.
The array creation have changed from initWithArray:
to initWithObjects:
and therefore you don't create a new unnecessary, unused array, that is probably deallocating after this method call.
Plus, instead of calling [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:ofType:]]]
on every object in that array, there is simply a call to [[NSBundle mainBundle] URLForResource:withExtension:
music = [[NSMutableArray alloc] initWithObjects:
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM1" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM2" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM3" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"BM4" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"MP5" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"MP6" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"MP7" withExtension:@"mp3"]],
nil];
Good luck mate.
EDIT-
I'm not a native english speaker so I'll try my best to be clear,
If something isn't clear, tell me, and I'll try to rephrase it.
What the initWithArray
does is creating a new array, with the contents of a given array,
So for example:
NSArray *array1 = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil]];
NSArray *array2 = [[NSArray alloc] initWithArray:array1];
So now both array1
and array2
have the same items in them.
If I'm not mistaken, since Xcode 4, a new way of creating arrays was introduced, and now, instead of calling [[NSArray alloc] initWithObjects:]
, an array with objects can simply be created using the @[]
syntax.
So our example above would look like this:
NSArray *array1 = @[@"One", @"Two", @"Three"]; // Notice that 'nil' is not necessary
NSArray *array2 = [[NSArray alloc] initWithArray:array2];
So what you were doing in your original code, Is basically calling [[NSMutableArray alloc] initWithObjects:]
, which would eventually create a new array,
And then, using the 'new' @[]
syntax, you've created another new array that had all of the AVPlayerItem
objects in it,
And 'told' the music
array, to have the contents of that new array in it.
So in this 'one-line' of code, you actually created 2 different arrays.
The reason the 'new' un-named array is probably getting deallocated after that line, is because you don't have any reference to that array anywhere (you just have a reference to its objects, in the newly created array),
And ARC auto-releases objects with reference count of zero.
You would probably not feel any memory/performance issues because of this,
But I thought it is worth to point that out, since it is unnecessary, it wasn't the 'right' way to achieve what you were trying, and now the code looks cleaner and more readable.
BTW-
This was not why your code didn't work.
You problem was in the fact that that your original code were generating NSURL
with the path as a string: /PATH/TO/MY/MP3
But the AVPlayerItem
was expecting the path as a URL: file:///PATH/TO/MY/MP3
(You could NSLog
the new and old calls to verify the different output)
Upvotes: 0