ExoPlayer未发送RTSP请求:Jetpack Compose无法拉取本地流
问题排查:Jetpack Compose中ExoPlayer无法发起RTSP请求
核心问题分析及解决方案
1. Compose重组导致Player实例失效
你当前的代码在Composable函数内直接创建ExoPlayer实例,且未用remember保存,每次Compose重组都会生成新的Player对象:
- 调用
prepare()的Player实例可能在重组后被丢弃,PlayerView绑定的是新创建的未执行prepare的实例 - 未正确管理Player的生命周期,导致资源泄漏且逻辑混乱
修正代码:用remember保存Player实例,通过DisposableEffect在Composable销毁时释放资源:
val mContext = LocalContext.current // 用remember保存Player实例,避免重组重复创建 val player = remember { ExoPlayer.Builder(mContext).build().apply { val rtspUri = "rtsp://10.0.2.2:8554/test" val mediaSource = RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(rtspUri)) setMediaSource(mediaSource) } } // 管理Player生命周期,销毁时释放资源 DisposableEffect(Unit) { onDispose { player.release() } } // 绑定PlayerView并触发播放 AndroidView(factory = { context -> PlayerView(context).apply { this.player = player // 绑定后启动播放 player.playWhenReady = true player.prepare() } })
2. 缺少ExoPlayer RTSP扩展依赖
ExoPlayer的RTSP支持需要单独引入扩展库,默认依赖不包含RTSP模块,导致RtspMediaSource无法正常初始化,不会发起网络请求。
添加依赖(在Module级别的build.gradle.kts或build.gradle中):
// 适配你的ExoPlayer版本,建议使用最新稳定版 implementation "com.google.android.exoplayer:exoplayer-rtsp:2.19.1"
3. Android 9+明文流量限制
从Android 9(API 28)开始,默认禁止明文HTTP/RTSP流量,rtsp://10.0.2.2属于明文协议,会被系统拦截,导致无法发起请求。
解决办法:
- 在
res/xml目录下创建network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">10.0.2.2</domain> </domain-config> </network-security-config>
- 在
AndroidManifest.xml的<application>标签中引用该配置:
<application ... android:networkSecurityConfig="@xml/network_security_config">
4. 确认Docker容器端口映射正确
确保Docker运行aler9/rtsp-simple-server时,已正确映射8554端口:
docker run -p 8554:8554 aler9/rtsp-simple-server
验证步骤
- 先确认RTSP流可通过第三方工具(如VLC)正常播放
rtsp://10.0.2.2:8554/test - 按上述步骤修正代码、添加依赖和网络配置
- 运行App后查看Docker容器日志,确认是否收到连接请求
内容的提问来源于stack exchange,提问作者Iets Iets
相关产品推荐
相关产品推荐

