999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于Android平臺的音頻播放處理研究與實現(xiàn)

2020-12-23 05:47:19王強洪蕾
軟件 2020年10期

王強 洪蕾

摘? 要: 隨著Android終端設(shè)備的普及,基于Android平臺的音頻應(yīng)用大批涌現(xiàn)。對于音頻的處理,Android提供了MediaPlayer來滿足開發(fā)者對音頻的處理,MediaPlayer在音頻采集、解碼和播放,需要將音頻數(shù)據(jù)從Java層拷貝到native層,對系統(tǒng)資源的消耗是巨大的。為了減少數(shù)據(jù)的拷貝,開發(fā)更加高效的Android音頻應(yīng)用,能夠直接在native層處理音頻數(shù)據(jù)顯得尤為重要。本文介紹將FFmpeg與OpenSL ES的數(shù)據(jù)結(jié)構(gòu),在native層使用FFmpeg的解碼過程,及使用OpenSL ES對音頻數(shù)據(jù)的播放處理研究。

關(guān)鍵詞: Android;Ffmpeg;OpenSLES;解碼;音頻播放

中圖分類號: TP311.52? ? 文獻(xiàn)標(biāo)識碼: A? ? DOI:10.3969/j.issn.1003-6970.2020.10.008

本文著錄格式:王強,洪蕾. 基于Android平臺的音頻播放處理研究與實現(xiàn)[J]. 軟件,2020,41(10):3133

【Abstract】: With the popularity of Android terminal devices, a large number of audio applications based on the Android platform have emerged. For audio processing, Android provides MediaPlayer to meet the needs of developers for audio processing. MediaPlayer needs to copy audio data from the Java layer to the native layer for audio acquisition, decoding and playing, which consumes a lot of system resources. In order to reduce the copy of data, to develop more efficient Android audio applications, it is particularly important to be able to directly process audio data in the native layer. This paper introduces the data structure of FFmpeg and OpenSL ES, the decoding process of FFmpeg in the native layer, and the playback processing of audio data using OpenSL ES.

【Key words】: Android; FFmpeg; OpenSLES; Decoded; Audio playback

0? 引言

Android[1-4]終端設(shè)備的普及,讓人們對安卓應(yīng)用的體驗有著越來越高的需求。音頻的處理包含著許多方面,如音樂播放[5],音頻錄制等。手機性能的局限導(dǎo)致對安卓應(yīng)用在控制性能消耗有著高的需求,所以開發(fā)人員在完成音頻應(yīng)用開發(fā)的時候選擇一個合適的方案是必要的。

Android提供了MediaPlayer對音頻進(jìn)行播放處理,而MediaPlayer在處理音頻上對系統(tǒng)資源有著巨大的消耗。采用FFmpeg與OpenSLES,可以讓應(yīng)用層傳遞目標(biāo)音頻的資源地址,使得FFmpeg直接在native層對資源進(jìn)行訪問,解碼音頻,然后將數(shù)據(jù)傳遞給OpenSLES進(jìn)行處理。降低性能消耗。

1? 關(guān)鍵技術(shù)研究

1.1? FFmpeg

FFmpeg[6]是一套用來記錄,轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源程序。提供了轉(zhuǎn)換、錄制與音視頻流化的完整解決方案,不僅包含了編解碼、流化音頻文件的功能,還可以對音頻文件進(jìn)行錄制、轉(zhuǎn)換等工作[7]。

通過對FFmpeg的研究,給出其對音頻數(shù)據(jù)的解碼流程,如圖1所示。

1.2? OpenSL ES

OpenSL ES[8]是針對嵌入式系統(tǒng)調(diào)整的無授權(quán)費,跨平臺,硬件加速的音頻API。它為嵌入式移動多媒體設(shè)備上的應(yīng)用程序開發(fā)人員提供了一套標(biāo)準(zhǔn)化,高性能,低延遲的音頻處理方案,從而實現(xiàn)了硬件和軟件音頻功能的直接跨平臺部署。

OpenSL ES作為音頻開發(fā)的API,它相較于Android提供的Java層API,如MediaPlayer,減少了數(shù)據(jù)在Java層和native層的拷貝,提高效率,并配合FFmpeg,播放解碼轉(zhuǎn)碼后的PCM音頻數(shù)據(jù)。

