ExoPlayer无法播放特定M3U8文件,报ERROR_CODE_IO_UNSPECIFIED错误
问题
- 现有ExoPlayer实现可正常播放以下公开M3U8测试链接:
https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8
- 核心实现代码(Kotlin):
private fun initExo(url: String) { layoutVideoWidgetBinding!!.exoVideoPlayer.visible() layoutVideoWidgetBinding!!.loaderLa.gone() exoPlayer = ExoPlayer.Builder(layoutVideoWidgetBinding!!.root.context).build() exoPlayer?.playWhenReady = true layoutVideoWidgetBinding!!.exoVideoPlayer.player = exoPlayer val defaultHttpDataSourceFactory = DefaultHttpDataSource.Factory() val mediaItem = MediaItem.fromUri(url) val mediaSource = HlsMediaSource.Factory(defaultHttpDataSourceFactory).createMediaSource(mediaItem) exoPlayer?.apply { setMediaSource(mediaSource) seekTo(playbackPosition) playWhenReady = playWhenReady prepare() addListener(playbackStateListener) } }
- 无法播放自定义M3U8文件(该文件在VLC和网页端可正常播放),文件内容:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:138 #EXT-X-TARGETDURATION:2 #EXT-X-PLAYLIST-TYPE: EVENT #EXTINF:1.796, 869409066980304_front-138.ts #EXTINF:1.775, 869409066980304_front-139.ts #EXTINF:1.772, 869409066980304_front-140.ts #EXTINF:1.797, 869409066980304_front-141.ts #EXTINF:1.783, 869409066980304_front-142.ts #EXTINF:1.775, 869409066980304_front-143.ts #EXTINF:1.161, 869409066980304_front-144.ts #EXT-X-DISCONTINUITY #EXTINF:1.894, 869409066980304_front-145.ts #EXTINF:1.938, 869409066980304_front-146.ts #EXTINF:1.668, 869409066980304_front-147.ts #EXT-X-DISCONTINUITY #EXTINF:1.241, 869409066980304_front-148.ts #EXTINF:1.217, 869409066980304_front-149.ts #EXTINF:1.153, 869409066980304_front-150.ts #EXTINF:0.964, 869409066980304_front-151.ts #EXT-X-DISCONTINUITY #EXTINF:1.002, 869409066980304_front-152.ts #EXT-X-DISCONTINUITY #EXTINF:1.895, 869409066980304_front-153.ts #EXTINF:1.133, 869409066980304_front-154.ts #EXT-X-DISCONTINUITY #EXTINF:0.000, 869409066980304_front-155.ts #EXT-X-DISCONTINUITY #EXTINF:1.839, 869409066980304_front-156.ts #EXTINF:0.275, 869409066980304_front-157.ts
- 报错信息:ExoPlayer抛出
ERROR_CODE_IO_UNSPECIFIED错误,异常为androidx.media3.exoplayer.ExoPlaybackException: Source error - 播放状态日志仅打印
STATE_BUFFERING,状态监听代码(Java):
@Override public void onPlaybackStateChanged(@Player.State int playbackState) { if (playbackState == Player.STATE_ENDED) { showControls(); Log.i("EventLogger", "STATE_ENDED"); } if (playbackState == Player.STATE_BUFFERING) { Log.i("EventLogger", "STATE_BUFFERING"); } if (playbackState == Player.STATE_IDLE) { Log.i("EventLogger", "STATE_IDLE"); } if (playbackState == Player.STATE_READY) { Log.i("EventLogger", "STATE_READY"); } if (playbackState == Player.EVENT_PLAYBACK_STATE_CHANGED) { Log.i("EventLogger", "EVENT_PLAYBACK_STATE_CHANGED"); } updateButtonVisibility(); }
解决方案
1. 修复TS文件路径问题
你的M3U8中TS文件使用相对路径,ExoPlayer会基于M3U8的URL拼接TS文件请求地址,需确认:
- M3U8与TS文件是否在同一域名/路径下,若不在,需将TS路径改为绝对URL
- 服务器是否能正确解析相对路径的请求,必要时调整服务器路由配置
2. 处理EXT-X-DISCONTINUITY标签兼容
M3U8中大量存在该标签,需确保:
- 每个不连续点前后的TS文件编码参数(分辨率、码率、编码格式)一致,避免ExoPlayer切换失败
- 配置HlsMediaSource工厂开启兼容:
val hlsFactory = HlsMediaSource.Factory(defaultHttpDataSourceFactory) .setAllowChunklessPreparation(true) val mediaSource = hlsFactory.createMediaSource(mediaItem)
3. 优化HttpDataSource配置
针对ERROR_CODE_IO_UNSPECIFIED网络类错误,调整数据源参数:
val defaultHttpDataSourceFactory = DefaultHttpDataSource.Factory() .setConnectTimeoutMs(10000) .setReadTimeoutMs(10000) .setAllowCrossProtocolRedirects(true) .setRetryCount(3) // 若服务器需要鉴权Header,添加以下配置 defaultHttpDataSourceFactory.setDefaultRequestProperties(mapOf( "Authorization" to "Bearer your_token", "User-Agent" to "ExoPlayer/1.2.1" ))
4. 添加详细错误监听
当前监听未捕获错误事件,需补充onPlayerError方法定位具体问题:
private val playbackStateListener = object : Player.Listener { override fun onPlaybackStateChanged(playbackState: Int) { // 原有状态监听逻辑 } override fun onPlayerError(error: PlaybackException) { Log.e("ExoPlayerError", "错误码: ${error.errorCode}, 信息: ${error.message}", error) error.cause?.let { Log.e("ExoPlayerErrorCause", "底层原因: ${it.message}", it) } } }
5. 修正非法EXTINF值
M3U8中存在#EXTINF:0.000,的片段,违反HLS规范(EXTINF值需大于0),需修改该片段的EXTINF值为有效时长,或移除该片段。
6. 更新ExoPlayer版本
确保使用最新稳定版Media3(ExoPlayer),旧版本可能存在HLS特性支持缺陷:
implementation "androidx.media3:media3-exoplayer:1.2.1" implementation "androidx.media3:media3-exoplayer-hls:1.2.1" implementation "androidx.media3:media3-ui:1.2.1"
内容的提问来源于stack exchange,提问作者Tehleel Mir
相关产品推荐
相关产品推荐

