iPhone: first song not pause before start next song - iphone

In My app Song play through buffering,
I have two music player in my app,
But it plays both musicplayer songs together. It does not pause the first song even when I try to pause.
i refer this tutorial:
http://cocoawithlove.com/2008/09/streaming-and-playing-live-mp3-stream.html
for that i try to call
[streamer pause];
- (void)pause
{
#synchronized(self)
{
if (state == AS_PLAYING)
{
err = AudioQueuePause(audioQueue);
if (err)
{
[self failWithErrorCode:AS_AUDIO_QUEUE_PAUSE_FAILED];
return;
}
self.state = AS_PAUSED;
}
else if (state == AS_PAUSED)
{
err = AudioQueueStart(audioQueue, NULL);
if (err)
{
[self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
return;
}
self.state = AS_PLAYING;
}
}
}
streamer calls the pause method of buffering.
How can i do that?

if (audioPlayer.playing==YES) {
[audioPlayer pause];
}
try this.

Related

how to stop audio when iOS Sleep Timer gets called

I want to stop my audio app when iOS sleep timer gets called.
Just like Pandora app.
http://help.pandora.com/customer/portal/articles/24324-ios-sleep-timer-with-pandora
Tap the Clock app, Tap Timer, Select a time, Tap When Timer Ends, Tap Stop
Playing
This will sleep your Pandora app if it is running.
I can see inInterruptionState == kAudioSessionBeginInterruption gets called when iOS sleep timer ends, but how can I detect if it's sleep timer or just interruptions like phone call?
Here is my codes.
Currently, my app just starts playing again after iOS sleep timer ends.
// Audio Interruption Listener
void MyInterruptionListener(void *inClientData, UInt32 inInterruptionState) {
if (inInterruptionState == kAudioSessionBeginInterruption) {
[[DOSpeechManager sharedInstance] audioSessionBeginInterruption];
}
if (inInterruptionState == kAudioSessionEndInterruption) {
[[DOSpeechManager sharedInstance] audioSessionEndInterruption];
}
}
- (void)audioSessionBeginInterruption {
if ([_MyAcaTTS isSpeaking] && [_MyAcaTTS isPaused] == NO) {
[_MyAcaTTS pauseSpeakingAtBoundary:AcapelaSpeechImmediateBoundary];
[self setAudioSettionStatus:NO];
_audioInterruptedWhileSpeaking = YES;
}
}
- (void)audioSessionEndInterruption {
if (_audioInterruptedWhileSpeaking) {
[self setAudioSettionStatus:YES];
[_MyAcaTTS continueSpeaking];
}
}
- (void)setAudioSettionStatus:(BOOL)status {
AudioSessionSetActive(status);
[_MyAcaTTS setActive:status];
//cancel audio interrupted flag
if (status) {
_audioInterruptedWhileSpeaking = NO;
}
}
The trick is not to detect the source of the interruption, but to know whether your app should resume after the interruption.
The AVAudioSession API will send a notification when the audio session is interrupted. Within this notification, the OS gives a "hint" as to whether the app should resume playback or not.
See below:
//Add notification observer
__weak typeof(self) weakSelf = self;
self.audioSessionInterruptionNotification =
[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionInterruptionNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
NSNumber* interruptionType = note.userInfo[AVAudioSessionInterruptionTypeKey];
NSNumber* interruptionOption = note.userInfo[AVAudioSessionInterruptionOptionKey];
BOOL shouldResume = interruptionOption.integerValue == AVAudioSessionInterruptionOptionShouldResume;
switch (interruptionType.integerValue) {
case AVAudioSessionInterruptionTypeBegan:
[weakSelf beginInterruption];
break;
case AVAudioSessionInterruptionTypeEnded:
[weakSelf endInterruption:shouldResume];
break;
default:
break;
}
}];
}

How to check live streaming url response iphone

