使用ExoPlayer播放res/raw中音頻資源

前言

關(guān)于ExoPlayer的使用,很多前人已經(jīng)幫我們翻譯了官方文檔,例如ExoPlayer使用,這里不再闡述。
但是上述文章一般就是將官方文檔翻譯一下,針對(duì)具體的使用,可能會(huì)遇到很多難以解決問(wèn)題。

正文

某天,我想用ExoPlayer播放一段存放在res/raw文件夾下的ogg格式的音頻,在之前代碼中,使用Mediaplayer播放,一切正常。
但是,有了高逼格的ExoPlayer,肯定要放棄Mediaplayer啊,畢竟程序員都是喜新厭舊的嘛(手動(dòng)滑稽)。所以,那就根據(jù)官方API開(kāi)整,這里就放核心代碼

        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        TrackSelection.Factory selectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        TrackSelector trackSelector = new DefaultTrackSelector(selectionFactory);
        currentPlayer = ExoPlayerFactory.newSimpleInstance(this.context, trackSelector);
        DataSource.Factory dataSourceFactory = buildDataSourceFactory(this.context, bandwidthMeter);
        ExtractorMediaSource mediaSource = new ExtractorMediaSource(FmManager.getUriById(context, resId),
                dataSourceFactory, new DefaultExtractorsFactory(), null, null);
        LoopingMediaSource loopingMediaSource = new LoopingMediaSource(mediaSource);  //循環(huán)播放
        currentPlayer.prepare(loopingMediaSource);
        currentPlayer.addListener(this);
        currentPlayer.setPlayWhenReady(true);  


    private DataSource.Factory buildDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) {
        return new DefaultDataSourceFactory(context,
                Util.getUserAgent(context, context.getString(R.string.app_name)), bandwidthMeter);
    }

    //根據(jù)raw資源ID獲取URI
    public static Uri getUriById(Context context, int rawId) {
        String basePath = "android.resource://";
        StringBuilder stringBuilder = new StringBuilder(basePath);
        String uriStr = stringBuilder.append(context.getPackageName()).append("/").append(rawId).toString();
        return Uri.parse(uriStr);
    }

代碼基本是根據(jù)官方Demo提供的,一運(yùn)行,哎喲,報(bào)錯(cuò)了:

com.google.android.exoplayer.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to android.resource://```
納尼?報(bào)資源找不到,可是獲取Uri的方法沒(méi)錯(cuò)啊,打開(kāi)Chrome,上Google,不搜不要緊,一搜好多人都遇到這個(gè)問(wèn)題,看來(lái)代碼沒(méi)寫錯(cuò),那就一個(gè)個(gè)帖子找吧。
找來(lái)找去,大家的解決辦法竟然是將raw中音頻資源放到assets目錄下,這真是沒(méi)辦法的辦法,但是轉(zhuǎn)念一想,Google不至于這么坑爹吧,難道放在raw中的資源就無(wú)法使用了么?
打開(kāi)官方文檔(http://google.github.io/ExoPlayer/doc/reference/)

![看構(gòu)造函數(shù)名字](http://upload-images.jianshu.io/upload_images/2789715-07eda3215111e0ff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

這里肯定是和raw資源有關(guān),繼續(xù)往下看

![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2789715-4e391f5c11cbae3a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

1.使用buildRawResourceUri(int rawResourceId)傳入資源ID,得到Uri

public static Uri buildRawResourceUri(int rawResourceId)
Builds a Uri for the specified raw resource identifier.```
2.使用DataSpec(Uri uri),得到DataSpec對(duì)象,

DataSpec(Uri uri)
Construct a DataSpec for the given uri and with key set to null.```
3.創(chuàng)建RawResourceDataSource對(duì)象,最后使用 open(DataSpec dataSpec)打開(kāi)之前的DataSpec對(duì)象

public long open(DataSpec dataSpec)
throws RawResourceDataSource.RawResourceDataSourceException
Description copied from interface: DataSource
Opens the source to read the specified data. ```
4.使用RawResourceDataSource的getUri();得到Uri

public Uri getUri()
Description copied from interface: DataSource
When the source is open, returns the Uri from which data is being read. The returned Uri will be identical to the one passed DataSource.open(DataSpec) in the DataSpec unless redirection has occurred. If redirection has occurred, the Uri after redirection is returned.```

那就修改根據(jù)資源ID獲取Uri的方法,完整代碼如下:
    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory selectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(selectionFactory);
    currentPlayer = ExoPlayerFactory.newSimpleInstance(this.context, trackSelector);
    try {
        DataSpec dataSpec = new DataSpec(RawResourceDataSource.buildRawResourceUri(this.resId));
        RawResourceDataSource rawResourceDataSource = new RawResourceDataSource(context);
        rawResourceDataSource.open(dataSpec);
        DataSource.Factory factory = () -> rawResourceDataSource;

        ExtractorMediaSource mediaSource = new ExtractorMediaSource(rawResourceDataSource.getUri(),
                factory, new DefaultExtractorsFactory(), null, null);
        LoopingMediaSource loopingMediaSource = new LoopingMediaSource(mediaSource);
        currentPlayer.prepare(loopingMediaSource);
        currentPlayer.addListener(this);
        currentPlayer.setPlayWhenReady(true);
    } catch (RawResourceDataSource.RawResourceDataSourceException e) {
        e.printStackTrace();
    }
重新編譯運(yùn)行,ok,順利播放,看來(lái)還是官方靠譜

----------------
####總結(jié)
針對(duì)ExoPlayer播放raw中資源,不同于Mediaplayer方式,需要通過(guò)下列代碼獲取Uri,才能成功
        DataSpec dataSpec = new DataSpec(RawResourceDataSource.buildRawResourceUri(this.resId));
        RawResourceDataSource rawResourceDataSource = new RawResourceDataSource(context);
        rawResourceDataSource.open(dataSpec);
        rawResourceDataSource.getUri()```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程,因...
    小菜c閱讀 7,330評(píng)論 0 17
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,036評(píng)論 25 709
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 關(guān)鍵詞:對(duì)立面題主:女問(wèn):感謝冷愛(ài),關(guān)注冷愛(ài)有半年,學(xué)藝未精,目前有非常大的困擾,無(wú)法自己解答,所以麻煩冷愛(ài)能夠給...
    冷愛(ài)閱讀 1,764評(píng)論 0 0
  • 看完張小嫻的《想念》,我在想,有時(shí)候作為高級(jí)動(dòng)物的人類對(duì)于愛(ài)情的堅(jiān)貞有時(shí)竟不及一個(gè)動(dòng)物對(duì)于自己配偶的忠誠(chéng)相依,即便...
    小緣兒閱讀 351評(píng)論 0 0

友情鏈接更多精彩內(nèi)容