通過對OpenSL ES的研究,給出其對音頻數(shù)據(jù)的播放流程,如圖2所示。

2? 程序結(jié)構(gòu)與方案設(shè)計

2.1? 程序結(jié)構(gòu)設(shè)計

對于程序的結(jié)構(gòu)設(shè)計,給出其結(jié)構(gòu)圖,如圖3所示。

為了方便開發(fā)者的調(diào)用,在對native層的調(diào)用上封裝了一層代碼,即程序結(jié)構(gòu)圖中的AudioPlayer類,向外提供操作接口,實現(xiàn)了播放,暫停,停止與循環(huán)等功能。

在AudioPlayer類中,使用native關(guān)鍵字聲明與native層交互的函數(shù),并一一對應(yīng)在native-lib類中進(jìn)行實現(xiàn)。通過Java的JNI機制讓Java層與底層C++進(jìn)行交互,即對native-lib類函數(shù)進(jìn)行調(diào)用,具體表現(xiàn)為,向native-lib類傳遞音頻的資源地址,通過對AudioPlayer類提供的音頻控制函數(shù),調(diào)用native-lib類中對應(yīng)的控制方法,對音頻的播放暫停,占用資源釋放與循環(huán)進(jìn)行控制。

在native-lib類中,通過對Decoder類的調(diào)用完成解碼,播放,暫停,資源釋放的功能。

在Decoder類中,首先通過FFmpeg完成對音頻信息的采集,解碼器的初始化與音頻解碼的工作,并將解碼完成的音頻數(shù)據(jù)緩存入SafeQueue類中,再通過調(diào)用Audio類進(jìn)行對音頻的處理工作。

通過Decoder類的調(diào)用,Audio類會進(jìn)行對OpenSL ES的相關(guān)初始化,并等待FFmpeg解碼完成的數(shù)據(jù),與音頻編碼轉(zhuǎn)碼,然后進(jìn)行播放。

2.2? 方案設(shè)計

對于FFmpeg的解碼[9]設(shè)計,給出其結(jié)構(gòu)圖,如圖4所示。

通過FFmpeg進(jìn)行對數(shù)據(jù)源的解碼。這里涉及兩個重要的結(jié)構(gòu)體。AVFormatContext,用于存儲音頻格式中的信息,AVCodecContext,用于存儲音頻解碼器信息[10]。由于解碼是個耗時操作,需要開啟子線程進(jìn)行解碼,由于Android系統(tǒng)是基于Linux內(nèi)核,而Linux又是遵循POSIX線程標(biāo)準(zhǔn)的,所以采用POSIX線程創(chuàng)建子線程。完成解碼需要執(zhí)行以下幾個操作:①FFmpeg通過av_register_all()注冊編解碼器,avformat_network_ init()進(jìn)行網(wǎng)絡(luò)初始化,以便FFmpeg可以直接訪問網(wǎng)絡(luò)地址。②通過avformat_open_input(),打開輸入文件流,讀取數(shù)據(jù)并判斷文件編碼格式,將格式信息存入AVFormatContext結(jié)構(gòu)體中。③通過avformat_find_ stream_info(),獲得文件的編碼信息,將信息存入AVFormatContext結(jié)構(gòu)體中。④遍歷AVFormatContext結(jié)構(gòu)體中的數(shù)據(jù)流,根據(jù)類型判斷,找到音頻流,保存音頻流的索引,并保存至音頻類對象Audio中。⑤通過avcodec_find_decoder()函數(shù)與AVFormatContext中保存的文件編碼格式找到相應(yīng)的解碼器⑥通過avcodec_parameters_to_context(),將音頻流信息保存至AVCodecContext結(jié)構(gòu)體中⑦通過avcodec_open2()打開解碼器。⑧通過av_read_frame()讀取原始音頻數(shù)據(jù)幀AVPacket,如果讀取失敗,則回調(diào)AudioPlayer類,通知調(diào)用者,反之,如果成功,則將數(shù)據(jù)存入SafeQueue類的幀隊列中。由于解碼的速度往往遠(yuǎn)大于音頻播放的速度,所以需要對解碼完成后的數(shù)據(jù)進(jìn)行緩存,先解碼好的先播放,利用隊列這個數(shù)據(jù)結(jié)構(gòu)。實現(xiàn)隊列的存、取、獲取隊列長度與清空隊列操作。因為音頻數(shù)據(jù)是邊解碼邊播放的,在對數(shù)據(jù)的存與取時可能會產(chǎn)生沖突,所以對于隊列的存與取需要進(jìn)行同步操作,這里通過POSIX線程,進(jìn)行加鎖,實現(xiàn)對隊列的同步。