In my app I am doing live streaming with the following code :
-(void)playurl:(id)sender
{
self.mpPlayer=[[[MPMoviePlayerController alloc]initWithContentURL:[NSURL URLWithString:#"http://alwatan.lsops.net/live/alwradio_ar_audio.sdp/playlist.m3u8"]] autorelease];
[self.mpPlayer prepareToPlay];
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.mpPlayer.view.frame = CGRectMake(0, 50, 768, 400);
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
self.mpPlayer.view.frame = CGRectMake(0, 0, 1024, 500);
}
[self.mpPlayer play];
self.mpPlayer.movieSourceType = MPMovieSourceTypeStreaming;
//self.mpPlayer.movieSourceType = MPMovieSourceTypeFile;
self.mpPlayer.shouldAutoplay = TRUE;
self.mpPlayer.controlStyle = MPMovieControlStyleDefault;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:mpPlayer];
[scrollView addSubview:self.mpPlayer.view];
if(isVideoPlay)
{
isVideoPlay = FALSE;
}
else
{
isVideoPlay = TRUE;
}
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification
{
NSError *error = [[notification userInfo] objectForKey:#"error"];
if (error) {
}
else
{
MPMoviePlayerController *moviePlayer = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
}
}
Everything is fine but my problem is that is url is not runing then application will be crashed so how can I check the live streaming url response so I can mange the condition and give alert for url not respond.
Thanks,
Use the following notification
MPMoviePlayerPlaybackStateDidChangeNotification
and check for
 if(moviePlayer.state == MPMoviePlaybackStateStopped)
{
// Alert
}
else  if(moviePlayer.state == MPMoviePlaybackStatePlaying)
{
// Alert
}
else  if(moviePlayer.state == MPMoviePlaybackStatePaused)
{
// Alert
}
else  if(moviePlayer.state == MPMoviePlaybackStateInterrupted)
{
// Alert
}
else  if(moviePlayer.state == MPMoviePlaybackStateSeekingForward)
{
// Alert
}
else  if(moviePlayer.state == MPMoviePlaybackStateSeekingBackward)
{
// Alert
}
My experience with MPMoviePlayerControler has been that it's not very good with error handling. One possibility would be to request the URL first, then only load the .m3u8 file when your stream is running.
You could use NSURLConnection and friends to try and load the stream, and, if necessary, read the file looking for something specific that indicates the stream is running (perhaps the presence of a line containing #EXTINF:.

How to implement mute functionality in a PJSIP call on iOS

I wanted to implement Mute button in my call. I am working on a VOIP application for iPhone. Now when a call comes and user picks up, I want to display a Mute button so the user can mute the call or conference. I did the same through the PJSIP API.
-(int) mutethecall
{
pj_status_t status = pjsua_conf_adjust_rx_level (0,0);
status = pjsua_conf_adjust_tx_level (0,0);
return (PJ_SUCCESS == status);
}
-(int) unmutethecall
{
pj_status_t status = pjsua_conf_adjust_rx_level (0,1);
status = pjsua_conf_adjust_tx_level (0,1);
return (PJ_SUCCESS == status);
}
The problem is that while this code is working for one to one call, it's not working for conference scenarios.
I wonder if I could turn off the mic directly: could I implement the same using iOS bypassing the PJSIP API?
Is this possible?
You can completely disconnect the microphone from the conference using pjsua_conf_disconnect and pjsua_conf_connect when you want to unmute.
Here's some Objective-C code that does the trick:
+(void)muteMicrophone
{
#try {
if( pjsipConfAudioId != 0 ) {
NSLog(#"WC_SIPServer microphone disconnected from call");
pjsua_conf_disconnect(0, pjsipConfAudioId);
}
}
#catch (NSException *exception) {
NSLog(#"Unable to mute microphone: %#", exception);
}
}
+(void)unmuteMicrophone
{
#try {
if( pjsipConfAudioId != 0 ) {
NSLog(#"WC_SIPServer microphone reconnected to call");
pjsua_conf_connect(0,pjsipConfAudioId);
}
}
#catch (NSException *exception) {
NSLog(#"Unable to un-mute microphone: %#", exception);
}
}
Note that the pjsipConfAudioID was retrieved when the call was established, again in Objective-C...
static void on_call_state(pjsua_call_id call_id, pjsip_event *e)
{
pjsua_call_info ci;
PJ_UNUSED_ARG(e);
pjsua_call_get_info(call_id, &ci);
pjsipConfAudioId = ci.conf_slot;
...
}
Hope that helps!

MPMoviePlayerController play error on iPad

I'm writing an app that will be playing videos alot using the MPMoviePlayerController on the iPad. The problem is the app was working fine and playing the videos when I stopped working about 15 hours ago but now the videos do not play. The MPMoviePlayerController will show the first frame from the video, and in full screen view I can scrub through the movie fine but when I hit play it just pauses right away. I have the code below, when debugging i noticed that when I call play it sends an MPMoviePlayerPlaybackStateDidChangeNotification with the playbackState being MPMoviePlaybackStatePlaying and then right away it sends another MPMoviePlayerPlaybackStateDidChangeNotification notification with playbackState being MPMoviePlaybackStatePaused. Not sure if that helps but please let me know if you see anything wrong in my code or have an ideas, thanks.
- (void)handleNotification:(NSNotification *)notification {
if ([[notification name] isEqualToString:MPMoviePlayerPlaybackStateDidChangeNotification]) {
if (_videoPlayer.playbackState == MPMoviePlaybackStatePlaying) {
_playButtonLarge.hidden = YES;
_scrubber.maximumValue = _videoPlayer.duration;
[_playPauseButton setBackgroundImage:[UIImage imageNamed:#"video_controls_pause.png"] forState:UIControlStateNormal];
if (_updateScrubberTimer == nil) {
_updateScrubberTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(updateScrubber) userInfo:nil repeats:YES];
}
} else if (_videoPlayer.playbackState == MPMoviePlaybackStatePaused || _videoPlayer.playbackState == MPMoviePlaybackStateStopped) {
[_playPauseButton setBackgroundImage:[UIImage imageNamed:#"video_controls_play.png"] forState:UIControlStateNormal];
_playButtonLarge.hidden = NO;
if (_updateScrubberTimer != nil) {
[_updateScrubberTimer invalidate];
_updateScrubberTimer = nil;
}
if (_videoPlayer.playbackState == MPMoviePlaybackStateStopped) {
_scrubber.value = 0.0f;
_timePlayedLabel.text = #"0:00";
_timeRemainingLabel.text = #"-0:00";
_videoPlayerBG.hidden = NO;
}
}
} else if ([[notification name] isEqualToString:MPMoviePlayerPlaybackDidFinishNotification]) {
NSNumber *reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
if ([reason intValue] == MPMovieFinishReasonPlaybackEnded) {
_videoPlayerBG.hidden = NO;
}
_scrubber.value = _scrubber.maximumValue;
}
}
- (void)playPause {
if ([_videos count] > 0) {
if (_videoPlayer.playbackState == MPMoviePlaybackStatePaused || _videoPlayer.playbackState == MPMoviePlaybackStateStopped) {
_playButtonLarge.hidden = YES;
_videoPlayerBG.hidden = YES;
if ([_videoPlayer contentURL] == nil) {
Video *video = [_videos objectAtIndex:0];
[_videoPlayer setContentURL:video.videoURL];
}
if (![_videoPlayer isPreparedToPlay]) {
[_videoPlayer prepareToPlay];
}
[_videoPlayer play];
} else if (_videoPlayer.playbackState == MPMoviePlaybackStatePlaying) {
_playButtonLarge.hidden = NO;
[_videoPlayer pause];
}
}
}
I think I figured it out, I put the following code before every call to play
if (![_videoPlayer isPreparedToPlay]) {
[_videoPlayer prepareToPlay];
}
works now, if anyone else has any input let me know

How to programmatically detect earpiece in iphone?

I'm currently working on a project that involves playing music from the iphone music library within the app inside. I'm using MPMediaPickerController to allow the user to select their music and play it using the iPod music player within the iPhone.
However, i ran into problem when the user insert his earpiece and removes it. The music will suddenly stop playing for no reason. After some testing, i found out that the iPod player will pause playing when the user unplug his earpiece from the device. So is there any way to programatically detect if the earpiece has been unplug so that i can resume playing the music? Or is there any way to prevent iPod player from pausing when the user unplug his earpiece?
You should register for AudioRoute changed notification and implement how you want to handle the rout changes
// Registers the audio route change listener callback function
AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange,
audioRouteChangeListenerCallback,
self);
and within the callback, you can get the reason for route change
CFDictionaryRef routeChangeDictionary = inPropertyValue;
CFNumberRef routeChangeReasonRef =
CFDictionaryGetValue (routeChangeDictionary,
CFSTR (kAudioSession_AudioRouteChangeKey_Reason));
SInt32 routeChangeReason;
CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);
if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable)
{
// Headset is unplugged..
}
if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable)
{
// Headset is plugged in..
}
If you just want to check whether headphones are plugged in at any given time, without listening to route changes, you can simply do the following:
OSStatus error = AudioSessionInitialize(NULL, NULL, NULL, NULL);
if (error)
NSLog("Error %d while initializing session", error);
UInt32 routeSize = sizeof (CFStringRef);
CFStringRef route;
error = AudioSessionGetProperty (kAudioSessionProperty_AudioRoute,
&routeSize,
&route);
if (error)
NSLog("Error %d while retrieving audio property", error);
else if (route == NULL) {
NSLog(#"Silent switch is currently on");
} else if([route isEqual:#"Headset"]) {
NSLog(#"Using headphones");
} else {
NSLog(#"Using %#", route);
}
Cheers,
Raffaello Colasante
I see you are using the MPMediaPlayer Framework however the microphone handling is done using the AVAudioPlayer framework, which you will need to add to your project.
Apple's website has code from the AVAudioPlayer framework which I use to handle interruptions from a user plugging in or removing the Apple microphone headphones.
Check out Apple's iPhone Dev Center Audio Session Programming Guide.
- (void) beginInterruption {
if (playing) {
playing = NO;
interruptedWhilePlaying = YES;
[self updateUserInterface];
}
}
NSError *activationError = nil;
- (void) endInterruption {
if (interruptedWhilePlaying) {
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
[player play];
playing = YES;
interruptedWhilePlaying = NO;
[self updateUserInterface];
}
}
My code is a little different and some of this may help you:
void interruptionListenerCallback (
void *inUserData,
UInt32 interruptionState
) {
// This callback, being outside the implementation block, needs a reference
// to the AudioViewController object
RecordingListViewController *controller = (RecordingListViewController *) inUserData;
if (interruptionState == kAudioSessionBeginInterruption) {
//NSLog (#"Interrupted. Stopping playback or recording.");
if (controller.audioRecorder) {
// if currently recording, stop
[controller recordOrStop: (id) controller];
} else if (controller.audioPlayer) {
// if currently playing, pause
[controller pausePlayback];
controller.interruptedOnPlayback = YES;
}
} else if ((interruptionState == kAudioSessionEndInterruption) && controller.interruptedOnPlayback) {
// if the interruption was removed, and the app had been playing, resume playback
[controller resumePlayback];
controller.interruptedOnPlayback = NO;
}
}
void recordingListViewMicrophoneListener (
void *inUserData,
AudioSessionPropertyID inPropertyID,
UInt32 inPropertyValueSize,
const void *isMicConnected
) {
// ensure that this callback was invoked for a change to microphone connection
if (inPropertyID != kAudioSessionProperty_AudioInputAvailable) {
return;
}
RecordingListViewController *controller = (RecordingListViewController *) inUserData;
// kAudioSessionProperty_AudioInputAvailable is a UInt32 (see Apple Audio Session Services Reference documentation)
// to read isMicConnected, convert the const void pointer to a UInt32 pointer
// then dereference the memory address contained in that pointer
UInt32 connected = * (UInt32 *) isMicConnected;
if (connected){
[controller setMicrophoneConnected : YES];
}
else{
[controller setMicrophoneConnected: NO];
}
// check to see if microphone disconnected while recording
// cancel the recording if it was
if(controller.isRecording && !connected){
[controller cancelDueToMicrophoneError];
}
}
Hey guys just check AddMusic sample app. Will solve all your iPod related issues
First register iPod player for notification with following code
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter
addObserver: self
selector: #selector (handle_PlaybackStateChanged:)
name: MPMusicPlayerControllerPlaybackStateDidChangeNotification
object: musicPlayer];
[musicPlayer beginGeneratingPlaybackNotifications];
And implement the following code in the notification
- (void) handle_PlaybackStateChanged: (id) notification
{
MPMusicPlaybackState playbackState = [musicPlayer playbackState];
if (playbackState == MPMusicPlaybackStatePaused)
{
[self playiPodMusic];
}
else if (playbackState == MPMusicPlaybackStatePlaying)
{
}
else if (playbackState == MPMusicPlaybackStateStopped)
{
[musicPlayer stop];
}
}