How to play audio, even when mute button is on? - objective-c

I'm trying to play an audio file when a button is tapped.
If I step through my code it works, but if I just tap on the button no sound is played.
Here is my code:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
AVAudioPlayer * player;
NSString * path = [[NSBundle mainBundle] pathForResource:#"soundOne" ofType:#"mp3"];
NSURL * url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[player play];
Is this the appropriate way to play audio? Nothing is being flagged as being deprecated.
I also see this message in the debugger:
AudioQueue: request to trim 0 + 2690 = 2690 frames from buffer containing 1152 frames
EDIT:
This code works.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"soundOne"
ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
self.audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:fileURL error:nil];
[self.audioPlayer prepareToPlay];
self.audioPlayer.currentTime = 0;
[self.audioPlayer play];
How can I play audio with the mute button on?
Here is the code I have tried for this:
CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
OSStatus audioStatus = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
if (audioStatus == kAudioSessionNoError) {
//NSLog(#"audio route: %#", state);
return (CFStringGetLength(state) <+ 0);
}
return NO;

Stick this before you call play:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
That should do it.

Related

How to play audio file of URL link using AVAudioPlayer in iphone objective-c

I am creating a voice communication feature in my application that sends voice notes between users via a web server, however during
testing I am experiencing an error with playing back message I created
with AVAudioPlayer. The AVAudioplayer just returns a null value.
How do I play an audio file from the URL link with AVAudioPlayer?
if (!self.audioRecorder.recording) {
NSURL *url = [NSURL URLWithString:[#"http://.../sound.mp4"]];
NSLog(#"%#", url);
NSLog(#"PlayBack");
NSData *audioData = [NSData dataWithContentsOfURL:url];
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0]
stringByAppendingPathComponent:#"sound1.caf"];
[audioData writeToFile:filePath atomically:YES];
NSError *error;
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:fileURL error:&error];
if (self.audioPlayer == nil) {
NSLog(#"%#", [error description]);
NSLog(#"%#", [self.audioPlayer description]);
}else
[self.audioPlayer play];
}else [self.audioRecorder stop];
please try out this code:
- (void) playMessageSound : (NSString *) filename{
self.soundFilename = filename;
//[[RBDMuteSwitch sharedInstance] detectMuteSwitch];
NSString *name = [filename stringByDeletingPathExtension];
NSString *extension = [filename pathExtension];
NSString *filePath = [[NSBundle mainBundle]pathForResource:name ofType:extension];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:fileUrl error:&error];
self.audioPlayer.numberOfLoops = 0;
self.audioPlayer.volume = 1.0;
[self.audioPlayer play];
}
check this
NSString* resourcePath = #""; //your url
NSData *_objectData = [NSData dataWithContentsOfURL:[NSURL URLWithString:resourcePath]];
NSError *error;
app.audioPlayer = [[AVAudioPlayer alloc] initWithData:_objectData error:&error];
app.audioPlayer.numberOfLoops = 0;
app.audioPlayer.volume = 4.0f;
[app.audioPlayer prepareToPlay];
if (app.audioPlayer == nil)
NSLog(#"%#", [error description]);
else
[app.audioPlayer play];

AVAudioPlayer Play/Pause/Stop local audio file on three different buttons

I want to play/pause/stop local audio file. Buttons for all functionalities are different. Check attached screenshot for reference.
Below is my click events,
-(IBAction)click_Play:(id)sender {
NSString *path;
NSURL *url;
//where you are about to add sound
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
path =[[NSBundle mainBundle] pathForResource:#"MySong" ofType:#"mp3"];
url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
[player setVolume:1.0];
[player prepareToPlay];
[player play];
}
-(IBAction)click_Pause:(id)sender {
[player pause];
}
-(IBAction)click_Stop:(id)sender {
[player stop];
}
Here, I am facing issue in pause functionality. After pausing the audio when I click on play button again. It start playing from starting and not at the point where I pause it. Any solution?
Thanks in advance!
Change your code to this:
-(IBAction)click_Play:(id)sender {
if (!player)
{
NSString *path;
NSURL *url;
//where you are about to add sound
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
path =[[NSBundle mainBundle] pathForResource:#"MySong" ofType:#"mp3"];
url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
[player setVolume:1.0];
[player prepareToPlay];
[player play];
}
else {
[player play];
}
}
Don't create instance of AVAudioSession and AVAudioPlayer again and again in play button action. So, keep it simple, create instance of AVAudioSession and AVAudioPlayer in viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path;
NSURL *url;
//where you are about to add sound
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
path =[[NSBundle mainBundle] pathForResource:#"MySong" ofType:#"mp3"];
url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
[player setVolume:1.0];
[player prepareToPlay];
}
-(IBAction)click_Play:(id)sender {
[player play];
}
-(IBAction)click_Pause:(id)sender {
[player pause];
}
-(IBAction)click_Stop:(id)sender {
[player stop];
}
Edit:
Call this method when you what to change track. I'll never recommend to create instance of object again and again
-(void)changeTrackWithPath:(NSString *)path{
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:path]];
[player replaceCurrentItemWithPlayerItem:playerItem];
[player play];
}

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 doesn't work with (NSString *)filename

I want to implement a player that plays sounds and/or music. I have these two methods:
-(void)playSound:(int)soundIndex
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[SoundFxFilenameArray objectAtIndex:soundIndex] ofType:#"mp3"]];
if(FxPlayer)
{
[FxPlayer release];
FxPlayer = nil;
}
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategorySoloAmbient error:nil];
FxPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[FxPlayer play];
}
-(void)playMusic:(NSString *)filename
{
NSURL *url = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:filename ofType:#"mp3"]];
if(MusicPlayer)
{
[MusicPlayer release];
MusicPlayer = nil;
}
MusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[MusicPlayer play];
}
Now, [[SoundPlayer sharedManager] playSound:FXIndex_Default] works just fine. When I try to play music though, [[SoundPlayer sharedManager] playMusic:#"music_file_name_here" just doesn't do anything. Note that both the sound file and the music file are of the same format (mp3).
Also, the "sharedInstance" is because I implemented the singleton pattern for this audio player.
Any pointers or ideas on what is so wrong in my code so that I can play sounds but not music?
Use fileURLWithPath instead of URLWithString in playMusic:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:filename ofType:#"mp3"]];
URLWithString expects a complete URL such as "file://path/to/file.mp3" as argument, fileURLWithPath expects just a file path.

Cocoa Touch - Loading AVAudioPlayer

I have this code to play a sound but the first time you play it it takes a good 5 seconds to load...
How can I speed this up?
-(IBAction)playSound{ //play the cricket noise
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"Cricket_Sound" ofType:#"mp3"];
audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundPath] error:NULL];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
}
You can try by putting the following section of your code in viewDidLoad so that the audioPlayer instance is ready to play before it is asked to actually play the audio:
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"Cricket_Sound" ofType:#"mp3"];
audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundPath] error:NULL];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
audioPlayer.numberOfLoops = 0;