分享一个Edge浏览器播放H265 RTSP流的问题,涉及到ZLMediaKit、WebRTC

分享一个Edge浏览器播放H265 RTSP流的问题,涉及到ZLMediaKit

问题背景

公司测试环境摄像头有五个,四个大华的,一个海康的,那一个海康的在edge浏览器上播放不了,在chrome浏览器上可以播放,
业务代码逻辑是这样的,这些摄像头都连接了一个硬盘录像机,然后一个后端服务会记录下有哪些流,然后前端可以调用接口查询,查询到在通过ZLMediaKit过滤拉取过来。

核心问题:

  • RTSP摄像头流是 H265 (HEVC) 编码
  • Chrome浏览器 原生支持H265
  • Edge浏览器 不支持H265
  • Edge播放时报错:Assertion failed: (have_active_media, 必须确保最少有一个活跃的track)

错误原因: Edge发送的WebRTC Offer不包含H265编解码器,ZLMediaKit无法找到匹配的编解码器进行协商。


解决方案架构

方案:智能检测 + 自动转码 + 优雅降级

复制代码
┌─────────────────────────────────────────────────────────────┐
│  1. 浏览器H265支持检测                                        │
│     ├─ 支持H265 (Chrome) → 直接拉流播放                      │
│     └─ 不支持H265 (Edge) → 尝试FFmpeg转码                    │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  2. FFmpeg自动转码 (H265 → H264)                             │
│     ├─ 成功 → 播放转码后的H264流                             │
│     └─ 失败 → 回退到直接拉流 (会报错但有明确提示)             │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│  3. WebRTC播放                                               │
│     ├─ 流状态校验 (FFmpeg转码需要更长等待时间)                │
│     ├─ WebRTC信令交换                                        │
│     └─ 视频播放                                              │
└─────────────────────────────────────────────────────────────┘

技术实现细节

1. 提前检测浏览器H265支持

javascript 复制代码
// 创建临时RTCPeerConnection检测编解码器支持
const tempPc = new RTCPeerConnection();
const tempOffer = await tempPc.createOffer({ 
    offerToReceiveVideo: true, 
    offerToReceiveAudio: false 
});
const supportsH265 = tempOffer.sdp.includes('H265') || tempOffer.sdp.includes('H.265');
tempPc.close();

优势:

  • 在拉流之前就知道是否需要转码
  • 避免无效的API调用和资源浪费

2. FFmpeg自动转码配置

关键点:使用RTMP协议作为FFmpeg输出

javascript 复制代码
//  错误:FFmpeg不支持输出到RTSP
dst_url: `rtsp://192.168.3.174:554/live/stream_0_xxx`

//  正确:使用RTMP协议
dst_url: `rtmp://192.168.3.174:1935/live/stream_0_xxx`

API调用:

javascript 复制代码
await axios.post('/index/api/addFFmpegSource', {
    src_url: rtspUrl,                                    // 原始H265流
    dst_url: `rtmp://${ip}:1935/${app}/${streamName}`,  // 转码后的H264流
    timeout_ms: 30000,
    enable_hls: 1,
    enable_mp4: 0,
    secret: secret
});

3. ZLMediaKit配置 (config.ini)

ini 复制代码
[ffmpeg]
# FFmpeg可执行程序路径
bin=F:\project\ffmpeg-7.0.2-full_build\ffmpeg-7.0.2-full_build\bin\ffmpeg.exe

# 转码命令(H265 → H264优化)
cmd=%s -rtsp_transport tcp -i %s -vcodec libx264 -preset ultrafast -tune zerolatency -profile:v baseline -level 3.1 -s 1280x720 -r 15 -b:v 1500k -acodec aac -ar 44100 -ab 48k -f flv %s

# FFmpeg日志路径
log=./ffmpeg/ffmpeg.log

# 截图命令
snap=%s -i %s -y -f mjpeg -frames:v 1 -an %s

# 自动重启时间(秒),0表示不自动重启
restart_sec=0

参数说明:

  • -rtsp_transport tcp:使用TCP传输,减少丢包
  • -preset ultrafast:最快编码速度(实时转码必需)
  • -tune zerolatency:最小延迟
  • -profile:v baseline:最大兼容性
  • -s 1280x720:降低分辨率(从2560x1440降到720p)
  • -r 15:降低帧率(从25fps降到15fps)
  • -b:v 1500k:合理的720p码率
  • -f flv:输出FLV格式(配合RTMP协议)

4. 流状态校验优化

javascript 复制代码
// FFmpeg转码需要更长的初始化时间
const maxRetries = usedFFmpeg ? 20 : 5;   // 40秒 vs 5秒
const retryDelay = usedFFmpeg ? 2000 : 1000;

const isOnline = await this.checkStreamOnline(streamName, maxRetries, retryDelay);

原因:

  • 直接拉流:几乎立即可用
  • FFmpeg转码:需要时间初始化、解码、编码、推流

工作流程对比

Chrome浏览器(支持H265)

复制代码
1. 检测到支持H265 
2. 直接拉流 (addStreamProxy)
3. 流状态校验 (5秒内)
4. WebRTC播放 H265流
5. 播放成功 

Edge浏览器(不支持H265)

复制代码
1. 检测到不支持H265 
2. 尝试FFmpeg转码 (addFFmpegSource)
   ├─ 成功 → 推流到 rtmp://ip:1935/live/stream_xxx
   └─ 失败 → 回退到直接拉流
3. 流状态校验 (40秒内,等待转码完成)
4. WebRTC播放 H264流
5. 播放成功 

还有一个方式好像是因为海康的流使用的是主码流

相关推荐
qcx232 小时前
【AI Agent实战】 0 成本视频处理全流程:ffmpeg + whisper 实现去水印、双语字幕、品牌片尾 | 实战SOP
人工智能·ffmpeg·音视频
huxiao_06012 小时前
Windosw下VS 2022编译FFmpeg(支持x264、x265、fdk-acc)
ffmpeg·音视频
F_D_Z2 小时前
Causal Forcing:自回归扩散蒸馏与高质量实时交互视频生成
数据挖掘·回归·音视频
骨子里的偏爱3 小时前
.raw后缀的文件转为jpg(压缩视频流转图片)
音视频
码云数智-园园3 小时前
告别Flash:HTML5音视频播放器实战指南
前端·音视频·html5
热爱专研AI的学妹13 小时前
Seedance 2.0(即梦 2.0)深度解析:AI 视频正式迈入导演级精准可控时代
大数据·人工智能·阿里云·音视频
byte轻骑兵17 小时前
从收音机到蓝牙:LE Audio核心BASS服务解析与实战
人工智能·音视频·语音识别·le audio·低功耗音频
双普拉斯17 小时前
打造工业级全栈文件管理器:深度解析上传、回收站与三重下载流控技术
spring·vue·js