41

我正在尝试一个接一个地以播放列表的形式播放视频。我正在使用 android Exoplayer 播放我的文件,但 mediaplayer 中没有侦听器来收听媒体文件的结尾。有没有办法使用 exoplayer 收听媒体文件的结尾。

4

11 回答 11

53

我知道这很旧,但只是为了扩展已接受的答案:

exoPlayer.addListener(this);

.....

@Override
public void onPlayerStateChanged(boolean playWhenReady, int state) {

    if (state == ExoPlayer.STATE_ENDED){
        //player back ended
    }
}
于 2016-02-11T00:26:00.343 回答
37

Exoplayer 提供媒体播放器不提供的高级实现。

在Android的Exoplayer的高级示例中,他们在FullPlayerActivity.java中实现了onStateChanged,它提供了STATE_ENDED

您可以从本页右侧部分的相关样本项下下载示例

于 2014-12-08T05:35:08.313 回答
25

Google 已弃用ExoPlayer.STATE_ENDED并已替换为Player.STATE_ENDED.

由于这篇文章已经有一段时间了,我将Kotlin在下面写一个监听器的版本。

this.simpleExoPlayer?.addListener(object : Player.DefaultEventListener() {
    override fun onPlayerStateChanged(playWhenReady: Boolean,playbackState: Int) {
        when (playbackState) {
            Player.STATE_IDLE -> {}
            Player.STATE_BUFFERING -> {}
            Player.STATE_READY -> {}
            Player.STATE_ENDED -> {}
        }
    }
})

更新:05-2020 自从DefaultEventListeneronPlayerStateChanged()已弃用。

player.addListener(object : Player.EventListener {
     override fun onPlaybackStateChanged(state: Int) {
           if (state == Player.STATE_ENDED) {
              // your code
           }
     }
})
于 2018-03-16T08:22:54.817 回答
12

你可以这样做:

