0

I'm trying to play a .m4a sound file using AVQueuePlayer, on iPhone4, but there is no sound. If I try AudioServicesPlaySystemSound with the same file, all works okay.

Here's the code.

(AVFoundation framework is installed.)

    #import <AVFoundation/AVFoundation.h> 

-(void) play_sound_file: (NSString *) sound_file_m4a
{
    printf("\n play_sound_file 1: '%s' ", [sound_file_m4a UTF8String] );


        AVPlayerItem *sound_file = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:sound_file_m4a ofType:@"m4a"]]]; 
        AVQueuePlayer *player = [AVQueuePlayer queuePlayerWithItems:[NSArray arrayWithObjects:sound_file, nil]];  

        [player play]; 

        return;
}

LATEST CODE AS OF 8/28/12........... (Note: both sound files work with AudioServicesPlaySystemSound)

AVPlayerItem *sound_file1 = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[[NSString alloc] initWithFormat:@"Hold still"] ofType:@"m4a"]]]; 

AVPlayerItem *sound_file2 = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[[NSString alloc] initWithFormat:@"Press go"] ofType:@"m4a"]]];     

AVQueuePlayer *player = [AVQueuePlayer queuePlayerWithItems: [NSArray arrayWithObjects:sound_file1, sound_file2,  nil]];  

[player play]; 
Doug Null
  • 7,989
  • 15
  • 69
  • 148
  • on a side note, the most widely accepted notation for naming methods and variables in objective-c is camel case. https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html – jere Aug 28 '12 at 14:06

1 Answers1

0

I explained how to fix this in a comment on my answer in your last post. One of the reasons this may not be working is because you are passing one item to arrayWithObjects: which requires more than one item. Another thing that may be causing this not to work is if you are attempting to run this in the simulator, there are known compatibility issues between AVQueuePlayer and the simulator.

Also:

Replace

AVPlayerItem *sound_file = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:sound_file_m4a ofType:@"m4a"]]]; 

With

AVPlayerItem *sound_file = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[[NSString alloc] initWithFormat:@"sound_file_m4a"] ofType:@"m4a"]]];

EDIT: Here's an example of how to play audio files sequentially.

In your header file:

#import <AVFoundation/AVFoundation.h>

AVAudioPlayer *data;
NSArray *arrayOfTracks;
NSUInteger currentTrackNumber;

Then in your implementation file:

- (void)viewDidLoad
{
    [super viewDidLoad];
    arrayOfTracks = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];//Do NOT include file extension here
    currentTrackNumber = 0;
}
- (void)startPlaying
{
    if (data) {
        [data stop];
        //[data release]; if project isn't using Automatic Reference Counting
        data = nil;
    }
    data = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[[NSString alloc] initWithString:[arrayOfTracks objectAtIndex:currentTrackNumber]] ofType:@"m4a"]] error:NULL];
    data.delegate = self;
    [data play];
}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    if (flag) {
        if (currentTrackNumber < [arrayOfTracks count] - 1) {
            currentTrackNumber ++;
            if (data) {
                [data stop];
                //[data release]; if project isn't using Automatic Reference Counting
                data = nil;
            }
            data = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[[NSString alloc] initWithString:[arrayOfTracks objectAtIndex:currentTrackNumber]] ofType:@"m4a"]] error:NULL];
            data.delegate = self;
            [data play];
        }
    }
}
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
  • This did not work either. I am using iPhone4 (iOS 5.1), not simulator. I added my latest code, above, and am using two files. The comments in the last post seem to be a little chopped up, but I will clean it up once this is working. Thanks, NSPostWhenIdle. – Doug Null Aug 28 '12 at 15:15
  • @DouglasK.Bell Is the log you've entered producing anything? – Mick MacCallum Aug 28 '12 at 15:18
  • NSPostWhenIdle: Yes -- it shows that it executed play; there was a log before and after play. What about just using AVPlayer? I'm actually only call the routine with one file at a time. Does AVPlayer play block until the sound file is played? – Doug Null Aug 28 '12 at 15:51
  • @DouglasK.Bell Not exactly, I'm currently working with `AVPlayer` in a project using a queue but I wouldn't recommend it. `AVPlayer` wasn't designed to handle a queue out of the box whereas `AVQueuePlayer` is a subclass of `AVPlayer` that was designed to do this. If you'd like another alternative I'll edit my answer to show you how you can play a sound in `AVAudioPlayer` and then use the players `didFinishPlaying` delegate method to start the next music item from an array of song names. – Mick MacCallum Aug 28 '12 at 15:56
  • @DouglasK.Bell I've edited my post here to show an example of how to create a queue using `AVAudioPlayer` – Mick MacCallum Aug 28 '12 at 16:27
  • Thanks, but unfortunately that has the same problem as AudioServicesPlaySystemSound: I have to program audioPlayerDidFinishPlaying. I need to be able to do consecutive sounds, like this: [self play_sound_file: @"one"]; [self play_sound_file: @"two"]; [self play_sound_file: @"three"]; ..without having to program the app's state machine for every sound file played. That's why I need to get AVQueuePlayer going, so I can send it one or more sounds files, and not have wait in between. – Doug Null Aug 28 '12 at 22:23
  • @DouglasK.Bell `AVAudioPlayer` will do this. You enter the names of the sounds in the array as stated above, and `audioPlayerDidFinishPlaying` automatically gets called, and immediately plays the next sound as soon as the one before ended. – Mick MacCallum Aug 28 '12 at 22:25