使用URL流式播放时ExoPlayer返回FileNotFoundException的排查
问题分析与解决方案
问题根源
日志里的open failed: ENOENT (No such file or directory)结合FileDataSource报错,说明ExoPlayer错误地将网络流式URL当作本地文件路径处理了,核心原因大概率是以下两点:
- MediaItem创建时未正确传入合法的网络URI
- 未配置带认证信息的HTTP数据源工厂,导致ExoPlayer无法识别网络资源,进而 fallback 到本地文件数据源
具体解决方案
1. 确保MediaItem正确创建
必须使用MediaItem.fromUri()传入完整的SoundCloud流式URL,注意URL要带http/https前缀,不能有多余转义字符或格式错误:
val streamUrl = "https://your-soundcloud-stream-url.com/track.mp3" // 替换为实际获取的流URL val mediaItem = MediaItem.fromUri(streamUrl)
2. 配置带认证头的HTTP数据源工厂
SoundCloud的流式播放URL需要携带认证信息(Client-ID或Access Token)作为请求头,否则会被服务器拦截。创建DefaultHttpDataSource.Factory并添加必要请求头:
val dataSourceFactory = DefaultHttpDataSource.Factory() .setUserAgent("YourAppName/1.0") // 设置合法的User-Agent .setDefaultRequestProperties( mapOf( "Authorization" to "OAuth ${yourAccessToken}", // 或使用"Client-ID ${yourClientId}" "Accept" to "audio/mpeg" ) )
3. 根据流格式创建对应MediaSource
- 若为普通MP3/AAC流,使用
ProgressiveMediaSource:
val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem)
- 若为HLS格式(URL带
.m3u8后缀),使用HlsMediaSource:
val mediaSource = HlsMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem)
4. 完整播放流程代码
将上述步骤整合到播放逻辑中:
private lateinit var player: ExoPlayer private lateinit var playerView: PlayerView private fun setupPlayer(){ player = ExoPlayer.Builder(this).build() playerView = findViewById(R.id.gm_player) playerView.player = player player.addListener(this) } private fun startPlayback(streamUrl: String, accessToken: String) { // 1. 创建带认证的数据源工厂 val dataSourceFactory = DefaultHttpDataSource.Factory() .setUserAgent("YourKotlinApp/1.0") .setDefaultRequestProperties( mapOf("Authorization" to "OAuth $accessToken") ) // 2. 创建MediaItem val mediaItem = MediaItem.fromUri(streamUrl) // 3. 创建MediaSource(根据实际流格式选择) val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem) // 4. 准备并播放 player.setMediaSource(mediaSource) player.prepare() player.playWhenReady = true }
5. 额外排查点
- 用Postman测试流式URL:携带相同的Authorization请求头,确认是否能正常返回音频数据
- 检查ExoPlayer版本:使用最新稳定版(如2.X系列最新版),避免旧版本兼容性问题
- 确认网络配置:若URL为HTTPS,检查是否存在证书校验问题(正式环境请勿关闭证书校验,仅用于临时排查)
内容的提问来源于stack exchange,提问作者Kera Linn
相关产品推荐
相关产品推荐

