Sound not playing with AVAudioPlayer

24,272

Solution 1

SOLVED.

1.- Check if your file has been added to "Copy Bundle Resources" in Build Phases. Copy Bundle Resources

2.- ViewController.m

#import <AVFoundation/AVAudioPlayer.h>

@interface ViewController ()
@property (nonatomic, strong) AVAudioPlayer *theAudio;
- (IBAction)pushBell;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *soundPath =[[NSBundle mainBundle] pathForResource:@"beep-beep" ofType:@"caf"];
    NSURL *soundURL = [NSURL fileURLWithPath:soundPath];

    NSError *error = nil;
    self.theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
}

- (IBAction)pushBell {
    [self.theAudio play];
}

3.- Connect the IBAction to your button in Interface Builder.

Done.

Solution 2

This was my issue, so I'm just posting it here in case it helps anyone!

Believe it or not, there appears to be a bug (in iOS 5.1 on iPad 2 at least) where if you had the Side Switch set to Mute and it was Muted, then set the Side Switch to Lock Rotation, AVAudioPlayer sounds WON'T PLAY except through headphones!

So I had to go to the Settings app, change the switch back to Mute, then unmute the iPad, switch it back to Lock Rotation and my app started to work properly.

Solution 3

Your theAudio AVAudioPlayer is deallocated before it can even start playing (since it's allocated as a local variable inside pushBell method.

Change your code to:

header file:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioPlayer.h>

@interface BellViewController:UIViewController

@property (nonatomic, strong) AVAudioPlayer *theAudio;

-(IBAction)pushBell;

@end

implementation file:

#import "BellViewController.h"

@implementation BellViewController

@synthesize theAudio = _theAudio;

- (void)viewDidLoad {

    if (!theAudio) {

        NSString *soundPath =[[NSBundle mainBundle] pathForResource:@"bell1" ofType:@"caf"];
        NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
        NSError *error;

        _theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
        [self.theAudio setDelegate:self];
        [self.theAudio setNumberOfLoops:0];

        [self.theAudio prepareToPlay];
    }
}

-(IBAction)pushBell {

   [self.theAudio play];
}

@end

I'm assuming that BellController is a UIViewController, if it's a different kind of class just modify the code accordingly.

Solution 4

I think that it is a memory issue, you should instantiate the AVAudioPlayer *theAudio as a global class object and initialise it in the init method. Then just run the [theAudio play]; method in the -(IBAction)pushBell method.

I responded do a similar issue related to playing a system sound (which in fact is what you are trying to do), check it out my response is at the bottom:

Couldn't play system sound after switching to iOS 5

By the way consider playing the bell as a system sound, AVAudioPlayer is more appropriate to play sound tracks, not bells and effects.

I hope that it helps.

Solution 5

I agree with hooleyhoop. Try

NSLog(@"%@", error.userInfo) 

to see what's coming out.

Another alternative would be to set up the player object in either viewDidLoad or initWithNib and storing it as a property on your object. This way you can use something like [self.theAudio prepareToPlay];

To avoid loading up the audio each time you press the button, which could save you some time if it's high quality audio. Then just call [self.theAudio play]; in you IBAction method.

Sorry, if this answer is a little sloppy - typing on an iPad so can't double check properly.

Share:
24,272
Aen Tan
Author by

Aen Tan

Aenism.com

Updated on July 16, 2022

Comments

  • Aen Tan
    Aen Tan almost 2 years

    I've searched and I believe my problem is quite unique. I'm aware of the Simulator 5.1 bug when using AVAudioPlayer which isn't my problem. I'm running on a iOS 5.1 device.

    Here's my header file:

    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import <AVFoundation/AVAudioPlayer.h>
    
    -(IBAction)pushBell;
    
    @end
    

    and my implementation file:

    #import "BellViewController.h"
    
    @interface BellViewController ()
    
    @end
    
    @implementation BellViewController
    
    -(IBAction)pushBell {
    
        NSString *soundPath =[[NSBundle mainBundle] pathForResource:@"bell1" ofType:@"caf"];
        NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
        NSError *error;
    
        AVAudioPlayer *theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error];
        [theAudio setDelegate:self];
        [theAudio setNumberOfLoops:0];
        [theAudio play];
    
    }
    
    @end
    

    And I have a button in my .xib that plays the file.

    To make sure I referenced my audio file correctly, I deliberately type a wrong file name and indeed I got an exception. To make sure the file is playable, I mailed it to myself and played it on the device.

    When I tap the button I hear nothing. There are no errors. I don't know what is wrong.

    More information iPhone 4 with iOS 5.1 Xcode 4.3.2 Audio is about 700kbps converted to .caf format using afconvert from a big .wav file.

  • Dinakar
    Dinakar almost 12 years
    tnx jowie,i fixed my issue after wasting lot of time debugging to make sure i am the path correctly to the avplayer object.Nice to learn OS has bugs.
  • jowie
    jowie almost 12 years
    yep... iOS is great, but far from perfect ;)
  • jowie
    jowie almost 12 years
    "Audio not playing" seems to reappear so many times in my coding life, it's just a different reason every time! And this one was my latest... With ARC switched on, alloc init isn't enough to ensure an object stays in memory! Thanks :)
  • jowie
    jowie over 11 years
    Funny thing is that, as WAV files, these will play regardless of whether they show up in the Bundle Resources or not. As CAF files, they don't play unless added.
  • jowie
    jowie over 11 years
    I've also noticed that when you add a WAV file to your Xcode (4.4) project, it will have Add To Target automatically checked. With CAF files, this check box defaults to off. I have no idea why they did this and it catches me out all the time! Anyone else?
  • Yan
    Yan over 11 years
    Thanks!!! Saved me at least another few hours of trying to figure this out on iOS 5 and iPad 1 at 1AM
  • jowie
    jowie about 10 years
    I'm not sure if I missed it at the time, but if your side switch is set to Lock Rotation, then Mute is available in the Control Center, and vice versa. It's possible that was the case on iOS 5.1 as well, but I didn't realise it at the time.
  • escapecharacter
    escapecharacter almost 9 years
    My god, this got me too. On an iPhone 6. When sound played through other apps (a video I recoded then immediately played back).
  • Yimin Rong
    Yimin Rong about 8 years
    Thanks, you saved me so much hassle. This is year 2016 - still not fixed!