由于利用OpenSL ES進(jìn)行播放,在播放之前需要對OpenSL ES進(jìn)行初始化,在循環(huán)解碼原始數(shù)據(jù)幀的同時,進(jìn)行OpenSL ES初始化,并啟用回調(diào)函數(shù)。

對于播放的配置回調(diào)給出具體流程圖,如圖5所示。

通過接口對象的創(chuàng)建,設(shè)置播放數(shù)據(jù)類型為PCM數(shù)據(jù),16位量化位數(shù),雙聲道,立體聲與采樣率,播放狀態(tài)為播放,并設(shè)置播放回調(diào),監(jiān)測數(shù)據(jù)的傳遞。

由于音頻編碼格式多樣,需要對原始音頻幀AVPacket進(jìn)行重采樣,生成PCM數(shù)據(jù),采樣標(biāo)準(zhǔn)為,每秒采樣音頻個數(shù)44100 HZ,采樣位數(shù)16 bit,輸出聲道為雙聲道。

給出每個采樣點數(shù)據(jù)大小的計算公式:

size(數(shù)據(jù)長度) = 采樣個數(shù) * 聲道數(shù) * 單個采樣點大小

對于重采樣并實現(xiàn)播放的具體流程圖,如圖6所示。

從SafeQueue類的緩沖隊列中通過popAVPacket()函數(shù)獲得原始音頻數(shù)據(jù)AVPacket,通過avcodec_ send_packet()函數(shù)進(jìn)行解封裝,得到音頻幀,并將其保存在AVCodecContext中,通過avcodec_receive_frame()函數(shù)獲得音頻幀,利用swr_alloc_set_opts()函數(shù)設(shè)置轉(zhuǎn)碼后的PCM音頻數(shù)據(jù)參數(shù),最后通過swr_convert()函數(shù)從音頻幀中獲得轉(zhuǎn)碼后的一幀PCM數(shù)據(jù),這時OpenSL ES監(jiān)測到回調(diào),將PCM數(shù)據(jù)通過Enqueue()函數(shù)加入播放隊列,完成播放。

3? 對比MediaPlayer

3.1? 音頻數(shù)據(jù)加載時間對比

MediaPlayer的加載時間,與本文方案(AudioPlayer)加載時間(單位:秒)對比如表1所示。

經(jīng)過試驗測算,在對同一資源地址進(jìn)行播放時,AudioPlayer所需要的時間約為0.2 S,MediaPlayer所需的時間約為0.45 s。

3.2? 播放音頻時內(nèi)存增量對比

MediaPlayer與本文方案(AudioPlayer)的播放音頻時內(nèi)存的增量對比如圖7所示。

經(jīng)過試驗測算,在對同一資源地址進(jìn)行播放時,AudioPlayer所占用的內(nèi)存均值約為2.5 MB,MediaPlayer所占用的內(nèi)容存均值約為4.6 MB。

4? 結(jié)論

采用FFmpeg與OpenSL ES實現(xiàn)了對音頻數(shù)據(jù)的播放處理,提供了一個較好的解決方案。相比與MediaPlayer不僅提高了數(shù)據(jù)的加載效率,還減少了Java層和native層之間的數(shù)據(jù)拷貝,符合了手機性能的需求,提升了用戶的體驗性。

參考文獻(xiàn)

[1]王翠香, 邵星. 基于安卓的大學(xué)生掌上論壇系統(tǒng)設(shè)計[J]. 軟件, 2015, 36(10): 33-35.

[2]何艷江, 呂鵬, 顏溯, 等. 基于安卓平臺的復(fù)合地基處理軟件開發(fā)[J]. 軟件, 2015, 36(12): 42-44.

