iPhoneのミュートボタン/スイッチをプログラムで感知する方法がSDKで見つからないようです。私のアプリがバックグラウンド ミュージックを再生すると、それに従うコードがなくても音量ボタンに適切に応答しますが、ミュート スイッチを使用すると、そのまま再生され続けます。
ミュートの位置をテストするにはどうすればよいですか?
(注: 私のプログラムには独自のミュート スイッチがありますが、物理的なスイッチでそれをオーバーライドしたいと考えています。)
iPhoneのミュートボタン/スイッチをプログラムで感知する方法がSDKで見つからないようです。私のアプリがバックグラウンド ミュージックを再生すると、それに従うコードがなくても音量ボタンに適切に応答しますが、ミュート スイッチを使用すると、そのまま再生され続けます。
ミュートの位置をテストするにはどうすればよいですか?
(注: 私のプログラムには独自のミュート スイッチがありますが、物理的なスイッチでそれをオーバーライドしたいと考えています。)
ありがとう、JPM。確かに、あなたが提供するリンクは正しい答えにつながります(最終的には。;)完全を期すために(SOはクイックアンサーのソースになるはずです!)...
// "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.");
}
ここで同様の質問に答えました(リンク) . 関連するコード:
-(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;
}
ミュート スイッチが尊重されるアンビエント モードでない場合、他の回答 (受け入れられた回答を含む) のコードの一部が機能しない場合があります。
アンビエントに切り替え、スイッチを読み取り、アプリで必要な設定に戻るルーチンを以下に記述しました。
-(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;
}
ミュートスイッチとボリュームコントロールの状態を調べるために、これら2つの関数を作成しました。これらは、ユーザーがオーディオ出力を作成しようとする前にユーザーに警告したい場合に理想的です。
-(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);
}
ここで一般的な理論に従い、これを機能させました http://inforceapps.wordpress.com/2009/07/08/detect-mute-switch-state-on-iphone/
要約は次のとおりです。短いサイレント サウンドを再生します。再生にかかる時間。ミュートスイッチがオンの場合、サウンドの再生はサウンド自体よりもはるかに短くなります。500 ミリ秒のサウンドを使用しましたが、サウンドがこの時間未満で再生された場合は、ミュート スイッチがオンになっています。Audio Services を使用してサイレント サウンドを再生します (これは常にミュート スイッチを尊重します)。この記事では、AVAudioPlayer を使用してこのサウンドを再生できると述べています。AVAudioPlayer を使用する場合は、AVAudioSession のカテゴリを設定してミュート スイッチを有効にする必要があると思いますが、試したことはありません。
ビデオを再生するためにAmbientモードを使用し、カメラ画面でビデオを録画するためにPlayAndRecordモードを使用すると、この場合の問題が解決されます。
アプリケーションのコード:didFinishLaunchingWithOptions:
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVideoRecording error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];
アプリでカメラまたは録画を使用する必要がある場合、viewWillAppear のコードは cameraController に表示されます。
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
viewWillDisappear のコードは cameraController で
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
これらの行を使用して、アプリケーションはビデオを記録および再生し、ミュート スイッチは iOS8 と iOS7 の両方で完全に機能します!!!
オリー、
ここであなたの質問に対する答えを見つけることができると思います:
https://devforums.apple.com/message/1135#1135
Apple.com の Developer Forums にアクセスできることを前提としています :)