亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

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

        2020-12-23 05:47:19王強(qiáng)洪蕾
        軟件 2020年10期
        關(guān)鍵詞:解碼

        王強(qiáng) 洪蕾

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

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

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

        本文著錄格式:王強(qiáng),洪蕾. 基于Android平臺(tái)的音頻播放處理研究與實(shí)現(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è)備的普及,讓人們對(duì)安卓應(yīng)用的體驗(yàn)有著越來(lái)越高的需求。音頻的處理包含著許多方面,如音樂(lè)播放[5],音頻錄制等。手機(jī)性能的局限導(dǎo)致對(duì)安卓應(yīng)用在控制性能消耗有著高的需求,所以開(kāi)發(fā)人員在完成音頻應(yīng)用開(kāi)發(fā)的時(shí)候選擇一個(gè)合適的方案是必要的。

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

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

        1.1? FFmpeg

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

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

        1.2? OpenSL ES

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

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

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

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

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

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

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

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

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

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

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

        2.2? 方案設(shè)計(jì)

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

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

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

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

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

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

        給出每個(gè)采樣點(diǎn)數(shù)據(jù)大小的計(jì)算公式:

        size(數(shù)據(jù)長(zhǎng)度) = 采樣個(gè)數(shù) * 聲道數(shù) * 單個(gè)采樣點(diǎn)大小

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

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

        3? 對(duì)比MediaPlayer

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

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

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

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

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

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

        4? 結(jié)論

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

        參考文獻(xiàn)

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

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

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

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

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

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

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

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

        [9]羅瀟. Android多媒體平臺(tái)下基于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.

        猜你喜歡
        解碼
        《解碼萬(wàn)噸站》
        《解碼萬(wàn)噸站》
        《解碼萬(wàn)噸站》
        解碼eUCP2.0
        NAD C368解碼/放大器一體機(jī)
        Quad(國(guó)都)Vena解碼/放大器一體機(jī)
        日韩有码在线观看视频| 在线永久看片免费的视频| 亚洲AV无码国产永久播放蜜芽| 99在线国产视频| 搞黄色很刺激的网站二区| 国产精品成人av大片| 久久精品国产字幕高潮| 国产精品_国产精品_k频道| Y111111国产精品久久久| 水蜜桃在线视频在线观看| 精品人妻码一区二区三区红楼视频 | 加勒比hezyo黑人专区| 亚洲成av人片在线观看ww| 99久久人妻无码精品系列蜜桃| 国产高清亚洲精品视频| 国产老熟女伦老熟妇露脸| 欧美a级在线现免费观看| 亚洲av无码av制服另类专区| 伊人久久大香线蕉在观看| 国产精品国产三级国产一地| 九七青青草视频在线观看| 亚洲av成人无码一二三在线观看| 最近最新中文字幕| 99久久国产亚洲综合精品| 午夜亚洲精品一区二区| 日韩亚洲精品国产第二页| 亚欧免费无码aⅴ在线观看| 亚洲av色先锋资源电影网站 | 国产成人亚洲合色婷婷| 日本一本一道久久香蕉男人的天堂 | 日本人妖一区二区三区| 一本一道久久综合久久| 亚洲日韩av无码一区二区三区人| 成人免费毛片内射美女-百度| 亚洲成a人片在线观看高清| 精品高清一区二区三区人妖| 国产精品久久久久久av| 天堂а√在线中文在线新版| 禁止免费无码网站| 少妇人妻偷人精品一区二区| 国产女人体一区二区三区|