playerExo.addListener(new ExoPlayer.Listener() {

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

                switch(playbackState) {
                    case ExoPlayer.STATE_BUFFERING:
                        break;
                    case ExoPlayer.STATE_ENDED:
                        //do what you want
                        break;
                    case ExoPlayer.STATE_IDLE:
                        break;
                    case ExoPlayer.STATE_PREPARING:
                        break;
                    case ExoPlayer.STATE_READY:
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onPlayWhenReadyCommitted() {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }
        });
        playerExo.seekTo(0);
        playerExo.setPlayWhenReady(true);

但是@Murtaza Khursheed Hussain 的回答是正确的!有一个愉快的代码日!让我知道您是否需要其他东西!

于 2017-06-20T13:30:20.600 回答
11

您必须实现接口Player.EventLister并添加到您的 exoPlayer。

只需在onPlayerStateChanged方法上编写代码即可。查看代码。

exoPlayer.addListener( new Player.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {

            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

            }

            @Override
            public void onLoadingChanged(boolean isLoading) {

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

                switch(playbackState) {
                    case Player.STATE_BUFFERING:
                        break;
                    case Player.STATE_ENDED:
                        //Here you do what you want
                        break;
                    case Player.STATE_IDLE:
                        break;
                    case Player.STATE_READY:
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onRepeatModeChanged(int repeatMode) {

            }

            @Override
            public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }

            @Override
            public void onPositionDiscontinuity(int reason) {

            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

            }

            @Override
            public void onSeekProcessed() {

            }


        });
于 2018-08-31T12:20:03.687 回答
4

对于未连接的 MediaSource(代表您要播放的任何单独的媒体),当该媒体完成播放时,您将收到STATE_ENDED

对于 ConcatenatingMediaSource,它会在整个串联播放完成时发生(即您已经播放到串联中最后一个项目的末尾)。因此,当整个 MediaSource 播放完毕时会发生 STATE_ENDED。

对于 ConcatenatingMediaSource,检测当前媒体结束和下一个媒体播放开始的最佳回调是“onPositionDiscontinuity” 您应该使用onPositionDiscontinuity()来确定何时发生转换。请注意,在其他一些情况下也会调用 onPositionDiscontinuity,但您可以调用getCurrentWindowIndex()并将其与您认为您所在的窗口进行比较以确定是否发生了转换。您可以执行以下操作:

public void onPositionDiscontinuity() {
  int newIndex = player.getCurrentWindowIndex();
  if (newIndex != currentIndex) {
    // The index has changed ==> last media has ended and next media playback is started.
    currentIndex = newIndex;
  }
}

请注意:除非我们明确调用 player.seekTo(position,0),否则不会为播放列表中的第一项调用 onPositionDiscontinuity()。因此,要处理您为播放列表中的所有媒体播放所做的任何事情,您必须单独处理播放列表中的第一项。

于 2019-09-09T06:35:49.233 回答
4

Google 已弃用 ExoPlayer.STATE_ENDED。请改用 Player.STATE_ENDED。请参阅下面的代码。

player.addListener(new Player.EventListener() {
    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {


    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

        if (playWhenReady && playbackState == Player.STATE_READY) {
            // Active playback.
        } else if (playbackState == Player.STATE_ENDED) {
            //The player finished playing all media

           //Add your code here

        } else if (playWhenReady) {
            // Not playing because playback ended, the player is buffering, stopped or
            // failed. Check playbackState and player.getPlaybackError for details.
        } else {
            // Paused by app.
        }

    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {

    }

    @Override
    public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {

    }

    @Override
    public void onPositionDiscontinuity(int reason) {
        //THIS METHOD GETS CALLED FOR EVERY NEW SOURCE THAT IS PLAYED
      //  int latestWindowIndex = player.getCurrentWindowIndex();


    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

    }

    @Override
    public void onSeekProcessed() {

    }
});

您可以查看ExoPlayer 开发者页面了解更多信息。

于 2019-09-07T11:22:36.447 回答
2

ExoPlayer.STATE_ENDED 已折旧。请改用 Player.STATE_ENDED。例子:

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    if(playbackState == Player.STATE_ENDED){
        // your brain put here
    }
}
于 2017-12-28T03:06:50.730 回答
1

因为DefaultEventListeneronPlayerStateChanged()已被弃用。

使用Player.EventListeneronPlaybackStateChanged()

科特林代码

 player!!.addListener(object : Player.EventListener {
            override fun onPlaybackStateChanged(state: Int) {
                if (state == Player.STATE_ENDED) {
                    // your code here
                }
            }
        })
于 2021-05-25T04:37:25.043 回答
1

我正在使用带有 exoplayer 的播放列表,我想在它完成后停止媒体。

对我来说,当我在里面播放列表结束时,正在调用Player.STATE_ENDED

所以为了实现我的用例,我首先在 exoplayer 中设置它

 simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);

因此,我没有使用EventListener ,而是使用了AnalyticsListener,它使用eventTime参数覆盖 onPositionDiscontinuity 并添加一个简单的代码来了解媒体是否已重新启动。

   @Override
   public void onPositionDiscontinuity(EventTime eventTime, int reason) {
        if (eventTime.currentPlaybackPositionMs / 1000 < 1) {
            exoPlayer.setPlayWhenReady(false);
            tvReplay.setVisibility(View.VISIBLE);
        }
    }

希望这对您的用例有所帮助

于 2019-07-15T07:15:09.947 回答
0

用这个

      exoPlayer.addListener(new Player.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {

            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

            }

            @Override
            public void onLoadingChanged(boolean isLoading) {

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                if (playbackState == Player.STATE_ENDED) {

                  
                }
            }

            @Override
            public void onRepeatModeChanged(int repeatMode) {

            }

            @Override
            public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }

            @Override
            public void onPositionDiscontinuity(int reason) {

            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

            }

            @Override
            public void onSeekProcessed() {

            }
        });
于 2021-06-22T07:29:14.273 回答