【发布时间】:2015-02-05 17:48:26
【问题描述】:
我正在尝试一个接一个地以播放列表的形式播放视频。我正在使用 android Exoplayer 播放我的文件,但 mediaplayer 中没有侦听器来收听媒体文件的结尾。有没有办法使用 exoplayer 收听媒体文件的结尾。
【问题讨论】:
我正在尝试一个接一个地以播放列表的形式播放视频。我正在使用 android Exoplayer 播放我的文件,但 mediaplayer 中没有侦听器来收听媒体文件的结尾。有没有办法使用 exoplayer 收听媒体文件的结尾。
【问题讨论】:
我知道这是旧的,但只是为了扩展已接受的答案:
exoPlayer.addListener(this);
.....
@Override
public void onPlayerStateChanged(boolean playWhenReady, int state) {
if (state == ExoPlayer.STATE_ENDED){
//player back ended
}
}
【讨论】:
onPositionDiscontinuity() 在我的情况下被调用然后如何处理?
Exoplayer 提供媒体播放器不提供的高级实现。
在 Android 的 Exoplayer 的高级示例中,在 FullPlayerActivity.java 中,他们实现了 onStateChanged,它提供了 STATE_ENDED
您可以在 RELATED SAMPLES
项下从this page 右侧部分下载示例【讨论】:
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
由于DefaultEventListener 和onPlayerStateChanged() 已被弃用。
player.addListener(object : Player.EventListener {
override fun onPlaybackStateChanged(state: Int) {
if (state == Player.STATE_ENDED) {
// your code
}
}
})
【讨论】:
EventListener现在也被弃用了,现在似乎只需要Player.Listener
您可以这样做:
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 的回答是正确的!有一个愉快的代码日!如果您还需要其他东西,请告诉我!
【讨论】:
Player.DefaultEventListener(),其中所有接口方法都被存根。因此,您可以删除不需要的方法,例如 onPlayWhenReadyCommitted 和 onPlayWhenReadyCommitted
您必须实现接口 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() {
}
});
【讨论】:
对于未连接的 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;
}
}
请注意: onPositionDiscontinuity() 不会为播放列表中的第一项调用,除非我们明确调用 player.seekTo(position,0)。因此,要处理您为播放列表中的所有媒体播放所做的任何事情,您必须单独处理播放列表中的第一项。
【讨论】:
onPositionDiscontinuity() 在轨道改变时被调用,但是如果我想在它改变之前做一些事情呢?
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 Developer page了解更多信息。
【讨论】:
ExoPlayer.STATE_ENDED 已贬值。请改用 Player.STATE_ENDED。 示例:
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if(playbackState == Player.STATE_ENDED){
// your brain put here
}
}
【讨论】:
我正在使用带有 exoplayer 的播放列表,我想在媒体播放完成后停止播放。
对我来说,Player.STATE_ENDED 在播放列表结束时被调用
所以为了实现我的用例,我首先在 exoplayer 中设置了这个
simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
因此,我没有使用 EventListener,而是使用了 AnalyticsListener,它提供了 onPositionDiscontinuity 来覆盖 eventTime 参数并添加一个简单的代码了解媒体是否已重新启动。
@Override
public void onPositionDiscontinuity(EventTime eventTime, int reason) {
if (eventTime.currentPlaybackPositionMs / 1000 < 1) {
exoPlayer.setPlayWhenReady(false);
tvReplay.setVisibility(View.VISIBLE);
}
}
希望这对您的用例有所帮助
【讨论】:
onPositionDiscontinuity() 是在轨道改变之后还是在改变之前调用?因为您的公式currentPlaybackPositionMs / 1000 < 1 看起来像是曲目的开头,应该是下一首曲目。
由于 DefaultEventListener 和 onPlayerStateChanged() 已被弃用。
使用Player.EventListener 和onPlaybackStateChanged()
Kotlin 代码:
player!!.addListener(object : Player.EventListener {
override fun onPlaybackStateChanged(state: Int) {
if (state == Player.STATE_ENDED) {
// your code here
}
}
})
【讨论】:
使用这个
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() {
}
});
【讨论】: