i'm developing an app which requires to play a video from an URL using MPMoviePlayerController while acquiring audio samples using AudioQueue from the microphone to further analyze them.
The problem is that I cannot record when the video starts playing (and also when it finishes). Simply the audio sampling stops. Instead, if I disable the video play, audio recording goes well.
I've tried setting up an AudioSession with property kAudioSessionProperty_OverrideCategoryMixWithOthers but with no success (it returns error). Moreover I think that it's useless setting a property in AudioSession when using AudioQueue. Even setting useApplicationAudioSession = NO for MPMoviePlayerController does not give any help.
Hereby the core code where the player is created:
audioManager = [[AudioController alloc] init];
//setting AudioQueue: audio buffer, sample rate, format ID (PCM), bits per channel
audioManager.delegate = self;
[audioManager startAudioRecording]; //starts recording with AudioQueue
self.playerVC = [[[MPMoviePlayerController alloc] init] autorelease];
layerVC.view.frame = self.viewPlayer.bounds;
[self.viewPlayer addSubview:playerVC.view];
playerVC.useApplicationAudioSession = YES; //if NO nothing changes
[playerVC setContentURL:[NSURL URLWithString:#"http://www......."]];
[playerVC prepareToPlay];
[playerVC play];
You're on the right way.
First, set the kAudioSessionProperty_OverrideCategoryMixWithOther to true. This will allow your app's sound mixes with sounds from another apps.
UInt32 allowMixing = true;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
After that, you will need to set MPMoviePlayerController to not use your app's AudioSession:
[yourMPMoviePlayerControllerInstance setUseApplicationAudioSession:NO];
Related
I'm developing an iPhone app that can play online videos and
I want to play an ad first when the video data is loading.
First, I request an AdColony video Ad and begin to play it, then use MPMoviePlayerController to load video data, But when the video is prepared to play, it interrupts the previous Ad sound, and causes the ad to stop.
Here are the codes Im using:
// Play Ad first
[AdColony playVideoAdForSlot:1 withDelegate:self]; // It also use MPMoviePlayerController to play video
// Load video for playing
moviePlayer = [[MPMoviePlayerController alloc]
init];
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.shouldAutoplay = NO;
moviePlayer.view.frame = CGRectMake(0,44,320,320);
moviePlayer.view.userInteractionEnabled = YES;
[moviePlayer prepareToPlay]; // Interrupt Ad playing
The offical doc said "calling prepareToPlay may interrupt the movie player’s audio session", so the Ad was interrupted. If I remove prepareToPlay, the video data will not be preloaded
I have tried to put
[AdColony playVideoAdForSlot:1 withDelegate:self]; below [moviePlayer prepareToPlay];
but it does not work. Does anyone know how to resolve it?
There are ways to handle interruptions,
read through he Apples guide
http://developer.apple.com/library/ios/#documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html#//apple_ref/doc/uid/TP40007875-CH11-SW1
My app plays video file without sound. And it interrupts any playing music in backgroud (iPod app for example). How do not interrupt audio session of other apps if it's possible.
My video file is without sound. To play video i use MPMoviePlayerController.
EDIT: Here is my video player code:
_player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:path]];
[self installMovieNotificationObservers:nil];
[_player setShouldAutoplay:YES];
[_player setUseApplicationAudioSession:NO];
[_player.view setFrame:self.navController.view.frame];
[_player setMovieSourceType:MPMovieSourceTypeFile];
[_player setRepeatMode:MPMovieRepeatModeNone];
[_player setFullscreen:YES animated:YES];
[_player setControlStyle:MPMovieControlStyleNone];
[_navController.view addSubview:_player.view];
[_player play];
Directly from Apple's docs:
http://developer.apple.com/library/ios/documentation/mediaplayer/reference/MPMoviePlayerController_Class/Reference/Reference.html#//apple_ref/occ/instp/MPMoviePlayerController/useApplicationAudioSession
useApplicationAudioSession
A Boolean value that indicates whether the
movie player should use the app’s audio session.
#property (nonatomic) BOOL useApplicationAudioSession Discussion The
default value of this property is YES. Setting this property to NO
causes the movie player to use a system-supplied audio session with a
nonmixable playback category.
Important In iOS 3.1 and earlier, a movie player always uses a
system-supplied audio session. To obtain that same behavior in iOS 3.2
and newer, you must set this property’s value to NO. When this
property is YES, the movie player shares the app’s audio session. This
give you control over how the movie player content interacts with your
audio and with audio from other apps, such as the iPod. For important
guidance on using this feature, see “Working with Movies and iPod
Music” in Audio Session Programming Guide.
Changing the value of this property does not affect the currently
playing movie. For the new setting to take effect, you must stop
playback and then start it again.
Availability Available in iOS 3.2 and later. Declared In
MPMoviePlayerController.h
Swift 5 answer
do {
if #available(iOS 10.0, *) {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: .mixWithOthers)
} else {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, options: .mixWithOthers)
}
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
I am using the following code to play a audio in iOS using **AVAudioPlayer** class.
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"myAudio" ofType:#"mp3"];
NSURL *audioURL = [[NSURL alloc] initFileURLWithPath:audioPath];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer play];
This is working fine in simulator. But, i am not getting the sound output when i run it on the device. The delegate methods ofAVAudioPlayerDelegate are also being called but there is no volume output. Where am i going wrong here.... Another important aspect i'v noticed here is that, i am getting a large message in my GDB while playing the audio file on simulator. But the same thing is not happening on device... Please refer the screenshot below for GDB messages while running on the simulator.
Check if your device is on loudspeaker mode or not..
to listen the sound through Loundspeaker use this -
// set audio to loudSpeaker mode for iphone
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
or you can increase the volume of your audio file using this -
Player.volume = 10.0;
Have you tried the .caf or .wav file? might possible that .mp3 is not working on iPhone. Also check the duration of your file not greater than 30 sec.
I was so so stupid.... My volume button was turned off. That was the reason.
Really sorry for wasting your time guys... My sincere apologies.
I have a problem with MPMoviePlayerController, i.e. I am playing the live stream url in (m3u8 format) MPMoviePlayer like below:
player = [[MPMoviePlayerController alloc] initWithContentURL:audioUrl];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(loadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:player];
if ([player respondsToSelector:#selector(loadState)])
{
// Set movie player layout
[player setMovieSourceType:MPMovieSourceTypeStreaming];
[player setControlStyle:MPMovieControlModeVolumeOnly];
[player setFullscreen:YES];
[player prepareToPlay];
[player play];
}
}
It is working in both simulators & iPad device with ios 5 version, but it is not giving the audio in any iPhone device i have.
Please help me out...
Thanks, in advance.
mr simham ... check this below url it help for us becoZ
Call stream-url within mobile safari. If that has the same results, then your code is correct and the stream is not. It would be an incorrectly encoded audio stream then.
it depends on bandwidth also below ref url regards to bandwidth check it once.... u r ref Stream URL prepare,according to BandWith
REFERENCE URL:
http://wfmu.org/ssaudionet.shtml
APPLE
You are assigning a deprecated MPMovieControlMode (MPMovieControlModeVolumeOnly) towards the controlStyle property which is expecting a MPMovieControlStyle.
Additionally, your code is missing the part that assigns the MPMoviePlayerController.view towards any superview and also its sizing is missing.
Last but I guess most importantly for you, I am guessing that the iPhone you are trying it with has set the volume all the way down to silence. Or, maybe the audio-routing is not set towards speaker-output. For the latter, make sure you are not setting up the audio session incorrectly anywhere else in your App. When in doubt, try fiddling with the useApplicationAudioSession property. Try setting it towards NO and see if that changes your results.
If all above fails, then one additional check would be to call the stream-url within mobile safari. If that has the same results, then your code is correct and the stream is not. It would be an incorrectly encoded audio stream then.
Check if your iPhone is on loudspeaker mode or not -
if not than set it using this-
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
Check if the iPhone is in silent mode. To play audio even in silent mode, add the following code in AppDelegate's application:didFinishLaunchingWithOptions:
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
I've got an iPhone app with a short intro video. If a user launches the app while their iPod is playing music, the music will stop while the video plays (whether or not the video has sound), and the audio stays permanently stopped after video playback.
Apple seems to indicate that you can solve this with AudioSession tricks:
https://web.archive.org/web/20100819124854/http://developer.apple.com:80/iPhone/library/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/WorkingWithOpenALiPodMusicandMovies/WorkingWithOpenALiPodMusicandMovies.html
But their suggestions here just don't seem to work; it seems like MPMoviePlayerController overrides the audio session configuration for its own purposes. Ideally I'd mix the movie audio over the iPod audio or maybe use ducking, but even restarting the music might be a passable fix.
I've found a great solution for that. In the .h file, you must create a BOOL called "wasPlaying". Before playing your video, you ask the iPod if it was playing.
if ([[MPMusicPlayerController iPodMusicPlayer] playbackState] == MPMusicPlaybackStatePlaying)
{
NSLog(#"Music was playing, lets put YES to the bool");
wasPlaying = YES;
}
Then, after you tell the movie player to play, you call the following:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(finishedPlaying) name:MPMoviePlayerPlaybackDidFinishNotification object: moviePlayer];
And after that, in the method finishedPlaying:
if (wasPlaying ==YES)
{
NSLog(#"Music was playing, lets play music again");
[[MPMusicPlayerController iPodMusicPlayer] play];
}
For me it worked fine!
I think you can do this by initializing the audio session similar to this:
NSError *audioSessionError = nil;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryAmbient
error:&audioSessionError] == YES)
Then when you want to use the audio session you can set the iPod audio to duck the video track:
AudioSessionInitialize (NULL, NULL, NULL, NULL);
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError |= AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);
AudioSessionSetActive(YES);
You can only have a single music-providing app at any time and multiple sources of (brief) sounds. If a background app is playing music, your app can overlay brief sounds. If you want to play music, the background app has to be stopped.
So I don't think that what you're trying to achieve is possible using MPMoviePlayerController (or any of the high-level audio frameworks). You might be able to overlay an audio track of a movie, if it's sufficiently short but MPMoviePlayerController is probably not good for this.