溫馨提示×

溫馨提示×

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

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

Android音視頻開發(fā)之MediaExtactor怎么使用

發(fā)布時間:2022-04-27 09:23:38 來源:億速云 閱讀:143 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“Android音視頻開發(fā)之MediaExtactor怎么使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Android音視頻開發(fā)之MediaExtactor怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

MediaExtactor

MediaExtactorAndroid音視頻開發(fā)中負(fù)責(zé)提取音視頻信息和數(shù)據(jù)流的功能,可以通過該類實現(xiàn)從多媒體文件中剝離得到音頻和視頻的能力。

使用MediaExtactor

在一個音視頻文件多可能會包含多個數(shù)據(jù)流(音頻數(shù)據(jù)、視頻數(shù)據(jù)等一般情況是一個視頻組合多個音頻)

  • 因此需要MediaExtactor加載音視頻文件獲取到所有數(shù)據(jù)軌道

  • 通過遍歷獲取到想要操作的軌道

  • 然后指定該軌道是MediaExtactor所有解析的數(shù)據(jù)流

  • 通過MediaExtactor獲取到該軌道MediaFormat

加載音視頻文件代碼

加載音視頻文件過程可傳遞Uripath、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);

獲取軌道代碼

加載文件之后可以通過MediaExtactorgetTrackCount方法獲取到所有數(shù)據(jù)軌道。然后可以通過getTrackFormat獲取到軌道信息,通過MediaFormat.KEY_MIME得到軌道格式比對期望所有獲取到的軌道,比如比對"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)前選擇軌道的基本信息,例如視頻尺寸大小、格式、時長、碼率等一些音視頻相關(guān)基礎(chǔ)信息方便只有做解碼時選用合適的解碼器以及其他必要信息確認(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);

但如果你選取的軌道是視頻軌道但操作錯誤提取了音頻相關(guān)信息可能會出現(xiàn)錯誤崩潰的情況(例如KEY_IS_ADTS 只有音頻軌道才能提?。?,因此盡量保證提取參數(shù)是否正確做好代碼保護機制。

一些源碼細(xì)節(jié)分析

MediaExtactor作為提取器,其底層代碼邏輯也是調(diào)用JNI來實現(xiàn)的,它只是上層API提供出能力而已。 在源碼細(xì)節(jié)中可以看到MediaExtactor同樣是加載media_jniso庫,這和MediaPlayer是一樣的邏輯。

public MediaExtractor() {
    native_setup();
}
private native final void native_setup();
static {
    System.loadLibrary("media_jni");
    native_init();
}

同時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;

這基本也能夠了解MediaExtactorMediaPlayer在底層實現(xiàn)上應(yīng)該屬于同一套邏輯和功能。只不過MediaExtactor可以理解為MediaPlayer其中一小部分功能提供提取能力而MediaPlayer是封裝成型的工具類只需要加載音視頻資源文件播放即可,中間提取軌道和解析過程直接就在底層幫開發(fā)者實現(xiàn)了。

讀到這里,這篇“Android音視頻開發(fā)之MediaExtactor怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI