AVAudioPlayer not playing any sound

2020-01-26 03:29发布

I'm working on an iOS application that needs to play some sounds using the AVFoundation framework. The workspace structure in Xcode 4 contains two projects:

  • Workspace
    • The application itself (main project)
    • A utility library

After building the utility library, it results in a static library which is used in the main application as a framework.

So, when trying to play a sound inside the main application by using the code below, it works as expected.

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
NSString *path = [NSString stringWithFormat:@"%@/sound.mp3", resourcePath];

NSURL *url = [NSURL fileURLWithPath:path];
NSError *error = nil;

AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url
                                                                    error:&error];
[audioPlayer play];

In contrast, when trying to play exactly the same sound (or any other) inside the utility library using the same code as above, no sound is played at all, even though error is nil and the audioPlayer property values are the right ones (number of channels, duration).

I've made sure the AVFoundation framework is in both projects.

Also, my class uses the AVAudioPlayerDelegate protocol and implements these two methods:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error;

None of these methods is called after trying to play the sound.

If I use the AudioToolbox framework instead, then it plays the sound. But I'm interested in using AVFoundation for several reasons.

Any idea of what is going on? Am I missing something about AVFoundation? Could it be related to using AVAudioPlayer from inside a static library?

Thanks in advance.

10条回答
做个烂人
2楼-- · 2020-01-26 04:27

I had the same issue. I had resolved it by adding below line in .h file:

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

And in .m file :

NSError *error;
NSString *soundFilePath = [NSString stringWithFormat:@"%@/dancepechance.mp3",
                               [[NSBundle mainBundle] resourcePath]];
    NSURL *url = [NSURL fileURLWithPath:soundFilePath];
    self.audioPlayer = [[AVAudioPlayer alloc]
                                  initWithContentsOfURL:url
                                  error:&error];
    NSLog(@"Error %@",error);
    [self.audioPlayer prepareToPlay];
    [self.audioPlayer play];
查看更多
爷、活的狠高调
3楼-- · 2020-01-26 04:27

Swift Solution:

  import AVFoundation

  // define your player in class
  var player = AVAudioPlayer()

  override func viewDidLoad() {
    super.viewDidLoad() 
  }
查看更多
Emotional °昔
4楼-- · 2020-01-26 04:28

You can use AVPlayerViewController from AVKit instead for both audio and video. Code is available for both swift and objective c here.

查看更多
【Aperson】
5楼-- · 2020-01-26 04:32

I found the solution and it's related to something I didn't mention and didn't think about: I'm compiling with Automatic Reference Counting (ARC).

ARC inserts a release call to the audio player, so it's deallocated right after leaving the method where it is created. It has nothing to do with AVAudioPlayer but with ARC.

In order to solve this issue, I just created an AVAudioPlayer attribute to the class that deals with sounds so that it is not released anymore by ARC. Well, at least, it's not released until the instance of this class is released.

For more information about ARC, refer to Automatic Reference Counting: Zeroing Weak References with details on why I had this issue.

查看更多
登录 后发表回答