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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:47:52