Pergunta

Eu não consigo encontrar no SDK como sentir programaticamente o botão / interruptor de silêncio sobre o iPhone. Quando meu aplicativo reproduz música de fundo, ele responde corretamente para o botão de volume sem me ter qualquer código a seguir isso, mas, quando eu uso o interruptor mudo, ele simplesmente continua jogando fora.

Como faço para testar a posição do mudo?

(NOTA:. Meu programa tem seu próprio interruptor de silêncio, mas eu gostaria o interruptor físico para substituir essa)

Foi útil?

Solução

Obrigado, JPM. Na verdade, o link que você fornecer pistas para a resposta correta (finalmente;). Para completar (porque S. O. deve ser uma fonte de respostas rápidas!) ...

// "Ambient" makes it respect the mute switch
// Must call this once to init session
if (!gAudioSessionInited)
{
    AudioSessionInterruptionListener    inInterruptionListener = NULL;
    OSStatus    error;
    if ((error = AudioSessionInitialize (NULL, NULL, inInterruptionListener, NULL)))
    {
        NSLog(@"*** Error *** error in AudioSessionInitialize: %d.", error);
    }
    else
    {
        gAudioSessionInited = YES;
    }
}

SInt32  ambient = kAudioSessionCategory_AmbientSound;
if (AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (ambient), &ambient))
{
    NSLog(@"*** Error *** could not set Session property to ambient.");
}

Outras dicas

Eu respondi uma pergunta semelhante aqui (link) . O código relevante:

 -(BOOL)silenced {
     #if TARGET_IPHONE_SIMULATOR
         // return NO in simulator. Code causes crashes for some reason.
         return NO;
     #endif

    CFStringRef state;
    UInt32 propertySize = sizeof(CFStringRef);
    AudioSessionInitialize(NULL, NULL, NULL, NULL);
    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
    if(CFStringGetLength(state) > 0)
            return NO;
    else
            return YES;

    }

Parte do código em outras respostas (incluindo a resposta aceita) pode não funcionar se você não está no modo de ambiente, onde o mudo é respeitado.

Eu escrevi a rotina abaixo para mudar para o ambiente, leia o interruptor, e depois voltar para as definições que preciso em meu aplicativo.

-(BOOL)muteSwitchEnabled {

#if TARGET_IPHONE_SIMULATOR
    // set to NO in simulator. Code causes crashes for some reason.
    return NO;
#endif

// go back to Ambient to detect the switch
AVAudioSession* sharedSession = [AVAudioSession sharedInstance];
[sharedSession setCategory:AVAudioSessionCategoryAmbient error:nil];

CFStringRef state;
UInt32 propertySize = sizeof(CFStringRef);
AudioSessionInitialize(NULL, NULL, NULL, NULL);
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);

BOOL muteSwitch = (CFStringGetLength(state) <= 0);
NSLog(@"Mute switch: %d",muteSwitch);

// code below here is just restoring my own audio state, YMMV
_hasMicrophone = [sharedSession inputIsAvailable];
NSError* setCategoryError = nil;

if (_hasMicrophone) {

    [sharedSession setCategory: AVAudioSessionCategoryPlayAndRecord error: &setCategoryError];

    // By default PlayAndRecord plays out over the internal speaker.  We want the external speakers, thanks.
    UInt32 ASRoute = kAudioSessionOverrideAudioRoute_Speaker;
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
                             sizeof (ASRoute),
                             &ASRoute
                             );
}
else
    // Devices with no mike don't support PlayAndRecord - we don't get playback, so use just playback as we don't have a microphone anyway
    [sharedSession setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];

if (setCategoryError)
    NSLog(@"Error setting audio category! %@", setCategoryError);

return muteSwitch;
}

Para saber o estado do interruptor mute e o controle de volume Escrevi estas duas funções. Estes são ideais se você quiser avisar o usuário antes de tentar criar uma saída de áudio.

-(NSString*)audioRoute
{
    CFStringRef state;
    UInt32 propertySize = sizeof(CFStringRef);
    OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
    if( n )
    {
        // TODO: Throw an exception
        NSLog( @"AudioSessionGetProperty: %@", osString( n ) );
    }

    NSString *result = (NSString*)state;
    [result autorelease];
    return result;
}

-(Float32)audioVolume
{
    Float32 state;
    UInt32 propertySize = sizeof(CFStringRef);
    OSStatus n = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume, &propertySize, &state);
    if( n )
    {
        // TODO: Throw an exception
        NSLog( @"AudioSessionGetProperty: %@", osString( n ) );
    }
    return state;
}
-(BOOL)isDeviceMuted
{
 CFStringRef state;
 UInt32 propertySize = sizeof(CFStringRef);
 AudioSessionInitialize(NULL, NULL, NULL, NULL);
 AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
 return (CFStringGetLength(state) > 0 ? NO : YES);
}

Olie,

Eu acredito que você pode encontrar a resposta para sua pergunta aqui:

https://devforums.apple.com/message/1135#1135

Eu estou supondo que você tenha acesso aos Developer Forum em Apple.com:)

Eu segui a teoria geral aqui e tenho essa para o trabalho http://inforceapps.wordpress.com / 2009/07/08 / detectar-mudo-switch-state-on-iphone /

Aqui está um resumo: Tocar um som silencioso curto. Tempo quanto tempo leva para jogar. Se o mudo está ligado, a reprodução do som vai voltar muito mais curto do que o próprio som. Eu usei um 500ms som e se o som reproduzido em menos de desta vez, em seguida, o mudo começou. Eu uso Serviços de áudio para reproduzir o som silencioso (que sempre honra o interruptor mute). Este artigo diz que você pode usar AVAudioPlayer para jogar este som. Se você usar AVAudioPlayer, eu suponho que você precisa configurar sua categoria de AVAudioSession para honrar o interruptor de silêncio, mas eu não tentei it`.

Usando Ambient modo para reproduzir um vídeo e PlayAndRecord modo para gravar um vídeo na tela da câmera, resolve o problema no nosso caso.

O código na aplicação: didFinishLaunchingWithOptions:

NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoRecording error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];

O código na viewWillAppear em cameraController, se você tem que usar a câmera ou gravação em seu aplicativo

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

O código na viewWillDisappear em cameraController

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];

Usando essas linhas de nossos registros de aplicação e desempenha um vídeo e mudo funciona perfeitamente sob ambos iOS8 e iOS7 !!!

Para Swift

Abaixo quadro funciona perfeitamente no dispositivo

https://github.com/akramhussein/Mute

Basta instalar usando pod ou transferência a partir Git

pod 'Mute'

e utilização como código abaixo

import UIKit
import Mute

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel! {
        didSet {
            self.label.text = ""
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Notify every 2 seconds
        Mute.shared.checkInterval = 2.0

        // Always notify on interval
        Mute.shared.alwaysNotify = true

        // Update label when notification received
        Mute.shared.notify = { m in
            self.label.text = m ? "Muted" : "Not Muted"
        }

        // Stop after 5 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            Mute.shared.isPaused = true
        }

        // Re-start after 10 seconds
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) {
            Mute.shared.isPaused = false
        }
    }

}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top