[3]姚永明, 梅雨凱, 章香, 等. 基于安卓的南郵通達(dá)掌上校園 APP 的需求分析[J]. 軟件, 2018, 39(8): 45-47.

[4]姚永明, 梅雨凱, 章香, 等. 基于安卓的南郵通達(dá)掌上校園 APP 的實現(xiàn)[J]. 軟件, 2018, 39(8): 48-51.

[5]張小琴, 張庚. 基于 Android 平臺的音樂播放器設(shè)計與實現(xiàn)[J]. 軟件, 2018, 39(9): 113-116.

[6]鄧正良. 基于FFmpeg和SDL的視頻流播放存儲研究綜述[J]. 現(xiàn)代計算機, 2019(22): 47-50.

[7]石佩青. 基于Android系統(tǒng)在線音樂播放器的設(shè)計與實現(xiàn)[D]. 北京郵電大學(xué), 2017.

[8]張希龍. 基于Android平臺的助聽器系統(tǒng)設(shè)計和實現(xiàn)[D]. 東南大學(xué), 2017.

[9]羅瀟. Android多媒體平臺下基于FFMPEG的音視頻處理方案研究[D]. 暨南大學(xué), 2016.

[10]Research and Implementation of Video Codec Based on FFmpeg. ZENG Hao, ZHANG Zhi-yong, SHI Lul-in. 2016 International Conference on Network and Information Systems for Computers. 2016.

主站蜘蛛池模板: 国产综合欧美| 狠狠干综合| 国产在线视频二区| 国产人成乱码视频免费观看| 午夜福利在线观看入口| 国产无码网站在线观看| 幺女国产一级毛片| 91精品国产91久久久久久三级| 精品国产电影久久九九| 免费不卡视频| 日韩天堂网| 国产日韩久久久久无码精品| 欧美啪啪一区| 亚洲最大福利视频网| 国产第三区| 中文字幕在线看| 一区二区三区毛片无码| 爱色欧美亚洲综合图区| 国产精品亚洲日韩AⅤ在线观看| 一本一道波多野结衣av黑人在线| 国产sm重味一区二区三区| 色哟哟精品无码网站在线播放视频| 亚洲综合色吧| AV老司机AV天堂| 国产精品无码AV中文| 欧美日韩导航| 亚洲成A人V欧美综合| 亚洲国产综合精品中文第一| 成人永久免费A∨一级在线播放| 欧美日韩午夜视频在线观看 | 亚洲首页在线观看| 精品一区二区三区自慰喷水| 欧美一区二区福利视频| 亚洲国产成熟视频在线多多| 国产大片喷水在线在线视频 | AV熟女乱| 亚洲三级成人| 国产国拍精品视频免费看 | 中文无码精品a∨在线观看| 日韩成人在线网站| 为你提供最新久久精品久久综合| 国产又黄又硬又粗| 亚洲男人的天堂在线| 国产亚洲精品97在线观看| 亚洲午夜福利在线| 国产丝袜第一页| 国产在线欧美| 国产二级毛片| 久久中文字幕2021精品| 国产成人精品综合| 就去吻亚洲精品国产欧美| 亚洲综合经典在线一区二区| 性69交片免费看| 亚瑟天堂久久一区二区影院| 国产欧美日韩另类精彩视频| 91蝌蚪视频在线观看| 国产成人三级在线观看视频| 色婷婷色丁香| 99精品免费在线| 91破解版在线亚洲| 真实国产乱子伦视频| 久久久久夜色精品波多野结衣| 亚洲欧美人成电影在线观看| 亚洲三级色| 色天堂无毒不卡| 亚洲一区二区成人| 久久免费视频6| 精品成人一区二区三区电影| 在线看免费无码av天堂的| 亚洲国产成熟视频在线多多 | 国产免费羞羞视频| 亚洲欧美国产高清va在线播放| 国产欧美另类| 91精品国产情侣高潮露脸| 精品免费在线视频| 激情無極限的亚洲一区免费| 成人国内精品久久久久影院| 青青青伊人色综合久久| 精品伊人久久久香线蕉| 午夜精品久久久久久久2023| 精品丝袜美腿国产一区| 婷婷伊人五月|