Getting my AVAudio player to work - objective-c

I'm trying to use AVAudioPlayer to play an mp3. Here is the code that I have:
- (void) playClip {
NSString *mp3File = [[NSBundle mainBundle] pathForResource:#"inFavor" ofType:#"mp3"];
AVAudioPlayer *avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3File] error:NULL];
[avPlayer play];
}
the name of the file that I'm referencing is "inFavor.mp3"
I'm a bit new to Objective-C so I'm not exactly sure why this isn't working. I'm using Xcode 5.

Make the AVAudioPlayer a property of the class so that it is not released when the function goes out of scope.
#property (strong, nonatomic) AVAudioPlayer* avPlayer;
Then initialize with
self.avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3File] error:NULL];

try this code, you need to check the error. paste the log you are getting in error
NSError *error;
NSString *path = [[NSBundle mainBundle] pathForResource:#"inFavor"
ofType:#"mp3"];
AVAudioPlayer* avPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:&error];
if (error) {
NSLog(#"failed playing error: %#", error);
}else{
//avPlayer.delegate = self;
[avPlayer play];
}

Related

Playing a simple Audio file in iOS

A very common question but I can't figure out what I'm doing wrong in playing a simple audio file in iOS 10 and 9. I have the following code:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
NSString *soundFilePath = [NSString stringWithFormat:#"%#",[[NSBundle mainBundle] pathForResource:#"www/sounds/ringbacktone" ofType:#"mp3"]];
[self playTone:soundFilePath Loop:YES];
-(void) playTone:(NSString *) soundFilePath Loop:(BOOL) loop{
NSLog(#"Sound File Path: %#",soundFilePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:soundFilePath]){
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error = nil;
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
if (error){
NSLog(#"Error creating the audio player: %#",error);
}else{
if (loop == YES)
player.numberOfLoops = -1; //Infinite
[player setVolume:1.0];
[player play];
}
}else{
NSLog(#"No sound will be played. The file doesn't exist.");
}
}
The output is
Sound File Path: /var/containers/Bundle/Application/E8CCA88C-B6AB-4C36-9426-EFBB94E1D509/myapp.app/www/sounds/myfile.mp3
The file exists so the sound should play. I've tried wav,m4a and mp3 files without success.
I'm using the function before calling pjsip library. Not sure if it plays a role.
Any thoughts? Is there any other way to debug it further?
check this solution it may work :
1.create property for ur audio player:
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
2.write delegate methods for player: AVAudioPlayerDelegate
3.implement this in ur action :
yourSoundArray=[NSArray arrayWithObjects:#"sound1",#"sound2",#"sound3",#"sound4",#"sound5",#"sound6", nil];//dont include formate type
NSString *audioPath = [[NSBundle mainBundle] pathForResource: [yourSoundArray objectAtIndex:indexPath.row] ofType:#"mp3"];
NSLog(#"%#",audioPath);
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *audioError = [[NSError alloc] init];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&audioError];
audioPlayer.delegate=self;
if (!audioError) {
NSLog(#"playing!");
audioPlayer play];
}
else {
NSLog(#"Error!");
}
check the audio player-delegate action
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{ NSLog(#"%d",playing the audio);
}
The answer was a combination of these:
in .h file I had to inherit from AVAudioPlayerDelegate, i.e.
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#interface scAudioManager : NSObject <AVAudioPlayerDelegate>{
#property (strong, nonatomic) AVAudioPlayer *player;
}
And then in .m file:
NSString *soundFilePath = [NSString stringWithFormat:#"%#",[[NSBundle mainBundle] pathForResource:#"www/sounds/ringbacktone" ofType:#"mp3"]];
[self playTone:soundFilePath Loop:YES];
-(void) playTone:(NSString *) soundFilePath Loop:(BOOL) loop{
NSLog(#"Sound File Path: %#",soundFilePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:soundFilePath]){
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error = nil;
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
if (error){
NSLog(#"Error creating the audio player: %#",error);
}else{
if (loop == YES)
_player.numberOfLoops = -1; //Infinite
_player.volume=[[AVAudioSession sharedInstance] outputVolume];
_player.delegate = self;
[_player prepareToPlay]
[_player play];
}
}else{
NSLog(#"No sound will be played. The file doesn't exist.");
}
}

Play sound when app is in background or screen is locked

I have a timer that plays a sound when time reaches 0, but now I can't understand how to fire the event in order to play the sound if the app is in background mode or the screen is locked, What I found searching on the web was to set "UIBackgroundModes" in my .plist file, and add "audio" as array member.
UIBackgroundModes Array
Item0 String audio
Then add in the app delegate the following code:
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
But the sound doesn't get played.. So I was wondering if it's possible to do something like this or I should change method
EDIT:
I imported:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
And this is the code I use to create the sound:
AVAudioPlayer *player;
NSString *soundFilePath = [NSString stringWithFormat:#"%#/clock.mp3",
[[NSBundle mainBundle] resourcePath]];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL
error:nil];
player.numberOfLoops = -1;
dispatch_async(dispatch_get_main_queue(), ^{
[player prepareToPlay];
});
Then to play it:
[player play];
I have just a snippet of Swift code but it should be easy to convert it to Obj-C
Try to use AVPlayerItem init with URL and then set AVPlayer init with PlayerItem
let assetUrl = self.nowPlayingItem!.associatedItem!.valueForProperty(MPMediaItemPropertyAssetURL) as! NSURL
let playerItem = AVPlayerItem(URL: assetUrl)
if let player = self.player {
player.replaceCurrentItemWithPlayerItem(playerItem)
} else {
self.player = AVPlayer(playerItem: playerItem)
}
self.player!.play()
and for this line of code:
NSString *soundFilePath = [NSString stringWithFormat:#"%#/clock.mp3",
[[NSBundle mainBundle] resourcePath]];
Have you tried:
[[NSBundle mainBundle] URLForResource:#"song" withExtension:#"mp3"];
// Create a new player item
NSURL *assetUrl = [nowPlayingItem valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:assetUrl];
// Either create a player or replace it
if (self.player) {
[self.player replaceCurrentItemWithPlayerItem:playerItem];
} else {
self.player = [AVPlayer playerWithPlayerItem:playerItem];
}
nowPlayingItem is here a MPMediaItem but just replace NSURL *assetUrl = [nowPlayingItem valueForProperty:MPMediaItemPropertyAssetURL]; by NSURL *assetUrl =[[NSBundle mainBundle] URLForResource:#"song" withExtension:#"mp3"];

AVAudioPlayer is causing leaks under ARC

I have a class that provides a Music Player, compiled under ARC. This is the init code:
- (id) init{
self = [super init];
runningVolumeNotification = FALSE;
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
systemVolume = musicPlayer.volume;
NSString *myExamplePath = [[NSBundle mainBundle] pathForResource:#"servo" ofType:#"mp3"];
AVAudioPlayer* p = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:myExamplePath] error:NULL];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[p prepareToPlay];
[p stop];
return self;
}
Instruments reports a 100% leak on the line:
AVAudioPlayer* p = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:myExamplePath] error:NULL];
I can't figure out where the problem is!

background music

(using AVFoundation.framework)
#import "AVFoundation/AVFoundation.h"
So I got a problem, I tried this code first in init method of my class (that is the one that is loaded first)
NSString* soundFilePath = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"];
NSURL* soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops=-1;
[player play];
But it didn't work, than I decided to do it in thread:
in init method:
[NSThread detachNewThreadSelector:#selector(playMusic) toTarget:self withObject:nil];
and method itself:
-(void) playMusic {
NSString* soundFilePath = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"];
NSURL* soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops=-1;
[player play];
}
it is declared in *.h file of course. It also didn't work.
I tried to debug, on line
}
of playMusic method the file is played for 2 or 3 seconds and then stops. It isn't played without debug. What is the problem?
The AVAudioPlayer will be deallocated immediately. You need to retain the player.
So make the AVAudioPlayer an instance variable of the class.

Objective C error when playing multiple sounds

Hi i am trying to play many sounds using AVAudioPlayer and foundation.
The code is this
- (IBAction)pushButton19 {
NSString *path = [[NSBundle mainBundle] pathForResource:#"The Terminator" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
- (IBAction)pushButton20 {
NSString *path = [[NSBundle mainBundle] pathForResource:#"The Wizard of Oz" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
on the line theAudio.delegate = self;
it says
class * does not implement the
protocol
as well as
Semantic Issue Assigning to ID
from
incompatible type MainView *
what do i need to do to fix it and can u show me the correct code as im a noob at this?
Your controller must conforms to the AVAudioPlayerDelegate protocol and implements its necessary methods. This is a sample code for playing sound.