background audio working on iOS simulator but not device - ios

I'm writing an alarm clock application that works by playing looped silence in the background until it's time for the alarm to fire, at which point it plays the alarm sound on loop until the user opens the app. Here's my code from applicationWillResignActive:
UIApplication *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask = 0;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"silence" ofType:#".wav"];
NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
[player setNumberOfLoops:-1];
alarmTimer = [NSTimer scheduledTimerWithTimeInterval:timerInterval target:self selector:#selector(playAlarm) userInfo:nil repeats:NO];
[player prepareToPlay];
[player play];
here's the method triggered by the timer:
[player stop];
NSString *soundPath = [[NSBundle mainBundle] pathForResource:#"Alarm" ofType:#".m4r"];
NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
[player setNumberOfLoops:-1];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[player prepareToPlay];
[player play];
This works as intended when I test it on the simulator. On my iPhone, the timer's method does get called but audio doesn't play. I did add background audio to my plist file. The iPhone's case-sensitivity to the name of the audio file is not the problem and the iPhone's mute switch is off. Thanks for reading!

solved: apparently you can't initiate audio from the background. workaround is to call the method that plays audio from the main thread using performSelectorOnMainThread:withObject:waitUntilDone:.

Related

Sounds not playing on iPhone 7 iOS 10

I have apps that play sounds. They play fine on an iPad Air 10.3.1, but not on my iPhone 7 10.3.1. I've tried different audio formats and nothing plays on the iPhone 7. Is there some entry in the plist or some other setting I need to get sounds to play on iPhone 7?
ViewController.h
#property (strong,nonatomic) AVAudioPlayer *player;
ViewController.m
- (void)viewDidAppear:(BOOL)animated {
NSError *err;
NSURL *url = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"sound" ofType:#"wav"]];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
if (err) NSLog(#"error");
player.volume = 1.0;
player.delegate = self;
[player prepareToPlay];
[player play];
NSLog(#"sound should have played");
}
I added this and now it works. Not sure why it worked before on other devices.
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];

AVAudio layer is not playing the sound in ios

Hi in my application I am using UILocalNotifications and AVAudiopPlayer to play a song. When a notification comes I am trying to play a song when I select notification alert. Here is the code, I am getting the sound but isplaying property is setting as YES.
In AppDelegate:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
MainViewController *main=[[MainViewController alloc]init];
[main playSong:notification.soundName];
}
-(void)playSong:(NSString *)songName
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:songName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
[_audioPlayer setDelegate:self];
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
_audioPlayer.numberOfLoops = -1; //Infinite
[_audioPlayer prepareToPlay];
[_audioPlayer play];
}
Replace your code with following code and then try it may be help you.
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
MainViewController *main=[[MainViewController alloc]init];
[main playSong:notification.soundName];
}
-(void)playSong:(NSString *)songName
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:songName ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
[_audioPlayer setDelegate:self];
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL: soundFileURL fileTypeHint:AVFileTypeMPEGLayer3 error:&errorAudio];
_audioPlayer.numberOfLoops = -1; //Infinite
[_audioPlayer prepareToPlay];
[_audioPlayer play];
}

Playing Background Music in Objective-C

Ive tried previous question tutorials and still am not able to figure out how to play background music. I just want to play simple background music over loops. I've tried this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"drums" ofType:#"mp3"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPathath] error:NULL];
theAudio.delegate = self;
theAudio.numberOfLoops = -1;
[theAudio play];
I still can't get it to play. Ive also tried changing the background tasks of my info.plist to suit audio but couldn't find where to do that.
Add this key in your plist
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
add some more line of code in your code
theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
theAudio.delegate = self;
theAudio.numberOfLoops = -1;
[theAudio play];
This work for me.

Playing music in background ios app

In my code:
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSURL* musicFile = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"www/media/BlueZedEx" ofType:#"mp3"]];
AVAudioPlayer *click = [[AVAudioPlayer alloc] initWithContentsOfURL:musicFile error:nil];
NSLog(#"goldenace launchOptions = %#", musicFile);
click.delegate = self;
click.numberOfLoops = -1;
[click play];
}
But nothing music play when I run my app in simulator.
Please help!
use this for Playing Background Audio:
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
refer this link
This
www/media/BlueZedEx
is not a filename.
It needs to be a filename of a audio file inside your project (drag and drop)

Trigger AVAudioPlayer to stop all sounds and play selected except when playing(selected) button is clicked

I am creating a sound board app that plays one sound at a time. I would like a UIButton to be able to stop all other sounds playing and start playing its own sound when clicked. I have a single AVAudioPlayer set up to play all sounds (I change the sound file url when clicked and since I only want one sound at a time playing this is not an issue). I would like to know how to stop all other sounds and play the sound according to the button pressed, but if the button clicked is the button with the sound currently playing, the button only stops the sound. I know this is achievable through going to separate audioplayers and triggering the stop event but I want to avoid copy and pasting code and to stay efficient as possible, plus I only want / need a single audioplayer. Here is my code:
- (IBAction)play {
if (audioPlayer.playing == NO) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/k.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
[audioPlayer release];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
AVAudioSession *audiosession = [AVAudioSession sharedInstance];
[audiosession setCategory:AVAudioSessionCategoryAmbient error:nil];
[audioPlayer play];
[start setTitle:#"Stop" forState:UIControlStateNormal];
}
else
if (audioPlayer.playing == YES) {
[audioPlayer stop];
[start setTitle:#"Start" forState:UIControlStateNormal];
}
}
- (IBAction)play2 {
if (audioPlayer.playing == NO) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/chicken.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
[audioPlayer release];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
AVAudioSession *audiosession = [AVAudioSession sharedInstance];
[audiosession setCategory:AVAudioSessionCategoryAmbient error:nil];
[audioPlayer play];
[start2 setTitle:#"Stop" forState:UIControlStateNormal];
} else
if (audioPlayer.playing == YES) {
[audioPlayer stop];
[start2 setTitle:#"Start" forState:UIControlStateNormal];
}
}
Any help is appreciated. Thank you in advance!
Just do this
-(void)stopAudio{
if(audioPlayer && [audioPlayer isPlaying]){
[audioPlayer stop];
audioPlayer=nil;
}
}
And call this function on every click..
- (IBAction)play2 {
[self stopAudio];
//Do your Stuffs
}
when your button is clicked stop your audio player and assign your new song url and then play it.Write this code when you click on button to play song.
if(audioPlayer.isPlaying)
[audioPlayer stop];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
NSURL *url = [NSURL fileURLWithPath:YourSoundURL];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.delegate=self;
[audioPlayer play];
[start2 setTitle:#"Stop" forState:UIControlStateNormal];

Resources