Detectar AVAudioSessions activas en dispositivos iOS
objective-c cocoa-touch (2)
La forma en que administra la sesión de audio de su aplicación ha tenido algunos cambios significativos desde iOS 6.0 , y merece una breve mención primero. Antes de iOS 6.0 , haría uso de las clases AVAudioSession y AudioSessionServices , incorporando la delegación y la escucha de propiedad respectivamente. Desde iOS 6.0 en adelante, use la clase AVAudioSession e incorpore notificaciones.
Lo siguiente es para iOS 6.0 en adelante.
Para saber si se está reproduciendo otro tipo de audio fuera de sus aplicaciones.
// query if other audio is playing
BOOL isPlayingWithOthers = [[AVAudioSession sharedInstance] isOtherAudioPlaying];
// test it with...
(isPlayingWithOthers) ? NSLog(@"other audio is playing") : NSLog(@"no other audio is playing");
En cuanto al manejo de interrupciones, deberá observar AVAudioSessionInterruptionNotification
y AVAudioSessionRouteChangeNotification
. Por lo tanto, en la clase que administra su sesión de audio, puede poner algo como lo siguiente: esto debe llamarse una vez al inicio del ciclo de vida de la aplicación y no olvide eliminar el observador en el método dealloc de la misma clase.
// ensure we already have a singleton object
[AVAudioSession sharedInstance];
// register for notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(interruption:)
name:AVAudioSessionInterruptionNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(routeChange:)
name:AVAudioSessionRouteChangeNotification
object:nil];
Y finalmente agregue la siguiente interruption:
selectores interruption:
y routeChange:
estos recibirán un objeto NSNotification
que tiene una propiedad llamada userInfo del tipo NSDictionary
que usted lee para ayudar a cualquier condicional que tenga su aplicación.
- (void)interruption:(NSNotification*)notification {
// get the user info dictionary
NSDictionary *interuptionDict = notification.userInfo;
// get the AVAudioSessionInterruptionTypeKey enum from the dictionary
NSInteger interuptionType = [[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey] integerValue];
// decide what to do based on interruption type here...
switch (interuptionType) {
case AVAudioSessionInterruptionTypeBegan:
NSLog(@"Audio Session Interruption case started.");
// fork to handling method here...
// EG:[self handleInterruptionStarted];
break;
case AVAudioSessionInterruptionTypeEnded:
NSLog(@"Audio Session Interruption case ended.");
// fork to handling method here...
// EG:[self handleInterruptionEnded];
break;
default:
NSLog(@"Audio Session Interruption Notification case default.");
break;
} }
Y de manera similar ...
- (void)routeChange:(NSNotification*)notification {
NSDictionary *interuptionDict = notification.userInfo;
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
switch (routeChangeReason) {
case AVAudioSessionRouteChangeReasonUnknown:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonUnknown");
break;
case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
// a headset was added or removed
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonNewDeviceAvailable");
break;
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
// a headset was added or removed
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
break;
case AVAudioSessionRouteChangeReasonCategoryChange:
// called at start - also when other audio wants to play
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonCategoryChange");//AVAudioSessionRouteChangeReasonCategoryChange
break;
case AVAudioSessionRouteChangeReasonOverride:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonOverride");
break;
case AVAudioSessionRouteChangeReasonWakeFromSleep:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonWakeFromSleep");
break;
case AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory:
NSLog(@"routeChangeReason : AVAudioSessionRouteChangeReasonNoSuitableRouteForCategory");
break;
default:
break;
} }
No hay necesidad de sondear nada, siempre y cuando verifique el estado de la sesión de audio de sus aplicaciones, por ejemplo, en viewDidLoad
de su controlador de vista de raíz, al comienzo del ciclo de vida de sus aplicaciones. Cualquier cambio a partir de ahí en la sesión de audio de sus aplicaciones se conocerá a través de estas dos notificaciones principales. Reemplace las declaraciones de NSLog
con lo que su código deba hacer en función de los casos contenidos en el conmutador.
Puede encontrar más información sobre AVAudioSessionInterruptionTypeKey
y AVAudioSessionRouteChangeReasonKey
en la documentación de referencia de la clase AVAudioSession
.
Mis disculpas por la respuesta larga, pero creo que la administración de la sesión de audio en iOS es bastante complicada y, al momento de escribir esto, la Guía de programación de la sesión de audio de Apple no incluye ejemplos de código que usen notificaciones para el manejo de interrupciones.
Estoy intentando averiguar si esto es posible: mi aplicación activa una sesión de audio que se inicializa como:
[[[AVAudioSession alloc] init] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
Me gustaría poder entender cuándo se está reproduciendo una sesión de audio adicional que se originó desde otra aplicación o desde el sistema operativo.
Conozco la capacidad para implementar los métodos delegados beginInterruption:
y endInterruption
pero estos no se invocarán debido a la opción AVAudioSessionCategoryOptionMixWithOthers
que estoy usando.
¿Hay una manera de lograr esto sin usar la API privada?
Gracias por adelantado.
Puedes verificar si otro audio se está reproduciendo así:
UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof (otherAudioIsPlaying);
AudioSessionGetProperty (kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &otherAudioIsPlaying );
[self handleIfAudioIsPlaying: otherAudioIsPlaying];
Luego puede agregar un bucle y verificar cada X segundos si algo cambió.