2009-12-02 14 views
16

Actualmente estoy trabajando en un proyecto que implica reproducir música de la biblioteca de música iphone dentro de la aplicación. Estoy usando MPMediaPickerController para permitir al usuario seleccionar su música y reproducirla usando el reproductor de música iPod dentro del iPhone.¿Cómo detectar mediante programación el auricular en el iPhone?

Sin embargo, me encontré con el problema cuando el usuario inserta su auricular y lo quita. La música de repente dejará de reproducirse sin ningún motivo. Después de algunas pruebas, descubrí que el reproductor iPod detendrá la reproducción cuando el usuario desenchufe su auricular del dispositivo. Entonces, ¿hay alguna manera de detectar programáticamente si el auricular se ha desconectado para que pueda reanudar la reproducción de la música? ¿O hay alguna forma de evitar que el iPod se detenga cuando el usuario desconecta el auricular?

Respuesta

9

deberá registrarse en AudioRoute cambió la notificación e implementar cómo desea manejar la derrota cambia

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

y dentro de la devolución de llamada, puede obtener el motivo del cambio de ruta

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 estoy teniendo 2 error al compilar 1) wat's inPropertyValue? No se decolora tampoco en el parámetro de método 2) CFDictionaryGetValue devuelve un puntero void que es incompitable con CFNumberRef. ¿Debo hacer un casting antes de devolver el valor? –

+0

hmm logré compilar mis códigos y todo funciona bien, pero cuando enchufo o desconecto mis auriculares no pasa nada. La función audioRouteChangeListenerCallback no se ha llamado. ¿Hay algo más que me falta junto a las funciones anteriores? –

+0

Debe registrarse para la función de escucha DESPUÉS de su llamada a la inicialización de AudioSession .. ¿Lo hace de esa manera? – prakash

2

Veo que está usando MPMediaPlayer Framework, sin embargo, el manejo del micrófono se realiza utilizando el marco AVAudioPlayer, que deberá agregar a su proyecto.

El sitio web de Apple tiene un código del marco de AVAudioPlayer que utilizo para manejar las interrupciones de un usuario que conecta o quita los auriculares del micrófono de Apple.

Echa un vistazo a iPhone Dev Center Audio Session Programming Guide de 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]; 
    } 
} 

Mi código es un poco diferente y algunos de esto puede ayudarle a:

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 lo que desea es comprobar si los auriculares están conectados en un momento dado, sin escuchar a los cambios de ruta, sólo tiene que hacer lo siguiente:

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); 
} 

Saludos, Raffaello COLASANTE

+1

Una implementación mucho mejor de esto se puede encontrar aquí: http://stackoverflow.com/questions/3728781/detect-if-headphones-not-microphone-are-plugged- en-a-un-ios-dispositivo –

2

Hey chicos solo verifican la aplicación de ejemplo AddMusic. Va a resolver todos sus problemas relacionados con el iPod

Primera registrar el iPod reproductor de notificación con el siguiente código

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 

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

    [musicPlayer beginGeneratingPlaybackNotifications]; 

y poner en práctica el siguiente código en la notificación

- (void) handle_PlaybackStateChanged: (id) notification 
{ 

    MPMusicPlaybackState playbackState = [musicPlayer playbackState]; 

    if (playbackState == MPMusicPlaybackStatePaused) 
    { 
      [self playiPodMusic]; 
    } 
    else if (playbackState == MPMusicPlaybackStatePlaying) 
    { 

    } 
    else if (playbackState == MPMusicPlaybackStateStopped) 
    { 
     [musicPlayer stop]; 
    } 
} 
Cuestiones relacionadas