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

Jetpack Compose中ExoPlayer无法播放HLS视频求助

解决Jetpack Compose中ExoPlayer无法播放HLS流的问题

你的代码核心逻辑没问题,但几个细节没处理到位导致HLS流无法播放,下面是具体修复方案:

1. 补全必要的依赖与权限

ExoPlayer默认不包含HLS播放支持,必须手动添加对应模块,同时HLS流需要网络权限:

添加依赖

在Module级别的build.gradle(或build.gradle.kts)中加入:

dependencies {
    // 替换为当前ExoPlayer最新版本,比如2.19.1
    implementation "com.google.android.exoplayer:exoplayer:2.19.1"
    // HLS播放支持模块
    implementation "com.google.android.exoplayer:exoplayer-hls:2.19.1"
}

添加网络权限

在AndroidManifest.xml中加入:

<uses-permission android:name="android.permission.INTERNET" />

2. 修正ExoPlayerView实现

原代码存在几个影响播放的小问题,以下是修复后的完整代码:

@Composable
fun ExoPlayerView(url: String) {
    val context = LocalContext.current
    // 将url作为remember的key,确保url变化时重建播放器
    val exoPlayer = remember(url) {
        ExoPlayer.Builder(context).build().apply {
            val mediaItem = MediaItem.fromUri(url)
            setMediaItem(mediaItem)
            // 用异步准备替代同步prepare,避免阻塞主线程
            prepareAsync()
            playWhenReady = true
        }
    }

    // 绑定exoPlayer为DisposableEffect的key,保证监听只注册一次
    DisposableEffect(exoPlayer) {
        val listener = object : Player.Listener {
            override fun onIsPlayingChanged(isPlaying: Boolean) {
                Log.d("ExoPlayerView", "播放状态: ${if(isPlaying) "播放中" else "已暂停"}")
            }

            override fun onPlaybackStateChanged(state: Int) {
                val stateStr = when(state) {
                    Player.STATE_IDLE -> "闲置"
                    Player.STATE_BUFFERING -> "缓冲中"
                    Player.STATE_READY -> "就绪"
                    Player.STATE_ENDED -> "播放结束"
                    else -> "未知状态"
                }
                Log.d("ExoPlayerView", "播放状态码: $stateStr")
            }

            // 新增错误监听,方便排查播放失败原因
            override fun onPlayerError(error: PlaybackException) {
                super.onPlayerError(error)
                Log.e("ExoPlayerView", "播放出错: ${error.message}", error)
            }
        }

        exoPlayer.addListener(listener)

        onDispose {
            exoPlayer.removeListener(listener)
            exoPlayer.release()
        }
    }

    AndroidView(
        factory = {
            PlayerView(context).apply {
                player = exoPlayer
                // 强制开启控制器,方便调试播放状态
                useController = true
            }
        },
        modifier = Modifier
            .fillMaxWidth()
            .height(200.dp)
    )
}

关键修改说明

  • remember(url):把URL作为记忆key,后续如果支持切换URL,播放器会自动重建;
  • prepareAsync():异步准备媒体资源,避免同步操作阻塞主线程导致播放异常;
  • 新增错误监听:可以在Logcat中直接看到播放失败的具体原因,比如URL无效、网络问题等;
  • DisposableEffect(exoPlayer):确保播放器监听只注册一次,避免重复回调。

3. 测试验证

用官方提供的有效HLS测试地址验证:
https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8

如果还是无法播放,查看Logcat中的错误日志,根据提示排查问题(比如URL无效、网络不通、证书问题等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:24:51