Play a loading animation without losing the iPod music - objective-c

I got an app wich include several animations. To load these animations i use the MPMoviePlayerController.
The problem is that if the user is currently listening to some music with an app in background mode, the MPMoviePlayerController fade out the music, even if my animation didn't include any sounds.
Here is the code i use to instantiate my player
NSString *moviePath = [[NSBundle mainBundle] pathForResource:#"anim-geoloc" ofType:#"mp4"];
NSURL *movieURL = [[NSURL fileURLWithPath:moviePath] retain];
player = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
player.repeatMode = MPMovieRepeatModeOne;
player.controlStyle = MPMovieControlStyleNone;
player.movieSourceType = MPMovieSourceTypeFile;
player.shouldAutoplay = YES;
player.useApplicationAudioSession = YES;
[player prepareToPlay];
[movieURL release];
I have tried to change the useApplicationAudioSession attribute but it changes nothing.
How can i play my animation without loosing the music playback ? Is there a better way to perform an animation ?
Thanks

Ok i figured out what's going out. When you use the MPMoviePlayerController and you want to share the audio session with others apps, you must create an audio session like this.
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient error:NULL];
[session setActive:YES error:NULL];
With this, my animation doesn't stop the iPod app's sound anymore.

Related

Moving from MPMoviePlayerViewController to AVPlayer and streaming m3u8

