91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android音頻焦點管理實例分析

發布時間:2022-01-27 09:10:22 來源:億速云 閱讀:149 作者:kk 欄目:開發技術

這期內容當中小編將會給大家帶來有關Android音頻焦點管理實例分析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

    音頻焦點管理的意義

    兩個或兩個以上的 Android 應用可同時向同一輸出流播放音頻。系統會將所有音頻流混合在一起。雖然這是一項出色的技術,但卻會給用戶帶來很大的困擾。為了避免所有音樂應用同時播放,Android 引入了“音頻焦點”的概念。 一次只能有一個應用獲得音頻焦點。

    當您的應用需要輸出音頻時,它需要請求獲得音頻焦點,獲得焦點后,就可以播放聲音了。不過,在您獲得音頻焦點后,您可能無法將其一直持有到播放完成。其他應用可以請求焦點,從而占有您持有的音頻焦點。如果發生這種情況,您的應用應暫停播放或降低音量,以便于用戶聽到新的音頻源。

    音頻焦點管理的行為準則

    • 在即將開始播放之前調用 requestAudioFocus(),并驗證調用是否返回 AUDIOFOCUS_REQUEST_GRANTED。

    • 在其他應用獲得音頻焦點時,應該停止或者暫停播放,或者降低音量。

    • 播放停止后應該放棄音頻焦點

    版本兼容

    從Android 8.0(O版本,API 26)開始,音頻焦點的請求方式以及系統管理有了細微的變化,下面分兩部分來說明。

    在Android 8.0(API 26) 之前對音頻焦點具體處理實現

    當想錄音或者播放歌曲的時候,最好(非必須)先請求音頻焦點,這個時候需要調用AudioManager.requestAudioFocus()方法,函數原型如下

    AudioManager.requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)

    第一個參數用于監聽焦點變化

    第二個參數表明請求的音頻焦點影響的是那種類型流,例如,如果我們錄音,我們肯定是要影響Music這一類型的音頻流,因此可以選擇AudioManager.STREAM_MUSIC。當然還有許多類型。

    /** 通話相關 */
    public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
    /** 系統聲音 */
    public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;
    /** 鈴聲 */
    public static final int STREAM_RING = AudioSystem.STREAM_RING;
    /** 音樂相關 */
    public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;
    /** 鬧鐘相關 */
    public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;

    第三個參數用于表明音頻焦點的持續時間,這個很關鍵,它也有許多種類型,下面一一列出。

    • AudioManager.AUDIOFOCUS_GAIN: API文檔說請求的這類音頻焦點持續時間是未知的,通常用來表示長時間獲取焦點,可以用來播放音樂,錄音等等。

    • AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: 表明請求的音頻焦點持續時間比較短,通常用來播放導航路線的聲音,或者播放通知聲音。

    • AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: 這個也是表明請求的音頻焦點持續時間比較短,但是在這段時間內,它希望其他應用以較低音量繼續播放。例如,我們在使用導航的時候可以聽音樂,當出現導航語音的時候,音樂音量會降低以便我們能聽清楚導航的語音,當導航語音播放完畢后,音樂恢復音量,繼續播放。

    • AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: 這個也是表明音請求的音頻焦點持續時間比較短,但是在這段時間內,不希望任何應用(包括系統應用)來做任何與音頻相關的事情,就算是降低音量播放音樂也是不被希望的。例如當我們進行錄音或者語音識別的時候,我們不希望其他的聲音出現干擾。

    AudioManager.requestAudioFocus()的返回值表明請求的結果AudioManager.AUDIOFOCUS_REQUEST_FAILED表明請求焦點失敗,AudioManager.AUDIOFOCUS_REQUEST_GRANTED表明請求焦點成功。

    當我們成功請求焦點后,就可以做一些與音頻有關的事情,例如播放音樂,錄音,或者語音識別。當完成這些工作后,我們必須調用AudioManager.abandonAudioFocus(onAudioFocusChangeListener l)釋放音頻焦點。

    8.0 之后實現

    從Android 8.0開始(API 26),請求音頻焦點的方式以及系統對音頻焦點變化的管理有些微妙的變化。 首先,對音頻焦點變化的管理的變化體現在兩個方面,延遲獲取焦點和自動降低音量。

    延遲獲取焦點

    在Android 8.0之前,當我們請求音頻焦點的時候,只會返回兩種結果,要么請求成功(AUDIOFOCUS_REQUEST_GRANTED),要么請求失敗(AUDIOFOCUS_REQUEST_FAILED)。

    而從Android 8.0開始,還有一種結果,延遲成功請求(AUDIOFOCUS_REQUEST_DELAYED),這個也是成功的請求,但是這個請求具有延遲性。例如當我們處于通話狀態的時候,我們很顯然不希望任何app來獲取到音頻焦點來做些事,例如播放音樂。

    然而只有設置過AudioFocusRequest.Builder.setAcceptsDelayedFocusGain(true)才能獲取到這種結果,這個我們后面會講到。那么我們怎么知道什么時候獲取到了音頻焦點呢,當然還需要設置AudioManager.OnAudioFocusChangeListener這個音頻焦點變化的監聽器,通過回調確認何時獲取到了音頻焦點。

    自動降低音量

    在Android 8.0之前,如果請求焦點使用了AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK參數,它表明希望擁有了音頻焦點的其他應用降低音量來使用音頻,然而并不是所有的應用都會這樣做(有可能開發者忘記了優化),因為這并不是系統強制的。But, 從Android 8.0開始,這個降低音量的工作,就是系統默認行為了,可以說是一個良心的優化。

    如果我不希望系統自動給我降低音量,而是想自己暫停音頻相關的工作,那咋辦?這個可以通過AudioFocusRequest.Builder.setWillPauseWhenDucked(true)方法取消系統的默認行為,然后通過監聽音頻焦點變化

    音頻焦點請求方式

    從 Android 8.0(API 級別 26)開始,當您調用 requestAudioFocus() 時,必須提供 AudioFocusRequest 參數。要釋放音頻焦點,請調用 abandonAudioFocusRequest() 方法,該方法也接受 AudioFocusRequest 作為參數。在請求和放棄焦點時,應使用相同的 AudioFocusRequest 實例

    要創建 AudioFocusRequest,請使用 AudioFocusRequest.Builder。由于焦點請求始終必須指定請求的類型,因此此類型會包含在構建器的構造函數中。使用構建器的方法來設置請求的其他字段

    • setFocusGain(): 只有這個方法是必須的,而傳入的參數與8.0之前使用AudioManager.requestAudioFocus()傳入的第三個參數一樣,都是用來表示持續時間。

    • setAudioAttributes(): 這個方法是用來描述app的使用情況。這方法需要傳入一個AudioAttributes對象,這個對象也是使用Builder模式來構造,例如使用AudioAttributes.Builder.setUsage()來描述使用這個音頻來干什么,我們可以傳入一個AudioAttributes.USAGE_MEDIA來表明用這個音頻來作為媒體文件來播放,也可以傳入一個AudioAttributes.USAGE_ALARM來表明用這個來作為鬧鈴。

    • setWillPauseWhenDucked(): 這個前面說過,是為了覆蓋系統默認降低音量的行為,但是必須要設置AudioManager.OnAudioFocusChangeListener才能自己處理這類情況。

    • setAcceptsDelayedFocusGain(): 這個前面也說過,這個是為了能夠延遲獲取到焦點的必須條件,但是同時也必須要設置AudioManager.OnAudioFocusChangeListener才能得知何時獲取到焦點。

    • setOnAudioFocusChangeListener(): 音頻焦點變化監聽器。值得一提的是這個方法有個重載的方法,有一個重載方法有兩個參數,第二個參數為Handler對象,看到Handler應該明白了,是為了使用它的消息隊列來順序處理這個回調

    響應音頻焦點更改

    當應用獲得音頻焦點后,它必須能夠在其他應用為自己請求音頻焦點時釋放該焦點。出現這種情況時,您的應用會收到對 AudioFocusChangeListener 中的 onAudioFocusChange() 方法的調用,該方法是您在應用調用 requestAudioFocus() 時指定的。

    傳遞給 onAudioFocusChange() 的 focusChange 參數表示所發生的更改類型。它對應于獲取焦點的應用所使用的持續時間提示。您的應用應該做出適當的響應

    暫時性失去焦點

    如果焦點更改是暫時性的(AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK 或 AUDIOFOCUS_LOSS_TRANSIENT),您的應用應該降低音量(如果您不依賴于自動降低音量)或暫停播放,否則保持相同的狀態。

    在暫時性失去音頻焦點時,您應該繼續監控音頻焦點的變化,并準備好在重新獲得焦點后恢復正常播放。當搶占焦點的應用放棄焦點時,您會收到一個回調 (AUDIOFOCUS_GAIN)。此時,您可以將音量恢復到正常水平或重新開始播放。

    永久性失去焦點

    如果是永久性失去音頻焦點 (AUDIOFOCUS_LOSS),則其他應用會播放音頻。您的應用應立即暫停播放,因為它不會收到 AUDIOFOCUS_GAIN 回調。要重新開始播放,用戶必須執行明確的操作,例如在通知或應用界面中按播放傳輸控件。

    附音頻基礎知識

    采樣和采樣頻率:一秒鐘內采樣的次數稱為采樣頻率。采樣頻率越高,越接近原始信號,但是也加大了運算處理的復雜度。根據Nyquist采樣定理,要想重建原始信號,采樣頻率必須大于信號中最高頻率的兩倍。人能感受到的頻率范圍為20HZ--20kHZ, 一般音樂的采樣頻率為44.1kHZ, 更高的可以是48kHZ和96kHZ,不過一般人用耳聽感覺不出差別了。語音主要是以溝通為主,不需要像音樂那樣清晰,用16k采樣的語音就稱為高清語音了。現在主流的語音采樣頻率為16kHz。

    采樣位數:數字信號是用0和1來表示的。采樣位數就是采樣值用多少位0和1來表示,也叫采樣精度,用的位數越多就越接近真實聲音。如用8位表示,采樣值取值范圍就是-128--127,如用16位表示,采樣值取值范圍就是-32768--32767。現在一般都用16位采樣位數。

    聲道:聲道是指處理的聲音是單聲道還是立體聲。Android支持雙聲道立體聲和單聲道。CHANNEL_IN_MONO單聲道,CHANNEL_IN_STEREO立體聲。單聲道在聲音處理過程中只有單數據流,而立體聲則需要左、右聲道的兩個數據流。顯然,立體聲的效果要好,但相應的數據量要比單聲道的數據量加倍。

    碼率:就是比特率。比特率是指每秒傳送的比特(bit)數。碼率=采樣率X采樣位數X聲道數。

    音頻采集和播放:一般用專門的芯片(通常叫codec芯片)采集音頻,做AD轉換,然后把數字信號通過I2S總線(主流用I2S總線,也可以用其他總線,比如PCM總線)送給CPU處理(也有的會把codec芯片與CPU芯片集成在一塊芯片中)。當要播放時CPU會把音頻數字信號通過I2S總線送給codec芯片,然后做DA轉換得到模擬信號再播放出來。

    Android是什么

    Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

    上述就是小編為大家分享的Android音頻焦點管理實例分析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    鄂州市| 甘孜| 资溪县| 安阳市| 武义县| 丽水市| 左云县| 潼南县| 和林格尔县| 新闻| 聊城市| 平定县| 色达县| 栾城县| 兰考县| 贵南县| 沙河市| 托克托县| 枣庄市| 屯门区| 满洲里市| 许昌市| 易门县| 乌鲁木齐县| 江达县| 安龙县| 泾川县| 高陵县| 江安县| 中牟县| 军事| 德庆县| 鄂托克前旗| 乐清市| 朝阳县| 山丹县| 衢州市| 格尔木市| 泌阳县| 峨眉山市| 临西县|