如何检测ExoPlayer当前是否正在播放HDR视频?
获取ExoPlayer当前播放流的HDR状态实用方案
1. 从当前播放轨道的Format对象提取HDR信息
这是最直接可靠的方式,通过ExoPlayer的轨道变更回调,拿到当前选中视频轨道的Format实例,检查以下核心字段:
hdrFormat:直接返回HDR格式类型,非HDR_FORMAT_NONE即为HDR流(包含HDR_FORMAT_HDR10、HDR_FORMAT_DOLBY_VISION等枚举值)hdrStaticInfo:不为null时,包含HDR静态元数据(如峰值亮度、黑电平参数)colorSpace:判断是否为COLOR_SPACE_BT2020(HDR标准色彩空间)
示例代码:
player.addListener(new Player.Listener() { @Override public void onTracksChanged(Tracks tracks) { super.onTracksChanged(tracks); // 定位视频轨道组 Tracks.Group videoTrackGroup = null; for (Tracks.Group group : tracks.getGroups()) { if (group.getType() == C.TRACK_TYPE_VIDEO && group.isSelected()) { videoTrackGroup = group; break; } } if (videoTrackGroup == null) return; Format selectedVideoFormat = videoTrackGroup.getFormat(videoTrackGroup.getSelectedIndex()); // 判定HDR状态 boolean isCurrentStreamHdr = selectedVideoFormat.hdrFormat != Format.HDR_FORMAT_NONE; // 可选:结合色彩空间二次验证 boolean isBt2020ColorSpace = selectedVideoFormat.colorSpace == C.COLOR_SPACE_BT2020; // 更新诊断TextView diagnosticTextView.setText(String.format("当前流HDR状态:%s | BT.2020色彩空间:%s", isCurrentStreamHdr ? "是" : "否", isBt2020ColorSpace ? "是" : "否")); } });
2. 修复DashManifest解析空值问题
你遇到的DashManifest中色彩空间为null的情况,可能是这两个原因:
- 流的MPD文件未正确携带HDR元数据:检查MPD的
AdaptationSet或Representation节点,是否包含colorSpace属性、HDRSignaling扩展字段,若缺失需联系流提供者补充 - ExoPlayer版本过低:升级到2.18+版本,旧版本对Dash HDR元数据的解析支持不完善;也可以手动遍历解析后的
DashManifest,提取Representation的扩展参数:
DashMediaSource.Factory dashFactory = new DashMediaSource.Factory(...); dashFactory.setEventListener(new DashMediaSource.EventListener() { @Override public void onManifestLoaded(DashManifest manifest) { // 遍历视频AdaptationSet和Representation for (DashManifest.AdaptationSet adaptationSet : manifest.getPeriod(0).adaptationSets) { if (adaptationSet.type == C.TRACK_TYPE_VIDEO) { for (DashManifest.Representation representation : adaptationSet.representations) { Format format = representation.format; // 检查format的HDR相关字段 } } } } });
3. 结合Surface显示状态双重验证
虽然你已确认显示器和编解码器支持HDR,但可以通过Surface的像素格式辅助验证:
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // HDR播放常用的Surface像素格式 boolean isHdrSurface = format == PixelFormat.RGBA_F16 || format == PixelFormat.YUV_420_10BIT; // 结合轨道Format的判断结果,提升准确性 } });
注意:优先以
Format.hdrFormat的判断结果为准,部分HDR流可能未显式设置色彩空间,但会正确标记HDR格式类型。
内容的提问来源于stack exchange,提问作者Jerzy Kiler
相关产品推荐
相关产品推荐

