You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:17:09