How to make MPMoviePlayerController ignore the mute switch - ios

I want to play a video using MPMoviePlayerController but I want it to ignore the mute switch, similar to the behavior of Youtube's video player.
Any ideas?

Use the AVAudioSession category AVAudioSessionCategoryPlayback and your app will ignore the mute switch like the Youtube app.
For example (inspired by Ken Pletzer in the comments):
#import <AVFoundation/AVFoundation.h>
// note: you also need to add AVfoundation.framework to your project's
// list of linked frameworks
NSError *error = nil;
BOOL success = [[AVAudioSession sharedInstance]
setCategory:AVAudioSessionCategoryPlayback
error:&error];
if (!success) {
// Handle error here, as appropriate
}

_player.useApplicationAudioSession = NO;

in Swift: Do this once before you play sound/video (for example at the beginning of your application)
do{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch {
//Didn't work
}

For anyone in the future, I know this has been answered already, but I had an issue with playing a video in my app which caused apps like spotify, youtube etc. to stop playing it's audio, so I ending up using this:
NSError *silentSwitcherror = nil;
BOOL silentSwitchSuccess = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&silentSwitcherror];
if (silentSwitchSuccess)
{
//put whatever video code you are trying to play
}
else
{
//put how to handle failed instances.
}

After you import AVFoundation just put this in your delegate:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];

Related

react-native-video mutes the microphone

When a video is played during a webRTC call it causes the local stream to go mute without muting the track (audio track still has the enabled prop set to true). It does not happen when the 'muted' prop of the Video component is set to true or when the video stats playing before the call is started, but after muting or unmuting the video during the call, the microphone still disconnects. The Video component must be accessing the microphone. Do you know how to fix it? Happens on IOS 14, Xcode 12.2
I fixed it thanks to this post. It was a problem with AVAudioSession in ios/Video/RTCVideo.m. It turns out that the default settings in AVFoundation allow for the use of either Microphone or the Speaker (one at a time), so mounting Video component, or performing any actions that establish AVAudioSession interferes with other components using the microphone.
I changed this part of the code:
- (void)setPaused:(BOOL)paused
{
if (paused) {
[_player pause];
[_player setRate:0.0];
} else {
if([_ignoreSilentSwitch isEqualToString:#"ignore"]) {
// [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; OLD
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error:nil]; //NEW
} else if([_ignoreSilentSwitch isEqualToString:#"obey"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
}
[_player play];
[_player setRate:_rate];
}
_paused = paused;
}
This fix will work only if the ignoreSilentSwitch in Video component is set to 'ignore'

Preventing no-audio AVPlayer from pausing background audio

I understand that based on AVAudioSession category AVPlayer will pause background audio currently played by other app when starting its playback. I wonder if this is the expected behavior regardless of the type item/content being played?
I'm asking as in my case showing video with no sound. The video files contain no audio track. AVPlayer itself is also set to muted. It just a little weird to me that I still have to change to AVAudioSession category even though I do not produce audio. So I want to know if that is by design or if there is something that I miss. For example, could I set up AVPlayer with no audio session so that it knows not to worry about audio or something like that.
No. Just set the audio category to "Ambient" so that it doesn't step on any other audio:
AVAudioSession *session = [AVAudioSession sharedInstance];
if (session) {
NSError *setCategoryError = nil;
BOOL success = [session setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
if (success) {
NSError *activationError = nil;
[session setActive:YES error:&activationError];
} else {
NSLog(#"Failed to set music category to ambient. May interrupt other audio.");
}
}

Play MPMoviePlayerController audio stream in background

So I have this app where I play videos and when you exit the app I would like the user to continue to listen to the audio of the video. I use MPMoviePlayerController to play the video and it works in the app perfectly fine. I also setup AVAudioSession up before I play the video and I get no error.
NSError *audioSessionError;
NSError *activationError;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&audioSessionError];
[audioSession setActive:YES error:&activationError];
I also set in plist background modes audio. But the video with the audio both stop playing when you close the app. I've also imported the AVFoundation framework.
Simply set Application does not run in background to NO in .plsit file
You need to make couple of changes in plist file.i.e.
1) Set Required background mode to App plays audio
2) set Application does not run in background to YES.
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
Then, you need to write these much code in AppDelegate
Now, you can easily run audio while phone screen locks or goes in background.
This code worked for me, first you must to give your app permissions to keep playing music in the background (In your .plis), after that go to the wished class and implement this code, first the imports and the the method to play the music.
#import <MediaPlayer/MPNowPlayingInfoCenter.h>
#import <MediaPlayer/MPMediaItem.h>
#import <AVFoundation/AVFoundation.h>
---- o ----
-(void) playMusic{
[[AVAudioSession sharedInstance] setDelegate: self];
NSError *myErr;
// Initialize the AVAudioSession here.
if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&myErr]) {
// Handle the error here.
NSLog(#"Audio Session error %#, %#", myErr, [myErr userInfo]);
}else{
// Since there were no errors initializing the session, we'll allow begin receiving remote control events
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}
//initialize our audio player
audioPlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:#"http://www.cocoanetics.com/files/Cocoanetics_031.mp3"]];
[audioPlayer setShouldAutoplay:NO];
[audioPlayer setControlStyle: MPMovieControlStyleEmbedded];
audioPlayer.view.hidden = YES;
[audioPlayer prepareToPlay];
[audioPlayer play];
}//end playmusic
You need to turn on Background Modes in capabilities.

