iOS 8.1
I have a number of instances of AVPlayer playing sound effects, I also have an instance of AVAudioPlayer playing music.
Randomly when using the app the interface will hang for a split second and the music will stop, after this point none of the AVPlayer plays will trigger.
I'm getting nothing in the log and can't seem to find any reason for the players to stop. I have been unable to reproduce the issue reliably, it seems to happen without any direct cause.
Interestingly even when using MPMusicPlayerController in place of AVAudioPlayer I am experiencing the same problem: Music from my iTunes library will stop just as the AVAudioPlayer tracks did.
Has anybody experienced anything like this? I am completely stumped.
NSURL *urlRadio;
if (is2P){
urlRadio = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"retroremix" ofType:#"mp3"]];
} else {
urlRadio = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"pixel" ofType:#"mp3"]];
}
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlRadio error:nil];
if (!ownMusic){
[audioPlayer play];
} else {
[mDRMAudioPlayer prepareToPlay];
}
I'm getting nothing in the log
I suggest registering for the AVAudioSessionMediaServicesWereResetNotification. Then you'll get something in the log! The problem, I'm guessing, is that the media services daemon is being hosed. You might be crashing it, or some other app might be doing it. I'm guess that you're doing it, but that's neither here nor there; if you discover that you are the cause, you'll need to figure out why. Either way, you need to be prepared for this possibility. If the notification fires, you must throw away all audio and video players and recreate them from scratch.
(And see Apple's Q&A document on this topic: https://developer.apple.com/library/ios/qa/qa1749/.)
Related
The app I am working on using MPMoviePlayerController to play video at remote urls. When I reuse the player to play more than one video and the url doesn't point to a video, the controller doesn't send any notification back. I've tried MPMoviePlayerPlaybackDidFinishNotification, MPMoviePlayerPlaybackStateDidChangeNotification and MPMoviePlayerLoadStateDidChangeNotification. None of them was sent.
I also tried to do a custom time out function and calls the player's stop function like below. But, nothing happens. MPMoviePlayerController just seems dead there and doing nothing.
[self performSelector:#selector(checkTimeout) withObject:theMovie afterDelay:15];
-(void) checkTimeout {
[self.moviePlayer stop];
}
Does anyone know how to handle invalid url with MPMoviePlayerController?
I found a kind of solution myself.
It seems MPMoviePlayerController has problem playing more than one urls. If the 2nd url doesn't point to a video or invalid, the player doesn't do anything. So, I ended up creating a new instance of the MPMoviePlayerController for every url and listening to MPMoviePlayerPlaybackDidFinishNotification.
If you did not receive notification on invalid urls, then you should run a timer of duration max(initialplaybacktime, 0) and once you do not receive MPMoviePlayerReadyForDisplayDidChange notification within this time, generate an error that video is not available.
I am trying to play remote video with MPMoviePlayerViewController like this.
NSURL *url = [NSURL URLWithString: #"http://km.support.apple.com/library/APPLE/APPLECARE_ALLGEOS/HT1211/sample_iTunes.mov"];
self.mp = [[MPMoviePlayerViewController alloc]
initWithContentURL:url];
[self.navigationController presentMoviePlayerViewControllerAnimated:self.mp];
I can play above url. However, I can't play my own video file url like this. It is running on local server and it is pointing to file location.
http://127.0.0.1:8000/media/through_your_eyes/file0.mov
Is it client or server side problem? Shall I point to file location on server side or how shall I prepare?
It is server side problem
From your end you are doing well.
When you trying to play video - getting error like this
_itemFailedToPlayToEnd: {
kind = 1;
new = 2;
old = 0;
}
This shows that MPMoviePlayerViewController not able to play video from this url.
Reasons:
Your url is not proper - print NSURL object check its proper and escape character are there (If required)
Permission - It is not permitted to play this video from device. Firewall stop access this video from device. Check that you are permitted to access the url
Video format - Some times video conversion changes the formate of the video. You can see the correct format of the video how ever if conversion is made it is not able to play by the device. Please copy this url paste it in Simulator Safari app and check it is able to play.
Does anyone know how to stop the iphone muting the speaker output whilst a phone call is taking place?
I'm developing an app where I need to be able to play audio through the phone speakers whilst there's a phonecall..
Hope someone can help!
I know there's an accepted answer but I don't think that it's completely correct. Some navigation apps (Waze for instance) are able to give audio directions during phone calls.
If you use AVAudioPlayer you can handle interruptions (i.e. phone calls) by responding to the audioPlayerBeginInterruption: delegate (you can read more about it here).
While I didn't have too much time to look into it I did manage to play a short sound file while initiating a phone call or playing a song by using the following code:
-(void)audioPlayerBeginInterruption:(AVAudioPlayer *)player
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"mySound" ofType:#"mp3"];
SystemSoundID soundFileObject;
NSURL *pathURL = [NSURL fileURLWithPath : path];
CFURLRef soundFileURLRef = (CFURLRef)CFBridgingRetain(pathURL);
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundFileObject);
AudioServicesPlaySystemSound(soundFileObject);
}
Keep in mind that when an interruption comes in your app might be backgrounded or suspended which will also affect your ability to play sounds (or run any other code for that matter).
I don't believe Apple allows other audio to mix with the audio during a phone call. Apple wants to ensure that poorly written apps won't interfere with a user's ability to perform important functions, such as making phone calls, on their phone. So your app is basically forced to comply.
I do not think this is possible and I hope it's not, because personally, I do not want any app recoding my phone calls or interrupting important calls with prank sounds.
I also think this would be a very risky thing to allow if you think about it from a security standpoint.
So I successfully created an app, in this case it's a VOIP app using linphone sip library. I was doing some tests where I want a WAV file to always play, regardless of whether my app is in the foreground or background. I was able to successfully implement this test with the following code:
NSString * resourcePath = [NSString stringWithFormat:#"%#/myres/sounds/oldphone-mono.wav",[[NSBundle mainBundle] resourcePath]];
ringer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:resourcePath] error:nil];
[ringer setNumberOfLoops:100];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[ringer setVolume:1.0];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
[ringer play];
I think this is pretty straightforward code, because I copied it from another stack overflow answer. I also had to do something to my plist file to allow for audio background playing.
So the problem is that a function from some 3rd party software (in this case LinPhone SIP Library's Receive Incoming Call Function) that when fired will prevent my app from playing my sound file in background.
As an example, here's a test case:
start up my app and i hear the ringing wav file, that's good
i put the app in background mode and i still hear the ringing wav file, that's good
i bring the app back into focus, i still hear the ringing, that's good
i trigger the linphone receive call function, the ringing still continues because i'm in foreground, that's good
i put the app in background mode, the ringing stops, that's not good
So I suspect that linphone has done something to the avaudioplayer/avaudiosession, such that i can no longer play in background. So my question is, can anyone hazard a guess as to what linphone may have done to prevent my app from playing sound in the background, and how i might get around this issue?
ADDITIONAL NOTES
I even tried to instantiate a new avaudioplayer every second while the app was in the background. But it couldn't override whatever linphone has done to silence the playing of audio.
It appears that Linphone messed with the AVAudioSession Category Options. I had to reset the category option to AVAudioSessionCategoryOptionMixWithOthers in order to get around the problem like so:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
I'm trying to use the standardized "iPod" audio player to play some MP3 tracks in an iPhone app I'm building. The tracks are downloaded from the internet and stored in the app's "Documents" directory. I thought of using a MPMusicPlayerController to do this, but I don't seem to be able to get it to work. Also, I've seen the AVAudioPlayer, but that just plays the audio without an interface. Any suggestions?
The MPMusicPlayerController is for playing items out of the iPod library (songs sync'd via iTunes) so you won't be able to use it for this.
You can get the NSData for your audio using...
NSData* data = [NSMutableData dataWithContentsOfFile:resourcePath options:0 error:&err];
Then use an AVAudioPlayer created from that data and call play.
AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithData:data error:&err];
[player play];