¿Cómo detectar mediante programación el auricular en el iPhone?
-
11-09-2019 - |
Pregunta
Actualmente estoy trabajando en un proyecto que implica reproducir música desde la biblioteca de música del iPhone dentro de la aplicación interna.Estoy usando MPMediaPickerController para permitir al usuario seleccionar su música y reproducirla usando el reproductor de música iPod dentro del iPhone.
Sin embargo, tuve un problema cuando el usuario insertó su auricular y se lo quitó.La música dejará de reproducirse repentinamente sin ningún motivo.Después de algunas pruebas, descubrí que el reproductor iPod pausará la reproducción cuando el usuario desconecte el auricular del dispositivo.Entonces, ¿hay alguna forma de detectar mediante programación si el auricular se ha desconectado para poder continuar reproduciendo la música?¿O hay alguna forma de evitar que el reproductor iPod se detenga cuando el usuario desconecta el auricular?
Solución
Debe registrarse para recibir la notificación de cambios de AudioRoute e implementar cómo desea manejar los cambios de ruta.
// 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..
}
Otros consejos
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);
}
Cheers, Raffaello Colasante
veo que está utilizando el Marco MPMediaPlayer sin embargo el manejo del micrófono se hace utilizando el marco AVAudioPlayer, que tendrá que añadir a su proyecto.
sitio web de Apple tiene el código del marco AVAudioPlayer que utilizo para manejar las interrupciones de un usuario conectando o desconectando los auriculares micrófono de Apple.
Salida de Apple iPhone Dev Center Sesión Audio Guía de Programación .
- (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];
}
}
Hola chicos acaba de comprobar aplicación de ejemplo AddMusic. Va a resolver todos sus problemas relacionados con el iPod
En primer lugar registrarse reproductor iPod para la 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];
}
}