I'm trying to switch from MPMoviePlayerViewController to AVPlayer for video playback in my implementation looks something similar to this
NSURL *movieURL = [NSURL URLWithString:#"http://example.com/somefile.m3u8"];
movieController = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
movieController.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
[self presentMoviePlayerViewControllerAnimated:movieController];
[movieController.moviePlayer play];
My AVPlayer version plays everything but the desired m3u8 stream. It manages to find the file and the AVPlayerViewController shows the right file duration but hangs with an activity indication and never really starts playing.
NSURLComponents *comp = [NSURLComponents componentsWithString:url.absoluteString];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:comp.URL options:nil];
AVAssetResourceLoader *loader = asset.resourceLoader;
[loader setDelegate:self queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:asset];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
I have an observer on the status and it eventually plays when AVPlayer's status is ReadyToPlay.
I can't imagine AVPlayer can play everything MPMoviePlayerController can so how would the right implementation for the AVPlayer version to get this to work.
Like in your previous code (where you did [movieController.moviePlayer play];.
I think you should start your player.
[self.player play];.

Playing music within app

I have a soundtrack I would like to play throughout my app even when users change view controllers and such. I have a loop from a soundtrack that I want to repeat once it finishes. I am currently playing sounds through:
NSString *soundFile = [[NSBundle mainBundle]
pathForResource:#"Click03" ofType:#"wav"];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc]
initWithContentsOfURL:[NSURL fileURLWithPath: soundFile]
error:nil];
[audioPlayer start];
// or [audioPlayer stop];
I am not quite sure if this the best way of playing sounds. Can someone explain to me how to do what I asked above? Thanks in advance!
Basically you are trying to play an background audio..
Check the following links this would help you
Play music in the background using AVAudioplayer
http://www.sagorin.org/2011/11/29/ios-playing-audio-in-background-audio/
For repeating audio check this link
How do I repeat a AVAudioPlayer?
Write code to play sound in Appdelegate.
-(void)PlaySound:(NSString*)strSoundFileName
{
fileURL=[[NSURL alloc] initFileURLWithPath:strSoundFileName];
audioPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
audioPlayer.delegate=self;
[audioPlayer prepareToPlay];
audioPlayer.currentTime=0;
[audioPlayer play];
audioPlayer.numberOfLoops=-1;
}

Play music in the background using AVAudioplayer

I want to play music even if the app goes in background. I checked all stackoverflow links but none of them worked. Please help need to do it today.
I had used following code:-
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"Day At The Beach" ofType: #"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
NSError *error;
playerTemp = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
playerTemp.numberOfLoops = 0;
AudioSessionSetActive(true);
[playerTemp play];
I had solved this question by referring iOS Application Background tasks
and make some changes in .plist file of our application..
Update
write this code in your controller's view did load method like this
- (void)viewDidLoad
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"in-the-storm" ofType:#"mp3"]];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[audioPlayer play];
[super viewDidLoad];
}
I just wanted to add a note to Mehul's answer. This line:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
is actually very important. I used other tutorials to get my AVAudioPlayer up and running. Everything worked fine except my audio would not START if the app was in the background. To clarify, my audio was fine if it was already playing when the app went into the background...but it would not start if the app was already in the background.
Adding the above line of code made it so my audio would start even if the app was in the background.
You need to set 'audio' as one of your UIBackgroundModes in Info.plist. Apple has documentation on the issue.
Write this line in to plist for background run...
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
Write this code Where you want to use
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:self.urlForConevW error:&error];
audioPlayer.delegate = self;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
audioPlayer.numberOfLoops = 1;
[audioPlayer play];
Step1
Make the following changes in info.plist
Application does not run in background : NO
Required background modes
item0 :App plays audio or streams audio/video using AirPlay
Step 2
Don't forget to add the following things in MainViewController.h file
#import <'AVFoundation/AVAudioPlayer.h>
#interface MainViewController:<'AVAudioPlayerDelegate>
AVAudioPlayer *H_audio_player;
Step 3
Add the following code inside the play action of your MainViewController class.
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%d-%d",C_CID, C_SID] ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
H_audio_player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
H_audio_player.delegate = self;
H_audio_player.numberOfLoops = -1;
Also important here if you are using MPMusicPlayerController:
You must use:
[MPMusicPlayerController iPodMusicPlayer]
And Not
[MPMusicPlayerController applicationMusicPlayer]
Also if you don't want your app to stop music which was playing when your app is started, look here:
AVAudioPlayer turns off iPod - how to work around?
You can use MPMoviePlayerController even to play solo-audio movies. If you like it, read this detailed Apple Library Technical Q&A:
iOS Developer Library Technical Q&A QA1668
I use the below code. It work for me, and call on the button click of audio player instance method.
NSError *error; NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"]];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
[[AVAudioSession sharedInstance] setActive:YES error: &error];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self.player prepareToPlay];
From all answers is missing this code to control the player when user is waking the device:
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
[_audioPlayer play];
break;
case UIEventSubtypeRemoteControlPause:
[_audioPlayer pause];
break;
default:
break;
}
}
And you have all these options:
UIEventSubtypeRemoteControlPlay = 100,
UIEventSubtypeRemoteControlPause = 101,
UIEventSubtypeRemoteControlStop = 102,
UIEventSubtypeRemoteControlTogglePlayPause = 103,
UIEventSubtypeRemoteControlNextTrack = 104,
UIEventSubtypeRemoteControlPreviousTrack = 105,
UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
UIEventSubtypeRemoteControlEndSeekingBackward = 107,
UIEventSubtypeRemoteControlBeginSeekingForward = 108,
UIEventSubtypeRemoteControlEndSeekingForward = 109,
If even after setting audio as one of your UIBackgroundModes in the plist the audio stops when going to background, try setting your application's audio session to media playback.
Here's the related reference:
https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Introduction/Introduction.html
Here's about what the code's gonna look like:
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
NSError*setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
To play your audio in background
Step 1 :Just add in your info.plistmake an array
step2 :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
__block UIBackgroundTaskIdentifier task = 0;
task=[application beginBackgroundTaskWithExpirationHandler:^{
NSLog(#"Expiration handler called %f",[application backgroundTimeRemaining]);
[application endBackgroundTask:task];
task=UIBackgroundTaskInvalid;
}];
}
step3 :
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"iNamokar" ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[player prepareToPlay];
[self.player play];
From Apple's sample code: Audio Mixer (MixerHost)
// If using a nonmixable audio session category, as this app does, you must activate reception of
// remote-control events to allow reactivation of the audio session when running in the background.
// Also, to receive remote-control events, the app must be eligible to become the first responder.
- (void) viewDidAppear: (BOOL) animated {
[super viewDidAppear: animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
I think remote control events are not needed for the following case:
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof(value), &value);

AVPlayer Can't Play

I want to play a remote mp3 with AVPlayer. I can't make it work and I can't see the reason why it doesn't work. Code:
NSString *urlstr=#"..some link to a mp3"
NSURL *url=[NSURL URLWithString:urlstr];
self.player = [[[AVPlayer alloc] initWithURL:url] retain];
[player play];
The link is valid. If I load it in a webView it plays right away.
Please help.
I have get a solution. Please try the following code:
NSString *urlstr=#"http://www.3rdeyelab.com/mp3/mp3/tailtoddle_lo.mp3"
NSURL *url=[NSURL URLWithString:urlstr];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
player = [[AVPlayer playerWithPlayerItem:playerItem] retain];
[player play];
player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
Hope it will work for you!!!
If you use a local link as URL, so you should initiate url with fileURLWithPath method:
NSURL *url = [NSURL fileURLWithPath:urlstr];
The NSURLConnection class, regardless of whether the URL is local or remote, should always be used whenever a URL is concerned. It's the only thread-safe, non-intrusive means of loading a AVPlayerItem or AVAsset. Remember: your app shares the iPhone with other apps; and, this is the way to be responsible insodoing.

How to Stop UIWebView from playing mp3?

I am loading a MP3 file into UIWebView control on an iPad Application, I have a UIButton called done the user expected to dismiss the UIWebView and stop the music, here is a code snippet:
// points to the mp3 file path
NSURL *url = [NSURL fileURLWithPath:self.sFilePath];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[web loadRequest:request];
When the user hit done I do the following:
[self.webview removeFromSuperview];
[self.webview release];
But that does not stop the music from playing, I noticed that loading mp3 files on UIWebView opens the QuickTime player is that correct way?
I am greatly appreciative of any guidance or help.
Looks like a dupe of Video/audio streaming does not stop even if UIWebView is closed - iPad
The solution there:
[self.webContent loadRequest:NSURLRequestFromString(#"about:blank")];
I suggest that you play the sound yourself using for example AVAudioPlayer (probably the easiest way to play and control sounds in iOS).
Something like this:
NSURL *url = [NSURL fileURLWithPath:self.sFilePath];
NSData *mySound = [NSData dataWithContentsOfURL:url];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData:mySound error:NULL];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
You can then stop the sound as simple as:
[audioPlayer stop];
or
[audioPlayer pause];
Don't forget to include the AVFoundation.framework in your project.