如何通过ExoPlayer 2的EventListener获取各类基础事件?
如何在ExoPlayer 2.7.1中实现自定义事件的监听
嘿,我刚好对ExoPlayer 2.7.x的事件体系比较熟悉,咱们一个个拆解你需要的这些事件,看看怎么用现有接口实现等效的逻辑:
一、生命周期相关事件(onStart/onStop/onPause/onResume)
ExoPlayer本身没有直接暴露这些生命周期回调,因为这些属于宿主组件(Activity/Fragment)的生命周期,你需要在宿主的对应方法里绑定ExoPlayer的操作,并同步执行你的自定义代码:
// 在你的Activity/Fragment中 @Override protected void onStart() { super.onStart(); if (Build.VERSION.SDK_INT >= 24) { // 恢复播放 player.setPlayWhenReady(true); } // 执行你的onStart事件代码 yourOnStartLogic(); } @Override protected void onResume() { super.onResume(); if (Build.VERSION.SDK_INT < 24) { // 低版本恢复播放 player.setPlayWhenReady(true); } // 执行你的onResume事件代码 yourOnResumeLogic(); } @Override protected void onPause() { super.onPause(); if (Build.VERSION.SDK_INT < 24) { // 低版本暂停播放 player.setPlayWhenReady(false); } // 执行你的onPause事件代码 yourOnPauseLogic(); } @Override protected void onStop() { super.onStop(); if (Build.VERSION.SDK_INT >= 24) { // 高版本暂停并释放部分资源(按需) player.setPlayWhenReady(false); // 如果需要完全释放,可调用player.release(),但要注意后续重新初始化 } // 执行你的onStop事件代码 yourOnStopLogic(); }
二、广告相关事件(onStartAd/onStopAd)
如果你是用Google IMA集成广告,ExoPlayer 2.7.1提供了AdEventListener来监听广告状态:
// 初始化广告相关MediaSource时设置监听 AdsMediaSource adsMediaSource = new AdsMediaSource( contentMediaSource, adTagUri, adsLoader, playerView.getOverlayFrameLayout(), null, new AdEventListener() { @Override public void onAdStarted() { // 对应你的onStartAd事件 yourOnStartAdLogic(); } @Override public void onAdEnded() { // 对应你的onStopAd事件 yourOnStopAdLogic(); } // 其他广告回调按需实现 } );
三、心跳事件(onHeartBeat)
ExoPlayer没有原生的心跳回调,你需要自己实现定时触发逻辑,比如用Handler在播放期间定时执行:
private Handler heartbeatHandler = new Handler(); private Runnable heartbeatRunnable = new Runnable() { @Override public void run() { // 执行你的心跳逻辑 yourOnHeartBeatLogic(); // 每隔30秒触发一次(可自定义间隔) heartbeatHandler.postDelayed(this, 30000); } }; // 在播放开始时启动心跳 private void startHeartbeat() { if (!heartbeatHandler.hasCallbacks(heartbeatRunnable)) { heartbeatHandler.post(heartbeatRunnable); } } // 在播放停止时停止心跳 private void stopHeartbeat() { heartbeatHandler.removeCallbacks(heartbeatRunnable); } // 结合Player.EventListener的状态变化来启停心跳 player.addListener(new Player.EventListener() { @Override public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { if (playbackState == Player.STATE_READY && playWhenReady) { startHeartbeat(); } else { stopHeartbeat(); } } });
四、缓冲相关事件(onBufferingStart/onBufferingEnd)
通过Player.EventListener的onPlayerStateChanged方法判断缓冲状态:
player.addListener(new Player.EventListener() { @Override public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { switch (playbackState) { case Player.STATE_BUFFERING: // 缓冲开始,执行你的逻辑 yourOnBufferingStartLogic(); break; case Player.STATE_READY: case Player.STATE_ENDED: // 缓冲结束(从缓冲状态切换到就绪或播放完成) yourOnBufferingEndLogic(); break; } } });
五、加载完成事件(onLoadingComplete)
当播放器从加载/缓冲状态切换到就绪状态时,即可认为加载完成,同样在onPlayerStateChanged中处理:
player.addListener(new Player.EventListener() { private boolean wasLoading = false; @Override public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { if (playbackState == Player.STATE_BUFFERING) { wasLoading = true; } else if (wasLoading && playbackState == Player.STATE_READY) { // 加载完成,执行你的逻辑 yourOnLoadingCompleteLogic(); wasLoading = false; } } });
六、带宽变化事件(onBandWidthChange)
通过DefaultBandwidthMeter.EventListener来监听带宽变化,需要先创建带宽计量器并绑定到播放器:
// 创建带宽计量器并设置监听 DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(new DefaultBandwidthMeter.EventListener() { @Override public void onBandwidthSample(int elapsedMs, long bytes, long bitrate) { // bitrate即为当前带宽,执行你的带宽变化逻辑 yourOnBandWidthChangeLogic(bitrate); } }); // 将带宽计量器传给ExoPlayer的构造或MediaSource(比如用DefaultDataSourceFactory) DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory( context, Util.getUserAgent(context, "YourAppName"), bandwidthMeter ); // 后续用这个dataSourceFactory创建MediaSource即可
需要注意的是,ExoPlayer 2.7.1是比较老的版本了,部分API在后续版本中有变更,但以上逻辑完全适配2.7.1的版本。
内容的提问来源于stack exchange,提问作者khateeb
相关产品推荐
相关产品推荐

