2014年2月10日 星期一

[iOS] 調整系統音量(System Volume)_ Objective-C

尤其是遊戲與音樂類別的APP中,常會提供音量調整的介面,而這個音量大小很多時候都是牽動著系統音量的。曾經使用過一個音樂播放程式,有scroll bar可調整音樂音量,但是其音量的調整範圍卻是建立在系統音量之下,意思就是說,當今天系統音量是0.1時,用這個APP中內建的介面去調整音量,怎麼調都調不大聲,真正播放出來的聲音只介於0~0.1之間,由此來判斷,這個APP的音量控制,可能是使用AVAudioPlayer的volume屬性來做調整的。
如果想在APP中調整系統音量,方法有兩種,都是使用MediaPlayer.Framework,所以請記得在專案裡面加入喔:

方法1. 透過MPVolumeView
這個方法是透過MPVolumeView自動生成的scroller,讓使用者可以在APP中手動調整音量。
在.h標頭檔中將MPVolumeView.h匯入
#import <MediaPlayer/MPVolumeView.h>
.m實作檔中加入以下程式碼:
MPVolumeView *volumeView = [[MPVolumeView alloc] init];
[volumeView setFrame:CGRectMake(130, 305, 166, 40)];
[self.view addSubview:volumeView];
將紅字的部分替換成你想要的位置與大小,執行看看,就會看到畫面中出現一個scroller。試著拉動看看,會有股無名火從心中生起,想罵我這個騙子,因為就只是個scroller呀!與系統音量一點關係也沒有,按了右側的實體按鍵,也沒看scroller有什麼改變。
大人真是冤枉呀!我也是照著努力查來的資訊這麼做的咩!也是堵在這久久無法前行,之後發現,還真要騙才行!要先騙編譯器說:『唉嘿~我這個APP現在可是要播聲音的呢!這個...音量的事情...要麻煩...(搓手)』,要先行告知,方法就是先在專案中匯入一個音樂檔,並且加入AVFoundation.framework,接著撰寫下列程式碼:
在.h標頭檔中將AVFoundation.h匯入
#import <AVFoundation/AVFoundation.h>
在.m實作檔中加入
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test.mp3"]] error:NULL];
[audioPlayer prepareToPlay];
[audioPlayer stop];
將紅字替換成你的音樂檔名即可。執行看看,這次在按右側實體按鍵時,scroller也會跟著改變了!(如果本來就已經在播放影片跟音樂的話,上述的這一段應該就不需要了。)

方法2. 透過MPMusicPlayerController的volume屬性
其實volume這個屬性在iOS 7.0已經不宜使用了(deprecated),所以有許多做鬧鐘相關APP應用的開發者感到非常困擾,雖然硬是要用的話還是可以用啦!所以還是介紹一下。
請先在.h標頭檔中匯入MPMusicPlayerController.h,如下:
#import <MediaPlayer/MPMusicPlayerController.h>
至.m實作檔中,在需要程式自動調整系統音量的函式中加入下述程式碼:
MPMusicPlayerController *musicPlayerController = [MPMusicPlayerController applicationMusicPlayer];
musicPlayerController.volume = 1.0;
將紅字替換成你想要的音量大小,範圍為0.0~1.0之間,即可不透過使用者手動來改變系統音量,但在改變的同時,手機上會顯示出你調整的音量大小。
相關參考資料:
  • 關於volume屬性的官方文件
  • MPVolumeView之救人一命的大好文章:link
  • 官方Media Player Functions Reference:link
  • 官方MPVolumeView Class Reference:link
  • MPVolumeView Class教學:link
  • 監聽系統音量變化教學:link
2014/08/01 更新:
[iOS] 調整系統音量(System Volume)swift版本: link

2 則留言:

  1. 请问在一种方法下,应该怎么监听音量变化呢?我的本意是想监听实体音量键按动的事件。为了不显示音量变化的界面使用了MPVolumeView,跟你的方法一做了完全相同的事情。现在我的问题是,发现KVO player.volume 没反应,应该如何解决呢?谢谢啦。

    回覆刪除
    回覆
    1. 你好~我不確定是否有誤會你提出的討論,我針對這個寫了一篇文章,雖然是用Swift寫的,不過你可以參考看看。

      我嘗試了一下,發現正如你所說,player.volume沒有反應,所以研究了一下:
      監聽實體按鈕的音量,可以利用notification傳遞過來的資料來處理,你可以看看新的文章,或是列出的參考資料。
      主要是讀取(Objective-C):
      float volume =
      [[[notification userInfo]
      objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"]
      floatValue];

      新的文章在這裡:http://yummylife11.blogspot.tw/2014/08/ios-system-volume-swift.html

      如果有什麼問題,可以再提出來,一起討論討論 ^_^(不一定是最好的寫法,就麻煩你參考參考囉!)

      刪除