简体   繁体   中英

Sound not playing with AVAudioPlayer

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.

SOLVED.

1.- Check if your file has been added to "Copy Bundle Resources" in Build Phases. 复制捆绑资源

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.

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.

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.

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.

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.

You should give it some time to prepare the pronunciation since it's probably buffering from a URL.

The code:

[theAudio prepareToPlay];

[self performSelector:@selector(playMusic) withObject:nil afterDelay:3.0];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM