如何初始化 exoplayer 以播放 dash(.mpd) 视频

How to initialise exoplayer to play dash(.mpd) videos

我有 dash 视频的播放列表,这是我在 2.7.3 版本时用来播放媒体的代码。现在我已经更新到2.9.5,我遇到了问题。

我的 init 和 mediasource 方法:

private void initializePlayer() {
       if (player == null) {
  // a factory to create an AdaptiveVideoTrackSelection
  TrackSelection.Factory adaptiveTrackSelectionFactory =
          new AdaptiveTrackSelection.Factory(BANDWIDTH_METER);

  player = ExoPlayerFactory.newSimpleInstance(
          new DefaultRenderersFactory(this),
          new DefaultTrackSelector(adaptiveTrackSelectionFactory),
          new DefaultLoadControl());
  player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this),
          new DefaultTrackSelector(), new DefaultLoadControl());
  playerView.setPlayer(player);
  player.addListener(new PlayerEventListener());
        /*player.setPlayWhenReady(playWhenReady);
        player.seekTo(currentWindow, playbackPosition);*/
}

playListMediaSources = buildPlayListMediaSource(serialURLs);

concatenatingMediaSource = new ConcatenatingMediaSource(playListMediaSources);

player.prepare(concatenatingMediaSource, true, false);
player.setPlayWhenReady(playWhenReady);
player.seekTo(currentWindow, playbackPosition);
    }



private MediaSource buildMediaSource(Uri uri) {

  /*  DefaultExtractorsFactory defaultExtractorsFactory = new DefaultExtractorsFactory();
    DefaultHttpDataSourceFactory defaultHttpDataSourceFactory = new DefaultHttpDataSourceFactory("user-agent");*/

        DataSource.Factory manifestDataSourceFactory =
                new DefaultHttpDataSourceFactory("ua");
        DashChunkSource.Factory dashChunkSourceFactory =
                new DefaultDashChunkSource.Factory(
                        new DefaultHttpDataSourceFactory("ua", BANDWIDTH_METER));
        return new DashMediaSource.Factory(dashChunkSourceFactory,
                manifestDataSourceFactory).createMediaSource(uri);
    }


    private MediaSource[] buildPlayListMediaSource(String[] serialURLs) {


        MediaSource[] mediaSources = new MediaSource[serialURLs.length];
        Uri uri;
        for (int i = 0; i < serialURLs.length; i++) {
            uri = Uri.parse(serialURLs[i]);
            mediaSources[i] = buildMediaSource(uri);
        }
        return mediaSources;
    }

我将初始化代码修改为:

 private void initializePlayer() {
        if (player == null) {

            TrackSelection.Factory adaptiveTrackSelectionFactory = new AdaptiveTrackSelection.Factory();

           player = ExoPlayerFactory.newSimpleInstance(this,
                    new DefaultRenderersFactory(this),
                    new DefaultTrackSelector(adaptiveTrackSelectionFactory),
                    new DefaultLoadControl());
            player = ExoPlayerFactory.newSimpleInstance(this,new DefaultRenderersFactory(this),
                    new DefaultTrackSelector(), new DefaultLoadControl());


        }


            if (serialURLs != null) {

                playListMediaSources = buildPlayListMediaSource(serialURLs);
                concatenatingMediaSource = new ConcatenatingMediaSource(playListMediaSources);
                player.prepare(concatenatingMediaSource, true, false);
                player.setPlayWhenReady(playWhenReady);
                player.seekTo(currentWindow, playbackPosition);
    }
    }

但是视频播放失败。我的猜测是我也必须对媒体源方法进行一些更改,但我无法弄清楚这些更改。使用我当前的代码,日志显示以下错误:

E/AndroidRuntime: FATAL EXCEPTION: ExoPlayerImplInternal:Handler
    Process: com.packagename, PID: 2731
    java.lang.AbstractMethodError: abstract method "void com.google.android.exoplayer2.source.BaseMediaSource.prepareSourceInternal(com.google.android.exoplayer2.upstream.TransferListener)"
        at com.google.android.exoplayer2.source.BaseMediaSource.prepareSource(BaseMediaSource.java:140)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.prepareInternal(ExoPlayerImplInternal.java:398)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:285)
        at android.os.Handler.dispatchMessage(Handler.java:101)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)

我添加这段文字主要是为了避免代码错误。任何帮助表示赞赏。提前致谢。

com.google.android.exoplayer:exoplayer-corecom.google.android.exoplayer:exoplayer-dash 需要在您的 build.gradle 中使用相同的版本。

implementation 'com.google.android.exoplayer:exoplayer-core:2.9.6'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.9.6'

最后我解决了这个问题:

private void initializePlayer() {
        if (player == null) {

            TrackSelection.Factory adaptiveTrackSelection = new AdaptiveTrackSelection.Factory();
            TrackSelector trackSelector = new DefaultTrackSelector(adaptiveTrackSelection);

            DefaultLoadControl loadControl = new DefaultLoadControl.Builder().setBufferDurationsMs(64*1024, 128*1024, 1024, 1024).createDefaultLoadControl();
            //LoadControl loadControl = new DefaultLoadControl();
            //  HttpDataSource.Factory factory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Exo2"));
            player = ExoPlayerFactory.newSimpleInstance(this,new DefaultRenderersFactory(this), trackSelector, loadControl);
            playerView.setPlayer(player);
            player.addListener(new PlayerEventListener());

        }

        if (isPlaylist) {
            if (serialURLs != null) {

                nextBtn.setVisibility(View.VISIBLE);

                playListMediaSources = buildPlayListMediaSource(serialURLs);

                concatenatingMediaSource = new ConcatenatingMediaSource(playListMediaSources);
                readLastSeen(contentName, isWebSeries);
                player.prepare(concatenatingMediaSource, true, false);
                player.setPlayWhenReady(playWhenReady);
                player.seekTo(currentWindow, playbackPosition);
            } else {
                // previousBtn.setVisibility(View.GONE);
                //nextBtn.setVisibility(View.GONE);
                Uri uri = Uri.parse(getString(R.string.sample_video));  
                mediaSource = buildMediaSource(uri);

                Toast.makeText(MediaPlayerActivity.this, "Playing sample video..", Toast.LENGTH_LONG).show();
                player.prepare(mediaSource, true, false);
                player.setPlayWhenReady(playWhenReady);
                player.seekTo(playbackPosition);
            }
        } else {
            if (videoURL != null) {

                Uri uri = Uri.parse(videoURL); 
                mediaSource = buildMediaSource(uri);


            } 
            player.prepare(mediaSource, true, false);
            player.setPlayWhenReady(playWhenReady);
            player.seekTo(playbackPosition);
        }



    }



private MediaSource buildMediaSource(Uri uri) {


DataSource.Factory dataSourceFactory =
                new DefaultDataSourceFactory(MediaPlayerActivity.this, "ua");

        return  new DashMediaSource.Factory(dataSourceFactory)
                .createMediaSource(uri);


    }

这些是我的依赖项:

implementation 'com.google.android.exoplayer:exoplayer-core:2.10.0'
    implementation 'com.google.android.exoplayer:exoplayer-dash:2.10.0'
    implementation 'com.google.android.exoplayer:extension-mediasession:2.8.4'
    implementation 'com.google.android.exoplayer:exoplayer-ui:2.8.+'
    implementation 'com.google.android.exoplayer:exoplayer:r2.4.0'