聲音
iOS設(shè)備可以實現(xiàn)很棒的聲音效果。在你的程序中,聲音可能是核心的組成部分,或者偶爾出現(xiàn)增強效果。無論聲音扮演的角色如何,你應(yīng)當知道用戶對聲音抱著怎樣的期望,應(yīng)該如何來滿足它。
理解用戶的期望
用戶在設(shè)備上調(diào)節(jié)聲音,也可能帶著有線或無線的耳機。用戶也對應(yīng)該如何控制聲音有所期望。雖然你可能覺得有些期望很奇怪,但它們都遵循由用戶來控制何時應(yīng)聽到聲音的原則,而非由設(shè)備。
用戶會如下情況切換成靜音:
● 避免被不符合期望的聲音打擾,比如電話或短信的提醒音
● 避免聽到由操作帶來的副產(chǎn)品,比如鍵盤音或其他反饋音、故障音或啟動音樂
● 避免聽到與玩游戲不太相干的聲音,比如偶發(fā)的故障音。
例如,在劇院里用戶希望把設(shè)備調(diào)成靜音,以免打擾其他觀眾。這種情況下,用戶依然想使用程序,但并不想被出乎意料的聲音嚇到,比如鈴聲或新消息提醒音。
對某些刻意設(shè)定的聲音,當用戶的操作觸發(fā)它時,Ring/Silent的設(shè)置不能關(guān)閉它。例如:
媒體播放器里的播放不會靜音,因為播放是由用戶主動請求的。
鬧鐘不會靜音,因為它是由用戶明確設(shè)定為⑧有聲⑨的。
在語言學習軟件中的聲音片段不應(yīng)靜音,因為用戶有明確的欲望想聽到它。
語音聊天程序中的對話不應(yīng)靜音,因為用戶打開它就是為了聽聲的。
用戶使用設(shè)備音量鍵所做的調(diào)節(jié)會影響所有設(shè)備播放的聲音。這包括歌曲、程序聲音和設(shè)備聲音。用戶總是可以使用音量鍵靜音,無論Ring/Silent設(shè)置在哪一檔上。使用音量按鈕調(diào)節(jié)程序當前的聲音時,整個系統(tǒng)的音量都會受影響,鈴聲除外。
對于iPhone 來講,當沒有任何程序在播放聲音時,調(diào)節(jié)音量按鈕就會調(diào)整鈴聲音量。
用戶使用耳機來私下地聽聲音,同時解放雙手。無論這些設(shè)備是有線、無線,用戶對體驗都有一些期望。
當用戶插入耳機或聯(lián)通無線聲音設(shè)備時,他們是想私下里聽這些聲音。由于這個原因,他們希望當前正在播放的聲音不要暫停。
當用戶拔出耳機或與無線設(shè)備斷開時,他們不想把剛才聽到的聲音自動共享給其他人。所以,他們希望當前正播放的聲音可以暫停,等到用戶準備好了再重新播放。
定義聲音的行為
有必要的話,你可以為自己的程序設(shè)定相對的、獨立的音量水平,以便產(chǎn)生合適的聲音輸出。
但是終的聲音輸出還是要受系統(tǒng)音量的管制,由音量鍵或者音量滾動條來調(diào)節(jié)。這意味著程序音量的控制權(quán)還是在用戶手中。
合適的話,要給程序加上選擇聲道(audio route)的控件。即使當用戶沒有插上或拔下無線聲音設(shè)備,他也希望能選擇不同的聲道。為了解決這個問題,iOS自動提供了讓用戶選擇輸出通道的控件。由于切換聲道是用戶觸發(fā)的行為,用戶期望正在播放的聲音不要停。
如果程序只是在主界面上放些伴奏聲,就使用system sound services。SSS是一種產(chǎn)生警告聲、界面聲(UI Sounds)和振動的后臺服務(wù)。當使用SSS播放聲音時,你不能設(shè)置該聲音如何與設(shè)備上的其他混響,也不能設(shè)置如何處理中斷或其他設(shè)備設(shè)置的改變。
如果聲音是程序的核心功能之一,使用Audio Session Service 或者 AVAudioSession類。
這些類不能直接產(chǎn)生聲音,但可以幫你設(shè)置該聲音如何與設(shè)備上的其他混響,如何處理中斷或其他設(shè)備設(shè)置的改變。
在iPhone上,無論你用了什么樣的技術(shù)去控制聲音,iPhone總能打斷當前運行中的程序。因為任何程序都不應(yīng)妨礙到用戶接聽來電。
在Audio Session Service中,audio session充當程序與系統(tǒng)的調(diào)節(jié)者。它重要的一面是category,可以用來定義程序的聲音行為。
為了運用Audio Session Service的優(yōu)勢,提供用戶期待的聲音體驗,你應(yīng)當選擇與你的聲音行為相符的那一類。這要看你的程序是只在前臺時播放聲音,還是在后臺也能播放?梢詤⒄杖缦轮改希
根據(jù)category的語義來選擇,而非對行為的細節(jié)描述。這樣能保證你的程序能符合用戶期望。另外,如果將來類目對應(yīng)的行為方式被修訂了,也能保證你選擇類目是合適的。
少數(shù)情況下可以在標準行為的基礎(chǔ)上稍作定制。類別對應(yīng)的標準行為與大多數(shù)用戶的期望一致,所以在自定義前要考慮清楚。例如,你可能想添加⑧Should Duck⑨屬性,以便你的程序音比其他聲音都大(除了鈴聲),以便符合用戶的需求。
考慮根據(jù)設(shè)備當前的聲音環(huán)境來選擇類別。這也許是合理的,因為用戶也許想使用你的程序的同時聽著其他聲音。這樣的話,當用戶啟動你的程序時,不要暫停用戶正在聽的聲音或強迫用戶選擇音軌。
一般而言,避免在程序運行過程中改變類別。改變類別的主要原因是你的程序可能需要在不同的時候支持錄音和回放。這種情況下,可以在錄音類和回放類之間切換,而非只用⑧播放和錄音類⑨。這是因為選擇錄音類可以避免在錄制過程中有警告聲(比如新短信)出現(xiàn)。
表格7-2中列述了你可以使用的類別。

