下载了 HDR 视频结果一片灰白?HDR 下载、播放与转 SDR 的完整指南
你在 B 站或 YouTube 下载了一个标着"4K HDR 真彩"的视频,满心期待地打开——画面灰蒙蒙的,颜色像褪了色,亮度忽明忽暗。这不是视频坏了,是你的播放器/显示器不支持 HDR。HDR(高动态范围)视频包含的亮度和色彩信息远超普通 SDR 视频,但如果播放链路中任何一环不支持 HDR,画面就会"崩"。这篇文章讲清楚:HDR10、Dolby Vision、HLG 三种格式的区别、下载时怎么选、怎么正确播放、以及怎么把 HDR 转成 SDR 在普通设备上看。
TL;DR:HDR 视频发灰的原因——播放器把 HDR 数据当成 SDR 显示了,没有做"色调映射"(Tone Mapping)。解决方案:① 用支持 HDR 的播放器(VLC/mpv/ PotPlayer 开 HDR 模式) + HDR 显示器;② 用 FFmpeg 把 HDR 转成 SDR(色调映射),在任何设备上都能正常看;③ 下载时就选 SDR 版本(如果平台提供了 SDR 选项)。
目录
- 一、HDR 视频为什么在你的屏幕上发灰
- 二、HDR10、Dolby Vision、HLG 有什么区别
- 三、下载时怎么选:要 HDR 还是 SDR
- 四、正确播放 HDR 视频
- 五、HDR 转 SDR:在普通设备上正常观看
- 六、检测视频是否是 HDR
- 七、批量 HDR→SDR 转换脚本
- 八、合规与温馨提示
一、HDR 视频为什么在你的屏幕上发灰
1.1 根本原因:缺少色调映射
HDR 视频的亮度范围:0.0001 nit → 1000+ nit
SDR 显示器的亮度范围:0.1 nit → 100 nit(典型值)
如果直接把 HDR 数据喂给 SDR 显示器:
→ 超出 100 nit 的亮度被"截断"
→ 暗部细节丢失(0.0001 nit 在 SDR 上就是全黑)
→ 颜色空间不匹配(BT.2020 → BT.709 没有转换)
→ 结果:灰蒙蒙、褪色、发白
色调映射(Tone Mapping)就是把 HDR 的大范围亮度"压缩"到 SDR 显示器能显示的范围内,同时尽量保留明暗对比和色彩信息。
1.2 一个直观的类比
HDR 视频 = 一张 RAW 格式的照片(包含大量动态范围信息)
SDR 显示器 = 普通打印机
直接把 RAW 发给打印机 → 黑乎乎一团
先用 Lightroom 处理 RAW(色调映射)→ 打印机输出正常照片
FFmpeg 的色调映射滤镜就是视频领域的"Lightroom"。
二、HDR10、Dolby Vision、HLG 有什么区别
2.1 三种格式对比
| 特性 | HDR10 | HDR10+ | Dolby Vision | HLG |
|---|---|---|---|---|
| 元数据类型 | 静态 | 动态 | 动态 | 无(基于伽马) |
| 最大亮度 | 1000 nit | 4000 nit | 10000 nit | 1000 nit |
| 色深 | 10-bit | 10-bit | 12-bit | 10-bit |
| 授权费 | 免费 | 免费 | 收费 | 免费 |
| 兼容 SDR | 需要转换 | 需要转换 | 需要转换 | 原生兼容 |
| YouTube 使用 | ✅ | ❌ | ❌ | ❌ |
| B 站使用 | ❌ | ❌ | ✅(部分) | ❌ |
| Netflix 使用 | ✅ | ❌ | ✅ | ❌ |
| 电视广播 | ❌ | ❌ | ❌ | ✅(BBC/NHK) |
2.2 各自的特点
HDR10:最基础、最通用的 HDR 格式。所有 HDR 电视和播放器都支持。使用静态元数据——整个视频只有一套亮度和色彩参数。
HDR10+:三星主导的 HDR10 升级版。使用动态元数据——可以逐场景甚至逐帧调整亮度和色彩。免费授权。
Dolby Vision:杜比实验室的顶级 HDR 格式。使用动态元数据,支持 12-bit 色深。画质最好但需要授权费,所以支持的设备和平台较少。B 站的部分"杜比视界"视频就是这种格式。
HLG:由 BBC 和 NHK 联合开发,专为电视广播设计。最大的特点是原生兼容 SDR——在普通电视上也能正常显示(不会发灰),在 HDR 电视上效果更好。不需要元数据。
2.3 下载时怎么判断
# 用 ffprobe 查看视频的 HDR 信息
ffprobe -v error -show_entries stream=color_space,color_transfer,color_primaries \
-of default=noprint_wrappers=1 input.mp4
输出解读:
HDR10 视频:
color_space=bt2020nc
color_transfer=smpte2084 ← PQ 曲线(HDR10 的标志)
color_primaries=bt2020
HLG 视频:
color_space=bt2020nc
color_transfer=arib-std-b67 ← HLG 的标志
color_primaries=bt2020
Dolby Vision:
color_space=bt2020nc
color_transfer=smpte2084
color_primaries=bt2020
还有额外的 Dolby Vision 元数据流
普通 SDR 视频:
color_space=bt709
color_transfer=bt709
color_primaries=bt709
三、下载时怎么选:要 HDR 还是 SDR
3.1 选择决策树
你有 HDR 显示器(或 HDR 电视)吗?
├── 有 → 下载 HDR 版本 ✅
│ └── 播放器推荐:mpv(自动色调映射)、VLC(手动开启 HDR)
│
└── 没有 → 平台提供了 SDR 版本吗?
├── 有 → 下载 SDR 版本(省心)
└── 没有 → 下载 HDR 版本 + FFmpeg 转 SDR
3.2 yt-dlp 选择格式
# 查看可用格式
yt-dlp -F "URL"
# YouTube 的 HDR 格式通常标记为:
# 337 webm 1920x1080 HDR
# 336 webm 2560x1440 HDR
# 选择 HDR 视频 + 最佳音频
yt-dlp -f "bestvideo[height<=2160][dynamic_range=HDR]+bestaudio" URL
# 选择 SDR 视频(避免 HDR)
yt-dlp -f "bestvideo[height<=1080][dynamic_range=SDR]+bestaudio" URL
四、正确播放 HDR 视频
4.1 各播放器的 HDR 支持
| 播放器 | HDR 支持 | 配置方式 | 推荐度 |
|---|---|---|---|
| mpv | ✅ 自动 | 无需配置,开箱即用 | ⭐⭐⭐⭐⭐ |
| VLC | ✅ 手动 | 设置 → 视频 → 输出模块 → OpenGL | ⭐⭐⭐⭐ |
| PotPlayer | ✅ 手动 | 视频 → 像素着色 → HDR 自动校正 | ⭐⭐⭐⭐ |
| IINA (Mac) | ✅ 自动 | 开箱即用 | ⭐⭐⭐⭐⭐ |
| Windows Media Player | ❌ 不支持 | — | ⭐ |
| 浏览器 (Chrome/Edge) | ⚠️ 部分 | YouTube 支持,本地文件不行 | ⭐⭐ |
4.2 mpv 配置(推荐)
mpv 是目前 HDR 播放最省心的播放器——自动检测 HDR 并做色调映射:
# 安装 mpv
# Windows: https://mpv.io/installation/
# Mac: brew install mpv
# Linux: sudo apt install mpv
# 直接播放
mpv video_hdr.mp4
如果需要手动控制色调映射:
# ~/.config/mpv/mpv.conf
vo=gpu-next
target-colorspace-hint=yes
tone-mapping=bt.2390 # 色调映射算法
hdr-compute-peak=yes # 自动计算峰值亮度
target-peak=200 # 你的显示器峰值亮度(nit)
4.3 VLC 配置
1. 工具 → 偏好设置 → 视频
2. 输出模块 → OpenGL 视频输出
3. 开启 "HDR 色调映射"
4. 重启 VLC
五、HDR 转 SDR:在普通设备上正常观看
5.1 FFmpeg 色调映射命令
# HDR10 → SDR(推荐)
ffmpeg -i input_hdr.mp4 \
-vf "zscale=t=linear:npl=100,format=gbrpf32le,\
zscale=p=bt709,tonemap=tonemap=hable:desat=0,\
zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
-c:v libx264 -preset medium -crf 20 \
-c:a aac -b:a 192k \
output_sdr.mp4
这个命令看起来很复杂,拆解一下每一步:
步骤 1: zscale=t=linear:npl=100
→ 把 HDR 的 PQ 曲线转成线性光(npl=你的显示器峰值亮度,单位 nit)
步骤 2: format=gbrpf32le
→ 转为 32 位浮点格式(保留精度)
步骤 3: zscale=p=bt709
→ 把 BT.2020 色域转成 SDR 的 BT.709
步骤 4: tonemap=tonemap=hable:desat=0
→ 色调映射(Hable 算法,自然效果好)
→ desat=0 表示不降低饱和度
步骤 5: zscale=t=bt709:m=bt709:r=tv,format=yuv420p
→ 转回标准 SDR 格式
5.2 不同色调映射算法对比
| 算法 | 效果 | 速度 | 适用场景 |
|---|---|---|---|
| hable | 自然,不过曝 | 快 | 推荐,日常使用 |
| mobius | 平滑过渡 | 快 | 夜景/暗部细节多的视频 |
| reinhard | 亮部有压缩感 | 快 | 快速预览 |
| bt.2390 | 标准算法 | 中 | 严格按 ITU 标准 |
| clip | 简单截断 | 极快 | 不推荐(丢细节) |
# 尝试不同算法
ffmpeg -i input.mp4 \
-vf "zscale=t=linear,format=gbrpf32le,\
zscale=p=bt709,tonemap=tonemap=hable:desat=2,\
zscale=t=bt709:m=bt709,format=yuv420p" \
output_hable.mp4
5.3 HLG 转 SDR(更简单)
HLG 的转换比 HDR10 简单,因为它本身就是兼容 SDR 的设计:
# HLG → SDR
ffmpeg -i input_hlg.mp4 \
-vf "zscale=t=linear,format=gbrpf32le,\
zscale=p=bt709,tonemap=tonemap=mobius,\
zscale=t=bt709:m=bt709,format=yuv420p" \
-c:v libx264 -crf 22 -c:a copy \
output_sdr.mp4
5.4 保留 HDR 同时改变编码
如果只是想改变编码但保留 HDR:
# HDR VP9 → HDR H.265(保留 HDR 元数据)
ffmpeg -i input_hdr.webm \
-c:v libx265 -preset medium -crf 18 \
-x265-params "colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc" \
-c:a aac -b:a 192k \
output_hdr.mp4
六、检测视频是否是 HDR
import subprocess
import json
def detect_hdr(video_path):
"""检测视频的 HDR 格式"""
cmd = [
'ffprobe', '-v', 'error',
'-show_entries', 'stream=color_space,color_transfer,color_primaries,width,height,codec_name',
'-of', 'json', video_path
]
result = subprocess.run(cmd, capture_output=True, text=True)
data = json.loads(result.stdout)
for stream in data.get('streams', []):
transfer = stream.get('color_transfer', '')
hdr_type = 'SDR'
if transfer == 'smpte2084':
hdr_type = 'HDR10'
elif transfer == 'arib-std-b67':
hdr_type = 'HLG'
elif 'dolby' in str(stream).lower():
hdr_type = 'Dolby Vision'
if hdr_type != 'SDR':
print(f"[{hdr_type}] {video_path}")
print(f" 分辨率: {stream.get('width')}x{stream.get('height')}")
print(f" 编码: {stream.get('codec_name')}")
print(f" 色域: {stream.get('color_primaries')}")
print(f" 传输函数: {transfer}")
return hdr_type
print(f"[SDR] {video_path}")
return 'SDR'
七、批量 HDR→SDR 转换脚本
#!/usr/bin/env python3
"""批量把目录中的 HDR 视频转成 SDR"""
import os
import subprocess
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
def convert_hdr_to_sdr(input_path, output_path, tonemap='hable'):
"""单个视频 HDR→SDR 转换"""
cmd = [
'ffmpeg', '-i', str(input_path),
'-vf',
f'zscale=t=linear:npl=100,format=gbrpf32le,'
f'zscale=p=bt709,tonemap=tonemap={tonemap}:desat=0,'
f'zscale=t=bt709:m=bt709:r=tv,format=yuv420p',
'-c:v', 'libx264', '-preset', 'medium', '-crf', '22',
'-c:a', 'aac', '-b:a', '192k',
str(output_path), '-y'
]
subprocess.run(cmd, capture_output=True, check=True, timeout=3600)
in_size = os.path.getsize(input_path) / 1024 / 1024
out_size = os.path.getsize(output_path) / 1024 / 1024
return in_size, out_size
def batch_convert_hdr(input_dir, output_dir, tonemap='hable', workers=2):
"""批量 HDR→SDR 转换"""
os.makedirs(output_dir, exist_ok=True)
video_exts = {'.mp4', '.mkv', '.webm', '.mov'}
tasks = []
for f in Path(input_dir).iterdir():
if f.suffix.lower() not in video_exts:
continue
if detect_hdr(str(f)) == 'SDR':
print(f"跳过(SDR): {f.name}")
continue
out = Path(output_dir) / f'{f.stem}_SDR.mp4'
if out.exists():
print(f"跳过(已存在): {out.name}")
continue
tasks.append((f, out))
if not tasks:
print("没有需要转换的 HDR 视频")
return
print(f"待转换: {len(tasks)} 个 HDR 视频")
total_saved = 0
with ThreadPoolExecutor(max_workers=workers) as executor:
futures = {executor.submit(convert_hdr_to_sdr, *t, tonemap): t for t in tasks}
for i, future in enumerate(futures):
in_path, out_path = futures[future]
try:
in_size, out_size = future.result()
saved = in_size - out_size
total_saved += saved
print(f"[{i+1}/{len(tasks)}] {in_path.name}: "
f"{in_size:.0f}MB → {out_size:.0f}MB")
except Exception as e:
print(f"[{i+1}/{len(tasks)}] {in_path.name}: 失败 - {e}")
print(f"\n完成!总节省空间: {total_saved:.0f} MB")
if __name__ == '__main__':
batch_convert_hdr('./hdr_videos/', './sdr_output/', tonemap='hable')
八、合规与温馨提示
- HDR 转 SDR 属于视频格式转换,本身是合法的技术操作
- 转换他人版权内容用于再分发属于侵权
- 色调映射会损失部分画质——HDR 的高动态范围在 SDR 上不可能完全还原。如果需要最佳体验,建议升级到 HDR 显示器
- 更多讨论见 下载视频算侵权吗?聊聊个人备份与版权的那条线
HDR 这件事,如果你有 HDR 显示器(包括大部分近几年的 MacBook 和 iPhone),直接下载 HDR 版本用 mpv 或 IINA 播放,体验确实比 SDR 好一个档次。如果你只有普通显示器,就别折腾了——下载时选 SDR 版本,或者用 FFmpeg 转一下。别想着"我下载 HDR 版本存着以后看",HDR 视频在不支持的设备上就是灰白一片,存了也看不了。
本文由 VidDown 技术博客原创发布。VidDown 下载器支持自动检测 HDR 格式,并提供一键 HDR→SDR 转换功能。访问 VidDown 了解更多。