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

如何通过ExoPlayer Cast扩展创建CastPlayer?适配ExoPlayer 2.7.2

嘿,针对你在ExoPlayer 2.7.2上添加投屏功能的需求,我分两种场景给你详细说明,都是基于官方Cast扩展的方案:

解决ExoPlayer 2.7.2添加投屏功能的两种方案

一、将现有原生ExoPlayer转换为CastPlayer

如果你已经有一个正在运行的原生ExoPlayer实例,想无缝切换到投屏播放,可以按以下步骤操作:

1. 添加Cast扩展依赖

首先在Module级别的build.gradle里加入对应版本的Cast扩展依赖——版本必须和你的ExoPlayer主版本完全一致(2.7.2),不然会出现兼容性问题:

implementation 'com.google.android.exoplayer:extension-cast:2.7.2'

2. 初始化CastContext

在你的Application类或者主Activity的onCreate()方法里初始化Cast上下文,这是所有投屏功能的基础:

CastContext castContext = CastContext.getSharedInstance(this);

3. 添加投屏设备选择按钮

把系统自带的MediaRouteButton加到你的布局里,用户点击它就能看到并选择可用的Cast设备:

<androidx.mediarouter.app.MediaRouteButton
    android:id="@+id/media_route_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:mediaRouteTypes="user" />

然后在代码里为按钮绑定路由选择器,让它只识别Cast设备:

MediaRouter mediaRouter = MediaRouter.getInstance(this);
MediaRouteSelector routeSelector = new MediaRouteSelector.Builder()
    .addControlCategory(CastMediaControlIntent.categoryForCast(castContext.getApplicationId()))
    .build();
MediaRouteButton mediaRouteButton = findViewById(R.id.media_route_button);
mediaRouteButton.setRouteSelector(routeSelector);

4. 切换到CastPlayer播放

当用户选中投屏设备后,我们需要创建CastPlayer实例,把本地ExoPlayer的播放状态同步过去,实现无缝切换:

// 监听Cast会话的状态变化
castContext.addCastStateListener(new CastStateListener() {
    @Override
    public void onCastStateChanged(int state) {
        if (state == CastState.CONNECTED) {
            CastSession castSession = castContext.getSessionManager().getCurrentCastSession();
            if (castSession != null) {
                // 创建CastPlayer并关联当前会话
                CastPlayer castPlayer = new CastPlayer(castSession);
                
                // 同步本地播放器的媒体源、播放位置和播放状态
                MediaSource mediaSource = localExoPlayer.getMediaSource();
                long currentPosition = localExoPlayer.getCurrentPosition();
                boolean isPlaying = localExoPlayer.isPlaying();
                
                castPlayer.setMediaSource(mediaSource);
                castPlayer.prepare();
                castPlayer.seekTo(currentPosition);
                if (isPlaying) {
                    castPlayer.play();
                }
                
                // 暂停本地播放器,把UI控制绑定到CastPlayer(比如播放按钮、进度条)
                localExoPlayer.pause();
            }
        } else if (state == CastState.DISCONNECTED || state == CastState.NO_DEVICES_AVAILABLE) {
            // 投屏断开,切换回本地播放器
            if (localExoPlayer != null && castPlayer != null) {
                long castPosition = castPlayer.getCurrentPosition();
                localExoPlayer.seekTo(castPosition);
                if (castPlayer.isPlaying()) {
                    localExoPlayer.play();
                }
                // 释放CastPlayer资源,避免内存泄漏
                castPlayer.release();
            }
        }
    }

    // 实现其他CastStateListener的默认方法(比如onCastDeviceDetected)
});

二、直接基于Cast扩展创建CastPlayer

如果你的场景不需要本地播放,想直接用CastPlayer实现投屏播放,步骤会更简洁:

1. 先搞定依赖和CastContext初始化

和上面的步骤1、2完全一致,确保依赖版本匹配,CastContext初始化完成。

2. 创建CastPlayer并监听会话连接

直接初始化CastPlayer,然后设置会话监听器,等待用户连接投屏设备:

CastPlayer castPlayer = new CastPlayer();

// 设置会话监听器,处理连接成功和断开的逻辑
castPlayer.setSessionManagerListener(new SessionManagerListener<CastSession>() {
    @Override
    public void onSessionStarted(CastSession session, String sessionId) {
        // 投屏会话连接成功,设置媒体源并开始播放
        // 这里以渐进式媒体源为例,你可以根据自己的媒体类型调整(比如DASH、HLS)
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
                getApplicationContext(), Util.getUserAgent(getApplicationContext(), "你的应用名称"));
        MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse("你的媒体URL"));
        
        castPlayer.setMediaSource(mediaSource);
        castPlayer.prepare();
        castPlayer.play();
    }

    @Override
    public void onSessionEnded(CastSession session, int error) {
        // 投屏会话断开,释放CastPlayer资源
        castPlayer.release();
    }

    // 实现其他必要的SessionManagerListener方法(比如onSessionResumed、onSessionSuspended)
});

// 把CastPlayer的监听器绑定到CastContext的SessionManager
castContext.getSessionManager().addSessionManagerListener(
        castPlayer.getSessionManagerListener(), CastSession.class);

3. 绑定投屏控制UI

同样使用MediaRouteButton让用户选择投屏设备,当用户选中后,CastPlayer会自动触发onSessionStarted回调,你只需要在回调里处理播放逻辑即可。

关键注意事项

  • 版本一致性:ExoPlayer主库和Cast扩展的版本必须完全相同,2.7.2版本不要混用其他版本的扩展,否则会出现崩溃或者功能异常。
  • 资源释放:无论是本地ExoPlayer还是CastPlayer,在Activity销毁、投屏结束时,一定要调用release()方法释放资源,避免内存泄漏。
  • 媒体兼容性:Cast设备支持的媒体格式和本地可能有差异,尽量使用H.264编码的MP4、常见的HLS/DASH流等兼容性好的格式。

内容的提问来源于stack exchange,提问作者khateeb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:44:47