這里是一些用例,介紹如何選擇與用于期望一致的聲音類別。
用例1:幫助用戶學習語言的教學程序。你可以提供:
當用戶觸摸某個控件時提供反饋音
當用戶想聽正確的發(fā)音時記錄單詞和詞匯
在這個程序里,聲音是核心功能。用戶使用這個程序來聽所學語言的單詞和短語發(fā)音。所以即使設(shè)備的聲音鎖掉了也應(yīng)該發(fā)音。應(yīng)為用戶需要清楚地聽到發(fā)音,所以希望其他聲音都靜下來。
為了提供符合用戶期待的聲音,你應(yīng)該使用playback類。雖然這個類可以在稍加修改后支持與其他聲音混響,這個程序應(yīng)當使用默認的行為,以便保證其他程序的聲音不會帶來干擾。
用例2:Voice over internet protocol(VoIP)電話程序,你應(yīng)當提供:
獲得聲音輸入
播放聲音
在這個程序中,聲音是核心功能。用戶使用該程序與他人聯(lián)絡(luò)時,往往有其他程序正在運行。
用戶希望能在把設(shè)備設(shè)為靜音或設(shè)備被鎖定時依然能接聽電話,并希望在通話過程中其他程序保持安靜。用戶也希望當程序跑在后臺時依然能收到電話。
為了提供符合用戶期待的聲音,你應(yīng)該使用Play and Record類。另外,只能在需要的時候激活audio session,以便于在不通話的時候可以使用其他聲音模式。
用例3:允許用戶扮演角色執(zhí)行多種任務(wù)的游戲。你應(yīng)帶提供:
各種游戲音效
音樂音軌
在這個程序中,聲音可以提升用戶體驗,但是并不是主任務(wù)的核心。而且,用戶也可能想靜音玩游戲,或者聽著其他音樂玩。
好的策略是看一下程序啟動時用戶有沒有在聽其他聲音。不要在開始時讓用戶選擇想聽哪個音軌。可以調(diào)用ASS的函數(shù)AudioSessionGetProperty,讀取kAudioSessionProperty_OtherAudioIsPlaying的值;谶@個值,你可以選擇Ambient或者Solo Ambient類(兩種類都支持用戶靜音玩游戲)。
如果程序啟動時用戶正在聽其他聲音,應(yīng)該假設(shè)他想繼續(xù)聽,不應(yīng)該強行用當前程序的音軌代替它。這種情況下,應(yīng)該選擇Ambient類。
如果程序啟動時用戶沒在聽其他聲音,選擇Solo Ambient 類。
用例4:將用戶精確實時地導航到目的地的程序。你應(yīng)該提供
為行程中每一步說出方向
少許聲音反饋
可以繼續(xù)收聽其他聲音
在這個程序中,無論它在前臺還是后臺運行,聲音導航提示都是主要任務(wù);诖,你應(yīng)該使用Playback類,允許你在設(shè)備被鎖或切換到靜音、程序跑在后臺時也能播放聲音。
要想讓用戶運行程序的同時可以聽其他聲音,你可以添加kAudioSessionProperty_O
verrideCategoryMixWithOthers屬性。但是,你同時也希望用戶能在其他聲音播放時聽到聲音指示。這可以通過增加kAudioSessionProperty_OtherMixableAudioShouldDuck屬性來實現(xiàn)。這樣你的聲音就會比所有其他音軌的聲音大(除了iPhone上的電話聲)。
用例5:允許用戶上傳圖片和文字到網(wǎng)頁的博客程序。你應(yīng)該提供
簡短的啟動音樂
與用戶操作相匹配的音效(比如上傳成功后的提示)
上傳失敗時的警告音。
在這個程序中,聲音可以提升用戶體驗,但不是核心功能。主任務(wù)與聲音無關(guān),用戶不依賴聲音也能成功滿足需求。在這個勇利用,你應(yīng)該使用SSS來播放聲音。這是因為所有該程序?qū)β曇舻囊蠖寂cSSS的特性相符(播放界面音效和警告音,無視設(shè)備是否被鎖,無視Ring/Silent的設(shè)置)。
管理聲音沖突
有時,來自多個程序播放的聲音會沖突。例如,打電話的過程中電話聲會和正在播放的其他聲音沖突。在多任務(wù)環(huán)境中,這種沖突的頻率會更高。
為了提供符合用戶期望的音效,iOS需要你:
確定你的程序會導致怎樣的沖突。
在沖突解除后選擇合適的應(yīng)對方式。
每一個程序都需要確認可能會導致的沖突,但并不是每一個程序都需要制定應(yīng)對沖突的方案。
這是因為對于大多數(shù)程序來說,在沖突解除后繼續(xù)播放就是一個合適的方案。只有以錄音回放為主,提供回放控件的程序需要額外地定義好應(yīng)對方案。
從概念上來說,根據(jù)導致沖突的聲音類型以及用戶對沖突后的期待來分,共有兩種聲音沖突。
可恢復(fù)的沖突。當用戶在使用以聽覺為核心的程序時被其他聲音暫時干擾時,會出現(xiàn)可恢復(fù)的沖突。
可恢復(fù)中斷結(jié)束后, 有回放控件的程序應(yīng)該恢復(fù)到中斷發(fā)生前的狀態(tài),無論之前是正在播放還是暫停狀態(tài)。沒有回放控件的程序應(yīng)該恢復(fù)到播放狀態(tài)。(After a resumable interruption ends, an app that displays media playback controls should resume what it was doing when the interruption occurred, whether this is playing audio or remaining paused. An app that doesn’t have media playback controls should resume playing audio.)
例如,當用戶正用iPhone聽音樂時,突然來了個VoIP電話。用戶接了電話,希望在通話過程中音樂保持靜音。電話打完后,用戶希望回放(playback)型程序能自動恢復(fù)播放音樂。這是因為用戶在接電話前并沒有主動暫停音樂,所以希望打完電話后能繼續(xù)享受歌聲。否則,播放器在電話打完后就應(yīng)該還是暫停狀態(tài)。
不可恢復(fù)的沖突。不可恢復(fù)的沖突是由以播放聲音為核心功能的程序引起的,比如媒體播放器。
在不可恢復(fù)沖突結(jié)束后,顯示了回放控件的程序不要恢復(fù)播放,沒有回放控件的程序應(yīng)該恢復(fù)到播放狀態(tài)。
例如,當用戶在聽1號播放器的音樂時被2號播放器的聲音打斷。用戶決定聽一會兒2號播放。
再退出2號播放器后,用戶不會希望1號播放器再自動播放,因為他已主動將2號播放器視作了主程序。
以下指南幫助你判斷應(yīng)提供什么樣的信息,以及如何在中斷結(jié)束后繼續(xù):
確定程序?qū)е轮袛嗟念愋。你可以在你的聲音播放完畢后通過以下兩種方式屏蔽你的聲音:
如果你的程序?qū)е碌氖强苫謴?fù)的中斷,給你的聲音打上AVAudioSessionSetActiveFlags_NotifyOthersOnDeactivation的標。
如果你的程序?qū)е碌氖遣豢苫謴?fù)的中斷,就不用打標了。
這樣做可以幫助iOS恢復(fù)被打斷的聲音播放。
判斷中斷結(jié)束后你是否應(yīng)該恢復(fù)播放。你可以根據(jù)程序所播放聲音的體驗類型來判斷。
如果你的程序提供了讓用戶播放或暫停聲音的媒體回放控件,就應(yīng)該在中斷結(jié)束后檢查AVAudioSessionInterruptionFlags_ShouldResume標簽。
如果存在“Should Resume”標簽,你應(yīng)該:
如果你的程序在被打斷時正播放聲音,那就恢復(fù)播放
如果你的程序在被打斷時沒有播放聲音,那就不要恢復(fù)播放
如果你的程序沒有提供讓用戶播放或暫停聲音的媒體回放控件,就應(yīng)該在中斷結(jié)束后恢復(fù)剛才播放的聲音,不必再去檢查”Should Resume”標簽是否存在。
例如,播放音軌的游戲應(yīng)該在中斷結(jié)束后立即恢復(fù)播放。
處理遠程媒體控制事件
從iOS4.0起,程序可以在用戶使用iOS媒體控制器或其他附件時接受遠程控制事件。這使得無論你的程序是在前臺還是后臺,都能從界面以外的地方獲得指令。
媒體回放程序尤其需要使當?shù)仨憫?yīng)這些事件,尤其是當在后臺播放音樂時。
為了承擔起保護隱私的責任,請遵守以下指南:
只在合理的時候接受遠程控制信號。例如,如果你的程序支持閱讀內(nèi)容,搜索信息和聽音頻,那么只在用戶聽音頻時才接受遠程信號。當用戶沒在聽音頻時,就要把接收事件的權(quán)限釋放出來。這使得用戶可以在使用你的程序閱讀內(nèi)容時方便地收聽、控制其他程序的音頻。
即使某個事件對你的程序沒有意義,也不要重新定義事件的含義。用戶希望iOS媒體控制器和附件的事件在所有程序里具有一致的含義。不要處理與你的程序不需要的事件。所有你處理的事件就要符合用戶的期望。一旦重新定義事件的含義,用戶就暈了,必須要退出你的程序才能脫離困境。
|