2009-12-02 5 views
16

Je travaille actuellement sur un projet qui consiste à jouer de la musique à partir de la bibliothèque de musique iphone dans l'application à l'intérieur. J'utilise MPMediaPickerController pour permettre à l'utilisateur de sélectionner sa musique et de la lire en utilisant le lecteur de musique iPod de l'iPhone.Comment détecter par programme l'écouteur dans l'iphone?

Cependant, j'ai rencontré un problème lorsque l'utilisateur a inséré son écouteur et l'a retiré. La musique s'arrêtera soudainement de jouer sans raison. Après quelques tests, j'ai découvert que le lecteur iPod fait une pause de lecture lorsque l'utilisateur débranche son écouteur de l'appareil. Donc, y a-t-il un moyen de détecter par programme si l'écouteur a été débranché afin que je puisse reprendre la lecture de la musique? Ou est-il possible d'empêcher le lecteur iPod de s'arrêter lorsque l'utilisateur débranche son écouteur?

Répondre

9

Vous devez vous inscrire pour la notification a changé AudioRoute et mettre en œuvre la façon dont vous voulez gérer la débandade change

// Registers the audio route change listener callback function 
    AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, 
            audioRouteChangeListenerCallback, 
            self); 

et dans le rappel, vous pouvez obtenir la raison du changement de route

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..     
    } 
+0

erm je vais avoir 2 erreur lors de la compilation 1) wat's inPropertyValue? Il n'apparaît pas non plus dans le paramètre de méthode 2) CFDictionaryGetValue renvoie un pointeur vide qui est incompatible avec CFNumberRef. Ai-je besoin de faire un casting avant de retourner la valeur? –

+0

hmm j'ai réussi à compiler mes codes et tout fonctionne bien mais quand je branche ou débranche mon casque rien ne se passe. La fonction audioRouteChangeListenerCallback n'a pas été appelée. Y a-t-il autre chose qui me manque à côté des fonctions ci-dessus? –

+0

Vous devez vous inscrire à la fonction d'écoute APRÈS votre appel à l'initialisation d'AudioSession. Faites-vous cela? – prakash

2

Je vois que vous utilisez MPMediaPlayer Framework mais la gestion du microphone est faite en utilisant le framework AVAudioPlayer, que vous devrez ajouter à votre projet.

Le site Web d'Apple contient le code de l'infrastructure AVAudioPlayer que j'utilise pour gérer les interruptions d'un utilisateur qui branche ou enlève les écouteurs de microphone Apple.

Consultez le iPhone Dev Center Audio Session Programming Guide d'Apple.

- (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]; 
    } 
} 

Mon code est un peu différent et certains de cela peut vous aider:

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]; 
    } 
} 
4

Si vous voulez juste pour vérifier si le casque est branché à un moment donné, sans écouter les changements d'itinéraire, vous pouvez simplement effectuer les opérations suivantes:

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

+1

Une implémentation bien meilleure de ceci peut être trouvée ici: http://stackoverflow.com/questions/3728781/detect-if-headphones-not-microphone-are-plugged- in-to-an-ios-périphérique –

2

Hey les gars, il suffit de vérifier l'application exemple AddMusic. Résoudra tous vos problèmes liés iPod

premier registre lecteur iPod pour la notification avec le code suivant

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 

    [notificationCenter 
    addObserver: self 
    selector: @selector (handle_PlaybackStateChanged:) 
    name:  MPMusicPlayerControllerPlaybackStateDidChangeNotification 
    object:  musicPlayer]; 

    [musicPlayer beginGeneratingPlaybackNotifications]; 

et mettre en œuvre le code suivant dans la 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]; 
    } 
} 
Questions connexes