I have an app which plays audio using AVPlayer and I touch the right APIs to get the Now Playing info to update in Control Center.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:0 error:&categoryError];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeSpokenAudio error:&modeError];
[[AVAudioSession sharedInstance] setActive:YES error:&activeError];
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = {...};
...
MPRemoteCommandCenter * const commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
commandCenter.playCommand.enabled = YES;
...
This API works as expected, until some ads appear using Google's AdMob framework. These are the standard MREC and banners which are presented in UIWebView instances. As soon as one appears, the Now Playing state reverts back to the Music app, and the ability to use the remote controls disappears.
Once this happens, I can't even re-set the Now Playing info, it's like it's stuck. Although, when I print out the value of [[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo, it is as I expect, it just doesn't show.
The ads play no audio or video, but somehow they are corrupting the Now Playing API and it does not recover.
I've reached out to Google and Apple as to how to fix this, but in the meantime wondered if anyone had any workarounds to suggest?
I found this question when looking into a similar issue with the Google Interactive Media Ads SDK (IMA SDK) where it was automatically changing the Now Playing state to just say "Advertisement". Ultimately found the flag on the IMAAdsSettings object, disablesNowPlayingInfo Documentation. Setting this to true resolved my issue.
let adsLoaderSettings = IMASettings()
adsLoaderSettings.disableNowPlayingInfo = true
adsLoader = IMAAdsLoader(settings: adsLoaderSettings)
Related
In my application, playback is controlled from control center.
When playback is going on in AVPlayer(At this time playback controls are working fine from control center), I am loading a webview with other streaming URL.
Once streaming is done again I am starting playback from AVPlayer.
After this, Playback controls are greyed out in control center.
I am using [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo to enable playback control in control center.
What would be the problem?
I ran into this problem as well working with an AVPlayer instance. You can use MPRemoteCommandCenter to set up controls on the lock screen and command center.
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
commandCenter.previousTrackCommand.enabled = YES;
[commandCenter.previousTrackCommand addTarget:self action:#selector(previousTapped:)];
commandCenter.playCommand.enabled = YES;
[commandCenter.playCommand addTarget:self action:#selector(playAudio)];
commandCenter.pauseCommand.enabled = YES;
[commandCenter.pauseCommand addTarget:self action:#selector(pauseAudio)];
commandCenter.nextTrackCommand.enabled = YES;
[commandCenter.nextTrackCommand addTarget:self action:#selector(nextTapped:)];
previousTapped:, playAudio, pauseAudio, and nextTapped are all methods in my view controller that call respective methods to control my AVPlayer instance. To enable an action, you must explicitly set enabled to YES and provide a command with a target and selector.
If you need to disable a specific action, you must explicitly set the enabled property to NO in addition to adding a target.
commandCenter.previousTrackCommand.enabled = NO;
[commandCenter.previousTrackCommand addTarget:self action:#selector(previousTapped:)];
If you do not set enabled for the command, the item will not appear at all on the lock screen or in command center.
In addition, remember to set your app up for background playback (add the UIBackgroundModes audio value to your Info.plist file.), set the player active, and check for errors:
NSError *setCategoryError;
NSError *setActiveError;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
[[AVAudioSession sharedInstance] setActive:YES error:&setActiveError];
Google brought me here because I was having an issue with the command center when using AdMob video ads, and a comment on the OP referenced AdMob. Posting here for anyone else also having these issues.
AdMob video ads on iOS seem to utilize the MPRemoteCommandCenter for whatever reason. This may interfere with your app's usage of the command center. Here's what I came up with as a potential workaround to this: https://gist.github.com/ekilah/e74683291d3e7fafb947
The "gist" of the workaround is to reset all of the sharedCommandCenters listeners and the MPNowPlayingInfoCenter's info dictionary after an ad from AdMob is fetched and after it's played. The way the workaround goes about resetting all of the commands is less than pretty, but this is what I came up with. Maybe someone has a better method?
This approach may also help the OP. Resetting things between different usages may be a solution.
Finally I solved this problem by loading the mp3 url using AVplayer instead of loading it in UIWebview. Current playback time, total time can be retrieved from AVPlayer and also it is possible to seek the playback using slider.
Hope this question doesn't get down voted - I haven't seen anything in the documentation.
I want to play music from the ipod library while the app is in the back ground.
I am creating the music player using the default mechanism.
-(void)viewWillAppear:(BOOL)animated
{
MPMusicPlayerController *myPlayer =
[MPMusicPlayerController applicationMusicPlayer];
// assign a playback queue containing all media items on the device
[myPlayer setQueueWithQuery: [MPMediaQuery songsQuery]];
// start playing from the beginning of the queue
[myPlayer play];
}
As soon as the app enters the background the music stops playing. I would like it to continue playing though.
I do not want to use the iPodMusicPlayer option
How can I do this?
You should set background audio mode in the project settings (Project settings > Capabilities > Background modes > Audio and AirPlay) like it's shown on the screenshot below:
Also you should set Audio Session Category in the appDelegate (in the didFinishLaunching method). Example is shown below:
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
I have same issue. I searched even after added flag in plist. It will not work because :
The applicationMusicPlayer does not support background music. Use
MPMusicPlayerController's systemMusicPlayer instead. It shares the
state with the built-in System player and music will continue to play
when your app enters the background.
Other Solution is :
You can use AVAudioPlayer to play either streamed or local(bundle) audio. It even allows you to play multiple audio file at the same time having an AVAudioPlayer instance for each.
Note : iPodMusicPlayer is deprecated. so Instead of this use systemMusicPlayer.
I'm using the Spotify iOS SDK and have a question about the background music.
When a user locks the phone or presses the Home button I want my app to continue to play the music. How is this possible?
I've tested
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
Together with adding "Required background modes" to the apps plist.
Does this require that the AVAudioPlayer is used? Since I'm using the Spotify streamingPlayer its not possible.
Background playback should work just fine. You do need the audio item in your UIBackgroundModes Info.plist entry, though. Also, make sure you test on a device - I know remote control events don't work in the iOS Simulator, and that might be the case for background audio as well.
The iOS SDK will automatically set up the AVAudioSession for you, so you don't need to do that.
You might find this answer helpful, which is more in-depth: Background Audio with cocoalibspotify.
I want to have a sound effect in my iOS that, if other audio is playing (such as iTunes) quiets any other audio is playing and plays over top of it. I know
AVAudioSessionCategoryOptionMixWithOthers
Will mix the sounds together, but I want mine to be able to be heard clearly. I've seen this done in the RunKeeper app (when the lady describes your run to you it quiets your music) but I can not find it in Apple's Documentation.
Anyone have experience with this?
Apple's documentation says this only works with PlayAndRecord, but it works.
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDuckOthers error: nil];
Target OS: iOS 6+
Devices: Phones only
I'm creating an fairly simple locative media app. The one technical difficulty I'm having is whether or not I can do what I want with background audio.
I receive GPS location updates successfully in the background but I would like to use these to trigger audio on region entry. The app does not play audio constantly in foreground, only on entry to these fences.
Does the 'playing silence' trick still work to keep the Audio Session and is this an app where Apple would tolerate its use? If so could anyone provide recently functional code for it?
If you set up your application to also enable background audio, in application:didFinishLaunching: like so:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
and add audio as a background mode in the app's plist file, your app will keep on running in the background and play sounds when it wishes (e.g. when a location change has happened). However, I think you have to close the application while playing sound.
However, there might be an issue with this, because background audio is meant for apps that actually keep running a track/stream in the background. I could see how Apple might reject your app for using their API in an unintended way. So this is the problem with the playing silence trick.
Also, another problem could be that if the user goes out of your app, then starts playing their music through Music or any other music app (Spotify, a radio app etc.) that has access to background audio, your application's audio permissions will be disabled (your app won't be able to play sound anymore through the audio framework, because another app has taken control of the background audio).
An option I would recommend: throw a local notification with your own sound when the user changes location:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.soundName = #"your-sound-file-name";