Android ExoPlayer播放302跳转视频URL报ERROR_CODE_IO_BAD_HTTP_STATUS如何解决
问题原因
ExoPlayer默认的HTTP数据源组件未开启重定向自动跟随配置,当服务端返回302跳转状态码时,ExoPlayer不会自动请求跳转后的资源地址,会将302识别为异常HTTP状态码,触发ERROR_CODE_IO_BAD_HTTP_STATUS报错。而VLC默认开启了重定向跟随,所以可以正常播放。
解决方案
你需要自定义HTTP数据源工厂,开启重定向跟随配置,再将该工厂注入到ExoPlayer的构建参数中,具体实现如下:
1. (可选)使用OkHttp数据源(兼容性更强,推荐)
首先在模块级build.gradle中添加对应依赖,版本需和你项目中ExoPlayer核心版本保持一致:
implementation "com.google.android.exoplayer:exoplayer-okhttp:2.19.1"
2. 修改ExoPlayer初始化代码
使用默认DefaultHttpDataSource的修改示例:
private fun initializePlayer() { if (url.isNotEmpty()){ // 自定义HTTP数据源工厂,开启重定向跟随 val dataSourceFactory = DefaultHttpDataSource.Factory() .setFollowRedirects(true) // 核心配置,支持301/302重定向自动跳转 .setUserAgent("ExoPlayer-App") // 可自定义UA,避免部分服务端拦截请求 // 构建ExoPlayer时传入自定义数据源工厂 player = SimpleExoPlayer.Builder(this) .setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory)) .build() binding.videoView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT binding.videoView.player = player val mediaItem: MediaItem = MediaItem.fromUri(url) Log.d("testurl", url) player.setMediaItem(mediaItem) player.playWhenReady = playWhenReady player.seekTo(currentWindow, playbackPosition) player.prepare() player.addListener(this) } else { Toast.makeText(this, "Unable to play the video!", Toast.LENGTH_SHORT).show() } }
如果使用OkHttp数据源,替换数据源工厂部分的代码即可:
// 构建支持重定向的OkHttpClient实例 val okHttpClient = OkHttpClient.Builder() .followRedirects(true) .followSslRedirects(true) .build() // 初始化OkHttp数据源工厂 val dataSourceFactory = OkHttpDataSource.Factory(okHttpClient) .setUserAgent("ExoPlayer-App")
注意事项
- 如果你的302跳转涉及HTTP到HTTPS的跨协议跳转,或者服务端配置了请求头校验,需要在数据源工厂中通过
setDefaultRequestProperties方法添加和VLC请求一致的Referer、Origin等头字段,避免服务端拦截。 - 如果修改配置后仍然报错,可以通过抓包对比ExoPlayer和VLC的请求差异,补全缺失的请求参数即可。
内容的提问来源于stack exchange,提问作者Feroz Khan
相关产品推荐
相关产品推荐