iOS - Unable to play a sound in background

I'm currently trying to implement a system like the alarm one to alert the phone when an event occurred (in my case a bluetooth event). I want this alert to occur even if the phone is in silent and in background.
I create a local notification but i can't get sound played if the phone is in silent mode (which seems to be normal since we put the phone in silent).
So i tried to manage the sound by myself and i'm struggling with playing sound in background. So far i implement the "App plays audio or streams audio/video using AirPlay" key in my plist and i'm using this code.
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *error = nil;
BOOL result = [audioSession setActive:YES error:&error];
if ( ! result && error) {
NSLog(#"Error For AudioSession Activation: %#", error);
}
error = nil;
result = [audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
if ( ! result && error) {
NSLog(#"Error For AudioSession Category: %#", error);
}
if (player == nil) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"bell" ofType:#"wav"];
NSURL *url = [NSURL fileURLWithPath:path];
NSError *err = nil;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
if(err)
{
NSLog(#"Error Player == %#", err);
}
else {
NSLog(#"Play ready");
}
}
[player prepareToPlay];
[player setVolume:1.0];
if([player play])
{
NSLog(#"YAY sound");
}
else {
NSLog(#"Error sound");
}
The sound works great in foreground, even in silent mode, but i got no sound at all in background. Any ideas ?
Thanks
EDIT:
Finally i got it working with the above code. The only missing point is that i was trying to play the sound in somewhat appeared to be a different thread, when i play it right in my bluetooth event and not my function call it's working.
An app that plays audio continuously (even while the app is running in the background) can register as a background audio app by including the UIBackgroundModes key (with the value audio) in its Info.plist file. Apps that include this key must play audible content to the user while in the background.
Apple reference "Playing Background Audio"
Ensuring That Audio Continues When the Screen Locks
Found here
I'm not sure if your problem is that you have not configure correctly the audio session output. I had similar problem while playing .wav in my app. I only listened them with earphones. This method helped me:
- (void) configureAVAudioSession {
//get your app's audioSession singleton object
AVAudioSession *session = [AVAudioSession sharedInstance];
//error handling
BOOL success;
NSError* error;
//set the audioSession category.
//Needs to be Record or PlayAndRecord to use audioRouteOverride:
success = [session setCategory:AVAudioSessionCategoryPlayAndRecord
error:&error];
if (!success) NSLog(#"AVAudioSession error setting category:%#",error);
//set the audioSession override
success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
error:&error];
if (!success) NSLog(#"AVAudioSession error overrideOutputAudioPort:%#",error);
//activate the audio session
success = [session setActive:YES error:&error];
if (!success) NSLog(#"AVAudioSession error activating: %#",error);
else NSLog(#"audioSession active"); }
Try it out!
You need to make couple of changes in plist file.
for enabling sound when the app enter's Background.
1) Set Required background mode to App plays audio
2) set Application does not run in background to YES.
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
Then, you need to write these much code in AppDelegate
Now, you can easily run audio while phone screen locks or in background.
It works fine for me. :)
for more please refer to Playing Audio in background mode and Audio Session Programming Guide

How to play Video-Audio on iOS 6?

I am playing videos and audio in my iOS app using AVAudioPlayer for Audio files (.mp3 files) and MPMoviePlayerViewController for videos files (.mp4 files).
It works fine on iOS 5 and lower versions.
But in my iPad ( iOS 6) it doesn't work. It plays video with no audio. Of course it doesn't play audio at all.
Please help me to resolve this problem.
Thanks in advance ...
Since iOS 6 the mute switch will also mute apps, did you check if the mute swoth is turned off.
To force playback if the device is muted you could do the following:
NSError *error= nil;
if ([[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&error]) {
NSLog(#"Error setting audio session: %#", error);
}
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
if(setCategoryErr || activationErr)
{
NSLog(#"%# Error: Could not activate silence mode. %# %#", self, setCategoryErr, activationErr);
}

Resources