やりたいこと
特定の画面を音が聞こえる状態で使ってもらいたいので、本体が消音状態 or ボリューム小だったらアラートとか出したい
→iPhone本体のmuteスイッチ状態、ボリューム値を取得したい
結論としては「MPVolumeViewを使いなさいよ」ということなんだが、ちょっと調べた内容をメモしておきたい。
ミュート状態取得する方法
音声ファイル再生してみることによって消音状態の判別を行うアイディアの実装。
検出(音声再生)要求をcall → 判定結果のdelegateが呼ばれると状態が分かるという寸法。
見つけたときは「おおっ!」と思ったが、同期的に取得できる方法が欲しかったのと、ミュート状態取得がそこまでMUSTではなかったので今回はこの方法はパス。
”音量値をできるだけ簡単に参照する方法”を探した。
音量取得する方法
×:MPMusicPlayerController(deprecated)
NSLog(@"app:%f", [MPMusicPlayerController applicationMusicPlayer].volume);
NSLog(@"sys:%f", [MPMusicPlayerController systemMusicPlayer].volume);
とやってみると 0.0 -> 1.0 の範囲で取得される
- 本体サイドのvolを +/- 操作 →値変化しない
- iPod(音楽再生中)のvol +/- 操作 →値変化する
名前のとおり、取得できるのは "MusicPlayer" のボリューム値
一応これが所望の音量ではあるかな?
しかし、"volume"プロパティはiOS7からdeprecated
×:ObjectAL経由 = AvAudioSession(deprecated)
音声ファイル再生のために利用しているライブラリ
ObjectAL > OALSimpleAudio
ヘッダを眺めてみるとmuteとかがプロパティとして定義されていたり、音声ファイル再生時のパラメータとして"volume"があったり。
これはシステムの再生音量というよりは、再生しようとする音声データ(入力)のレベルだと理解している。
OALSimpleAudio *osa = [OALSimpleAudio sharedInstance];
BOOL muted = osa.muted; // NO
BOOL bgMuted = osa.bgMuted; // NO
float vol = osa.bgVolume; // 1
動作させてみたらコメント部の値。
本体MuteスイッチのON/OFFでmuted/bgMutedの値は変わらず。
bgVolumeもボリューム操作しても変わらず。
そもそも"bg"だし、用途が違うっぽい。(todo:詳細はちゃんとヘッダとかドキュメント読む)
//HardwareDemo.m, line117あたり
volume = [OALAudioSession sharedInstance].hardwareVolume;
muted = [OALAudioSession sharedInstance].hardwareMuted;
AvAudioSessionからハードウェアの音量取得できそう?
AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareOutputVolume)
しかしながら、AudioSessionGetProperty
もiOS7から使えなくなっている様子。
◯:MPVolumeViewを利用
MPVolumeView -> MPVolumeSlider を取得 -> UISlider経由で現在の音量値を得る というアイディア。
さすがです先輩。
元記事では最終的にやってることが異なるが、その過程のサンプルコードが役立ちました。
公式に提供されている音量を”変更する”手段なわけだが、あくまでも”変更”であって、”参照”する方法は明示的には提供されていないっぽい。
「MPVolumeViewやUISliderは表示せず、音量取得のためだけに裏で使う」
ということ。
// viewDidLoadとか、適当なとこで
MPVolumeView *volumeView = [[volumeView alloc] init];
float volume = -1.0;
for (UIView *view in [volumeView subviews]) {
if ([view.class.description isEqualToString:@"MPVolumeSlider"]) {
UISlider *volumeSlider = (UISlider *)view;
volume = volumeSlider.value;
break;
}
}
NSLog(@"%f", volume) // -1.0のままの場合は取得できていない
音量取得の方法が解決したと同時に、”オブジェクトの中を参照する”というやり方も勉強になりました。
以上。