新聞中心

EEPW首頁 > 測試測量 > 設(shè)計應(yīng)用 > Android系統(tǒng)WMA文件播放功能的設(shè)計與實現(xiàn)

Android系統(tǒng)WMA文件播放功能的設(shè)計與實現(xiàn)

作者: 時間:2011-12-18 來源:網(wǎng)絡(luò) 收藏

文件開始有一個16 Byte的標(biāo)識,表示是:30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 62 CE 6C。如果音頻文件的前16個字符和這16 Byte相符,那么就可以判斷該文件為文件。WMAExtraetor中的SniffWMA函數(shù)就是通過讀取文件前16 Byte來判斷該文件是不是WMA文件。在SniffWMA函數(shù)中,如果判斷前16 Byte和WMA的16個標(biāo)識字節(jié)相等,就會把MEDIA_MIMETYPE_AUDIO_WMA給mimeType指針,標(biāo)志著該音頻文件類型為WMA格式。MEDIA_MIMETYPE_AUDIO_WMA是在MediaDefs.h文件中定義,在MediaDefs.cpp文件中賦值:
g.JPG
(2)WMA文件的解析。
WMAExtmetor從WMA文件的第31 Byte開始取16 Byte,然后依次和file_header、stream_header、data_header、comment_header、exten-ded_content_header對比,如果和file_header相等,則從下個Byte開始依次獲取文件大小、創(chuàng)建時間、數(shù)據(jù)包個數(shù)、…數(shù)據(jù)包大小。然后再從下個Byte開始讀取16 Byte再進(jìn)行對比,如果和extended_content_header相等,則可以從下個Byte中依次獲取名稱、藝術(shù)家、版權(quán)、注釋等非音頻信息。然后再接著讀取16 Byte進(jìn)行比對,直到和data_eader相等。data_header后就是音頻文件解碼數(shù)據(jù),data_header的結(jié)束位置就是第一個數(shù)據(jù)包在文件中的偏移量。WMAExtractor會創(chuàng)建一個MetaData,并把文件頭中獲取的sample_rate、Byte_rate、channels、dura-tion都存入MetaData中。在WMAExtractor的getMetaData函數(shù)中,把之前獲取的非音頻信息放入MetaData中,最后返回該MetaData。在WMAEx-tractor的getTrack函數(shù)中,創(chuàng)建一個WMASource,并把WMA數(shù)據(jù)和MetaData傳給WMASource。
(3)編碼數(shù)據(jù)的讀取。
獲取未解碼數(shù)據(jù)是通過WmASource的read函數(shù)讀取的。WMA數(shù)據(jù)是以數(shù)據(jù)包為單位的,同文件中的數(shù)據(jù)包大小相同。每個數(shù)據(jù)包中有多幀數(shù)據(jù),每個數(shù)據(jù)包的起始位置減去第—個數(shù)據(jù)包的起始位置再除以包的大小等于一個整數(shù),這個整數(shù)就是該數(shù)據(jù)包之前數(shù)據(jù)包的個數(shù)。每個數(shù)據(jù)包的第一個Byte一般都等于0x82。第二個Byte以后是該數(shù)據(jù)包的相關(guān)信息。根據(jù)包的相關(guān)數(shù)據(jù)就可以獲取該包中的未解碼數(shù)據(jù)。
WMASource的read讀取未解碼數(shù)據(jù)時,首先會判斷從WMADecoder傳來的options是否為空,如果不為空,并可以從options中獲取一個時間seekTimeUs,就通過seekTimeUs、總時間和總數(shù)據(jù)包的個數(shù)算出要數(shù)據(jù)包的起始位置,然后從該起始位置獲取一個數(shù)據(jù)包的數(shù)據(jù),并從該數(shù)據(jù)包中獲取有效數(shù)據(jù)的大小、起始位置、時間等數(shù)據(jù),最后把該有效數(shù)據(jù)和時間放在WMADecoder傳來的Buffer里。
WMASource的Read被調(diào)用時,如果傳來的Options為空或是不能從Options中獲取時間seekTimeUs,就會從WMA文件中讀取一個數(shù)據(jù)包,根據(jù)其中的有效數(shù)據(jù)的大小、起始位置獲取有效數(shù)據(jù),并獲取該數(shù)據(jù)包中的時間,然后把該有效數(shù)據(jù)和時間放在WMADecoder傳來的buffer里。第一個數(shù)據(jù)包的起始位置就是解析頭文件時獲取的第一個數(shù)據(jù)包的偏移量,所以第一次調(diào)用WMASource的read時,就是從這個偏移量的下個位置讀取第一個數(shù)據(jù)包的。在WMASource中有一個專門記錄讀取位置的指針。每次讀取1個數(shù)據(jù)包后,該指針就會指向數(shù)據(jù)包末尾的下一個位置,當(dāng)下一次WMASource的read讀取未解碼數(shù)據(jù)時,如果不是音樂定點播放,就會從該指針?biāo)傅奈恢瞄_始讀取數(shù)據(jù)包。

本文引用地址:http://butianyuan.cn/article/194616.htm

(4)編碼數(shù)據(jù)的解碼和輸出。
AwesomePlayer通過OMXCodec中的Create函數(shù)創(chuàng)建WMADecoder,所以在OMXCodec中注冊WMADecoder的相關(guān)信息:
h.JPG
在創(chuàng)建WMADecoder時,把之前創(chuàng)建的WMASource傳給WMADecoder。在WMADecoder構(gòu)造函數(shù)中,WMADecoder從WMASource中獲取Metadata,并從Metadata獲取sampleRate、numChannels、duration等。在WMADecoder的start函數(shù)中,通過調(diào)用avcodec_open函數(shù),來分配解碼所需的空間、創(chuàng)建并初始化解碼所需的相關(guān)參數(shù)。在WMADecoder析構(gòu)函數(shù)中會調(diào)用WMADecoder的Stop函數(shù)。在Stop函數(shù)中會釋放所有相關(guān)空間。

c++相關(guān)文章:c++教程




關(guān)鍵詞: Android WMA 系統(tǒng) 播放

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