Android ExoPlayer `ExoPlaybackException` 系统性排查指南
是 ExoPlayer 播放过程中抛出的通用异常,通常由底层媒体源、解码器或网络问题引发。:DRM session error 或 License acquisition failed。通过 getSourceException() 获取底层异常对象,进一步定位问题根源。:Android 4.4 设备 HTTPS 请求失败,Android 5.0+ 正常。:Android 4.4 默认禁用 TLS
·
ExoPlaybackException
Android ExoPlayer ExoPlaybackException
android.exoplayer2.ExoPlaybackException
是 ExoPlayer 播放过程中抛出的通用异常,通常由底层媒体源、解码器或网络问题引发。以下是系统性排查指南:
一、异常类型与核心原因
异常子类 | 触发场景 |
---|---|
ExoPlaybackException.SourceError |
媒体源加载失败(网络错误/文件损坏/格式不支持)、元数据解析异常、DRM认证失败 |
ExoPlaybackException.RendererError |
解码器初始化失败、硬件编码格式不支持、渲染器配置错误(视频尺寸/像素格式不匹配) |
ExoPlaybackException.LoadError |
媒体数据加载超时、缓存不足、网络中断(HTTPS/SSL握手失败) |
1.关键方法
通过 getSourceException() 获取底层异常对象,进一步定位问题根源。例如:
try {
player.prepare(mediaItem);
} catch (ExoPlaybackException e) {
Throwable cause = e.getSourceException();
if (cause instanceof HttpDataSourceException) {
Log.e("ExoPlayer", "HTTP 错误: " + ((HttpDataSourceException) cause).responseCode);
}
}
二、关键排查方向
1. 网络与 SSL 问题(重点)
现象:Android 4.4 设备 HTTPS 请求失败,Android 5.0+ 正常
原因:Android 4.4 默认禁用 TLSv1.1/TLSv1.2
解决方案:
- application中增加代码
// 在 Application.onCreate() 中添加
try {
ProviderInstaller.installIfNeeded(getApplicationContext());
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
sslContext.createSSLEngine();
} catch (Exception e) {
e.printStackTrace();
}
- 代码配置:通过 OkHttpClient 或自定义 DataSource.Factory 启用 TLSv1.2。
// 1. 创建自定义 SSLSocketFactory
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
private final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patchSocket(delegate.createSocket(s, host, port, autoClose));
}
private Socket patchSocket(Socket socket) {
if (socket instanceof SSLSocket) {
((SSLSocket) socket).setEnabledProtocols(TLS_V12_ONLY);
}
return socket;
}
}
// 2. 配置 OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(new Tls12SocketFactory(SSLContext.getDefault().getSocketFactory()))
.connectionSpecs(Arrays.asList(
new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build(),
ConnectionSpec.COMPATIBLE_TLS,
ConnectionSpec.CLEARTEXT
))
.build();
// 配置 ExoPlayer DataSource
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory()
.setHttpClient(okHttpClient) // 核心:注入自定义 OkHttpClient
.setUserAgent("CustomUserAgent")
.setConnectTimeoutMs(30000);
ExoPlayer player = new ExoPlayer.Builder(context)
.setDataSourceFactory(dataSourceFactory)
.build();
验证:通过 adb logcat | grep 'ExoPlayer'
检查 SSL 日志
2. 媒体源与数据问题
检查点:
- 媒体 URL 有效性(使用浏览器/curl 测试)
- 媒体格式支持性(HLS/DASH/MP4 等)
- 媒体文件完整性(本地播放测试)
调试工具:
// 解析媒体元数据
MediaInfo mediaInfo = new MediaInfo(mediaUrl);
// 配置自定义参数
DefaultHttpDataSource dataSource = new DefaultHttpDataSource.Factory()
.setUserAgent("CustomUserAgent")
.setConnectTimeoutMs(30000)
.createDataSource();
3. 解码器与渲染问题
常见错误:
MediaCodecRenderer
报错:设备不支持 H.265 等编码格式- 视频尺寸/像素格式不匹配
解决方案:
// 启用软件解码器
RenderersFactory renderersFactory = new DefaultRenderersFactory(context)
.setEnableDecoderFallback(true);
// 监听视频尺寸变更
player.addListener(new Player.EventListener() {
@Override
public void onVideoSizeChanged(VideoSize videoSize) {
// 调整 Surface 尺寸
}
});
4. DRM 保护内容
现象:DRM session error 或 License acquisition failed
排查:
- 确认 DRM 许可证 URL 和认证信息正确性
- 检查网络请求是否携带正确 DRM 请求头(如 Authorization)
三、调试与日志分析
// 捕获异常堆栈
player.addListener(new Player.EventListener() {
@Override
public void onPlayerError(ExoPlaybackException error) {
Log.e("ExoPlayer", "Error stack trace: " + Log.getStackTraceString(error));
}
});
日志过滤:
adb logcat | grep 'ExoPlayer' -i
四、版本兼容性建议
- ExoPlayer 版本:使用最新稳定版(如 2.X/3.X)
- Android 版本适配:
- Android 4.4:强制启用 TLSv1.2,避免 HTTP/2
- Android 5.0+:检查
android:usesCleartextTraffic
配置
更多推荐
所有评论(0)