Android音視頻開發(fā)之MediaExtactor使用教程
前言
在之前學(xué)習(xí)如何使用MediaPlayer后,了解到Android系統(tǒng)提供開發(fā)者播放多媒體全家桶能力,但對(duì)于開發(fā)者希望DIY自由度更高的播放器能力也是可以利用Android內(nèi)部提供組件包自行實(shí)現(xiàn)一個(gè)播放器的。舉例實(shí)現(xiàn)一個(gè)視頻播放這個(gè)流程,它大致流程是【多媒體文件解析提取視頻文件】-> 【視頻流解碼】-> 【解碼數(shù)據(jù)播放渲染到Render】。首要需要實(shí)現(xiàn)的是多媒體中需要文件提取工作,這就需要使用到Android提供MediaExtactor
類來實(shí)現(xiàn)提取媒體信息能力。
MediaExtactor
MediaExtactor
在Android
音視頻開發(fā)中負(fù)責(zé)提取音視頻信息和數(shù)據(jù)流的功能,可以通過該類實(shí)現(xiàn)從多媒體文件中剝離得到音頻和視頻的能力。
使用MediaExtactor
在一個(gè)音視頻文件多可能會(huì)包含多個(gè)數(shù)據(jù)流(音頻數(shù)據(jù)、視頻數(shù)據(jù)等一般情況是一個(gè)視頻組合多個(gè)音頻)
- 因此需要
MediaExtactor
加載音視頻文件獲取到所有數(shù)據(jù)軌道 - 通過遍歷獲取到想要操作的軌道
- 然后指定該軌道是
MediaExtactor
所有解析的數(shù)據(jù)流 - 通過
MediaExtactor
獲取到該軌道MediaFormat
加載音視頻文件代碼
加載音視頻文件過程可傳遞Uri
、path
、URL
等。在確認(rèn)希望需要解析的數(shù)據(jù)軌道后調(diào)用selectTrack
就能鎖定當(dāng)前MediaExtactor
要使用的軌道在之后數(shù)據(jù)解碼中去使用。
// 加載資源 MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(path); // 遍歷獲取視頻軌道 int trackIndex = getTrackIndex(extractor, "audio/"); // 選定軌道 extractor.selectTrack(trackIndex);
獲取軌道代碼
加載文件之后可以通過MediaExtactor
的getTrackCount
方法獲取到所有數(shù)據(jù)軌道。然后可以通過getTrackFormat
獲取到軌道信息,通過MediaFormat.KEY_MIME
得到軌道格式比對(duì)期望所有獲取到的軌道,比如比對(duì)"audio/"
就是希望獲取到音頻軌道數(shù)據(jù)。
// 獲取指定軌道的方法 private static int getTrackIndex(MediaExtractor extractor, String mediaType) { int trackIndex = -1; for (int i = 0; i < extractor.getTrackCount(); i++) { MediaFormat mediaFormat = extractor.getTrackFormat(i); String mime = mediaFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith(mediaType)) { trackIndex = i; break; } } return trackIndex; }
提取軌道數(shù)據(jù)信息
在選定希望獲取到的軌道后就可以獲取到當(dāng)前選擇軌道的基本信息,例如視頻尺寸大小、格式、時(shí)長(zhǎng)、碼率等一些音視頻相關(guān)基礎(chǔ)信息方便只有做解碼時(shí)選用合適的解碼器以及其他必要信息確認(rèn)。
音頻軌道基礎(chǔ)信息獲取
MediaFormatInfo mediaFormatInfo = new MediaFormatInfo(); mediaFormatInfo.mediaFormat = mediaFormat; mediaFormatInfo.audioChannels = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT); mediaFormatInfo.audioSampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); mediaFormatInfo.maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE); mediaFormatInfo.mime = mediaFormat.getString(MediaFormat.KEY_MIME);
視頻軌道基礎(chǔ)信息獲取
MediaFormatInfo mediaFormatInfo = new MediaFormatInfo(); mediaFormatInfo.mediaFormat = mediaFormat; mediaFormatInfo.videoHeight = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT); mediaFormatInfo.videoWidth = mediaFormat.getInteger(MediaFormat.KEY_WIDTH); mediaFormatInfo.timeDuration = mediaFormat.getLong(MediaFormat.KEY_DURATION); mediaFormatInfo.mime = mediaFormat.getString(MediaFormat.KEY_MIME);
但如果你選取的軌道是視頻軌道但操作錯(cuò)誤提取了音頻相關(guān)信息可能會(huì)出現(xiàn)錯(cuò)誤崩潰的情況(例如KEY_IS_ADTS
只有音頻軌道才能提?。?,因此盡量保證提取參數(shù)是否正確做好代碼保護(hù)機(jī)制。
一些源碼細(xì)節(jié)分析
MediaExtactor
作為提取器,其底層代碼邏輯也是調(diào)用JNI來實(shí)現(xiàn)的,它只是上層API提供出能力而已。 在源碼細(xì)節(jié)中可以看到MediaExtactor
同樣是加載media_jni
so庫(kù),這和MediaPlayer
是一樣的邏輯。
public MediaExtractor() { native_setup(); } private native final void native_setup(); static { System.loadLibrary("media_jni"); native_init(); }
同時(shí)setDataSoure
方法調(diào)用底層native
接口和MediaPlayer
也是同樣的方法名和入?yún)ⅰ?/p>
private native final void nativeSetDataSource( @NonNull IBinder httpServiceBinder, @NonNull String path, @Nullable String[] keys, @Nullable String[] values) throws IOException;
這基本也能夠了解MediaExtactor
和MediaPlayer
在底層實(shí)現(xiàn)上應(yīng)該屬于同一套邏輯和功能。只不過MediaExtactor
可以理解為MediaPlayer
其中一小部分功能提供提取能力而MediaPlayer
是封裝成型的工具類只需要加載音視頻資源文件播放即可,中間提取軌道和解析過程直接就在底層幫開發(fā)者實(shí)現(xiàn)了。
到此這篇關(guān)于Android音視頻開發(fā)之MediaExtactor使用教程的文章就介紹到這了,更多相關(guān)Android MediaExtactor內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)apk插件方式換膚的實(shí)例講解
在本篇文章里小編給大家整理的是關(guān)于Android實(shí)現(xiàn)apk插件方式換膚的實(shí)例代碼以及相關(guān)知識(shí)點(diǎn),有需要的朋友們學(xué)習(xí)下。2019-10-10Flutter開發(fā)之支持放大鏡的輸入框功能實(shí)現(xiàn)
在Flutter開發(fā)時(shí),有時(shí)為了優(yōu)化用戶輸入體驗(yàn),往往會(huì)需要輸入框支持在移動(dòng)光標(biāo)過程中可以出現(xiàn)放大鏡功能。本文將為大家介紹實(shí)現(xiàn)的方法,需要的可以參考一下2022-02-02Kotlin Flow封裝類SharedFlow StateFlow LiveData使用
這篇文章主要為大家介紹了Kotlin Flow封裝類SharedFlow StateFlow LiveData使用對(duì)比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Android開發(fā)中調(diào)用系統(tǒng)相冊(cè)上傳圖片到服務(wù)器OPPO等部分手機(jī)上出現(xiàn)短暫的顯示桌面問題的解決方法
這篇文章主要介紹了Android開發(fā)中調(diào)用系統(tǒng)相冊(cè)上傳圖片到服務(wù)器OPPO等部分手機(jī)上出現(xiàn)短暫的顯示桌面問題的解決方法,需要的朋友可以參考下2016-12-12Android使用WebView實(shí)現(xiàn)截圖分享功能
這篇文章主要為大家詳細(xì)介紹了Android使用WebView實(shí)現(xiàn)截圖分享功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Flutter 實(shí)現(xiàn)網(wǎng)易云音樂字幕的代碼
這篇文章主要介紹了Flutter 實(shí)現(xiàn)網(wǎng)易云音樂字幕的代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04Android自定義View實(shí)現(xiàn)粉碎的面具效果
這篇文章主要給大家介紹了關(guān)于Android自定義View實(shí)現(xiàn)粉碎的面具效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08Android編程開發(fā)之TextView控件用法(2種方法)
這篇文章主要介紹了Android編程開發(fā)之TextView控件用法,結(jié)合實(shí)例分析了Android針對(duì)TextView控件固定顯示與動(dòng)態(tài)獲取顯示的兩種使用技巧,需要的朋友可以參考下2015-12-12