ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WebRTC(TODO)

WebRTC(TODO) 1 简介只是简单学学。。。简单看了下貌似就是SIP的下一代。因为我对SIP很熟所以就比对着来写。传统的SIPWebRTC网络端终端2 树莓派的实现代码webrtc-pi/ ├── server.py ├── static/ │ └── client.htmlserver.pyimport cv2 import asyncio from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription from aiortc.contrib.media import MediaRelay from flask import Flask, render_template, request, jsonify, send_from_directory import json app Flask(__name__, static_url_path) pcs set() relay MediaRelay() # 视频采集轨道OpenCV class VideoTrack(MediaStreamTrack): kind video def __init__(self): super().__init__() self.cap cv2.VideoCapture(0) async def recv(self): pts, time_base await self.next_timestamp() ret, frame self.cap.read() if not ret: return None # 关键OpenCV 转 RGB frame cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) from av import VideoFrame video_frame VideoFrame.from_ndarray(frame, formatrgb24) video_frame.pts pts video_frame.time_base time_base return video_frame app.route(/) def index(): return send_from_directory(static, client.html) app.route(/offer, methods[POST]) def offer(): offer_sdp request.get_json() pc RTCPeerConnection() pcs.add(pc) video VideoTrack() pc.addTrack(video) async def create_answer(): await pc.setRemoteDescription(RTCSessionDescription(**offer_sdp)) answer await pc.createAnswer() await pc.setLocalDescription(answer) return pc.localDescription loop asyncio.new_event_loop() asyncio.set_event_loop(loop) desc loop.run_until_complete(create_answer()) return jsonify({sdp: desc.sdp, type: desc.type}) app.route(/answer, methods[POST]) def answer(): return OK if __name__ __main__: app.run(host0.0.0.0, port5000)client.html!DOCTYPE html html head titleRaspberry Pi WebRTC Camera/title /head body h2WebRTC Camera Stream/h2 video idvideo autoplay playsinline controls/video script const pc new RTCPeerConnection(); const video document.getElementById(video); pc.ontrack function (event) { video.srcObject event.streams[0]; }; fetch(/offer, { method: POST }) .then(res res.json()) .then(async ({ sdp, type }) { await pc.setRemoteDescription({ sdp, type }); const answer await pc.createAnswer(); await pc.setLocalDescription(answer); fetch(/answer, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(pc.localDescription), }); }); /script /body /htmlTODO树莓派摄像头 WebRTC 低延迟视频流部署记录环境树莓派 5 Model Baarch64Raspberry Pi OS / Debian trixie· 摄像头 OV5647CSI 排线CAM0 口· WiFiziroom201-2_5G · IP192.168.124.34 · 用户tom 目标在局域网内的电脑/手机浏览器中直接观看摄像头实时画面延迟 200~500ms对比最初 MJPEG 方案的 1~3 秒一、整体架构OV5647 摄像头 (1280x720 15fps, MJPEG 编码) │ rpicam-vid (libcamera 官方工具) ▼ stdout MJPEG 帧流 │ ffmpeg 转码 (libvpx 实时模式 → VP8) ▼ RTSP 推流 (rtsp://127.0.0.1:8554/cam) │ ▼ MediaMTX 流媒体网关 ├─ WebRTC (WHEP) → 浏览器 http://IP:8889/cam ← 低延迟观看入口 ├─ RTSP server → :8554 ├─ HLS → :8888 (默认开) └─ RTMP / SRT → :1935 / :8890 (默认开)为什么绕道 VP8 而不用 H.264本机装的是rpicam-apps-lite精简版不含 H.264 编码器rpicam-vid --codec h264会报ERROR: *** Unable to find an appropriate H.264 codec ***树莓派 5 没有硬件 H.264 编码器完整版靠 libavcodec 软编。在等完整版安装期间改用 ffmpeg 自带的libvpxVP8软编绕开限制WebRTC 同样原生支持 VP8延迟效果相同。二、前置条件树莓派已联网WiFi/网线均可知道其 IP摄像头已接好且被识别rpicam-hello --list-cameras # 应输出类似 # 0 : ov5647 [2592x1944 10-bit GBRG] (/base/axi/pcie1000120000/rp1/i2c80000/ov564736)系统已开启摄像头自动检测默认/boot/firmware/config.txt里有camera_auto_detect1无需改动三、部署步骤步骤 1安装 ffmpeg负责 MJPEG→VP8 转码和 RTSP 推流sudo apt-get update sudo apt-get install -y ffmpeg ffmpeg -version # 验证本次安装的是 7.1.5步骤 2下载并安装 MediaMTX单文件流媒体网关cd /home/tom # 获取 arm64 版本v1.20.1树莓派5 用 linux_arm64 curl -L -o mediamtx.tar.gz \ https://github.com/bluenviron/mediamtx/releases/download/v1.20.1/mediamtx_v1.20.1_linux_arm64.tar.gz mkdir -p mediamtx tar -xzf mediamtx.tar.gz -C mediamtx # 解压出 mediamtx 可执行文件 默认配置 mediamtx.yml注意MediaMTX v1.20.1 的配置文件是位置参数没有-c选项直接在配置文件所在目录运行./mediamtx它会自动读取当前目录的mediamtx.yml。使用默认配置即可无需修改默认已开启 RTSP 8554 与 WebRTC 8889。 踩坑记录自定义精简配置时报unknown field webrtcLocalCandidate新版字段名有变化所以放弃自定义、回归默认配置。步骤 3启动 MediaMTX 网关cd /home/tom/mediamtx setsid ./mediamtx mediamtx.out 21 /dev/null 验证两条都要有输出才算成功ss -tlnp | grep -E 8554|8889 tail -25 mediamtx.out # 应看到: [RTSP] started with listeners on :8554 ... # [WebRTC] started with listeners on :8889 (TCP/HTTP), :8189 (UDP/ICE)步骤 4启动摄像头推流核心命令cd /home/tom setsid bash -c rpicam-vid -t 0 --codec mjpeg --width 1280 --height 720 --framerate 15 --inline -o - 2/home/tom/push_rpicam.err \ | ffmpeg -hide_banner -loglevel warning -f mjpeg -probesize 5000000 -analyzeduration 5000000 -i pipe:0 \ -c:v libvpx -deadline realtime -cpu-used 8 -b:v 2M -threads 4 \ -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/cam \ /dev/null /home/tom/push_ffmpeg.log 21 参数说明rpicam-vid -t 0 --codec mjpeg ... -o -持续拍摄并输出 MJPEG 帧流到管道-t 0表示不限时长-f mjpeg -i pipe:0ffmpeg 从管道读取 JPEG 帧序列-c:v libvpx -deadline realtime -cpu-used 8VP8实时编码模式牺牲压缩率换低延迟务必带上-b:v 2M -threads 42 Mbps 码率、4 线程编码Pi5 四核扛得住-f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/cam以 RTSP 方式推给 MediaMTX路径名camsetsid ... /dev/null ... 让进程完全脱离 SSH 会话断开后仍运行见踩坑 3验证推流成功关键看 MediaMTX 日志tail -8 /home/tom/mediamtx/mediamtx.out # 应看到: # INF [path cam] stream is available and online, 1 track (VP8) # INF [RTSP] [session xxx] is publishing to path cam ps aux | grep -E rpicam-vid|ffmpeg | grep -v grep # 两个进程都应存活步骤 5浏览器观看http://192.168.124.34:8889/cam页面即 MediaMTX 内置的 WebRTC 播放器WHEP 协议点开自动播放。手机连同一 WiFi 访问同样地址。四、踩坑记录按出现顺序#问题现象原因解决1第一版 MJPEG HTTP 方案延迟 1~3 秒每帧一张完整 JPEG、HTTP 缓冲、无帧间压缩升级 WebRTC本方案2推流一直失败Output file does not contain any stream根因是rpicam-vid --codec h264报Unable to find an appropriate H.264 codec而脚本把 stderr 丢弃了看不到先apt install rpicam-apps完整版替换 lite或临时改用 VP8 软编本次采用3SSH 里后台启动服务后本地脚本/命令卡死不返回nohup xxx 后台进程继承了 SSH 通道的 stdin通道 EOF 永远不来后台进程完全重定向setsid cmd log 21 /dev/null 4pkill -f rpicam-vid执行后目标进程还在且命令本身异常退出pkill -f按命令行模糊匹配把包含该字符串的当前 shell 自己也杀掉了自杀后面的进程没杀到用kill -9 PID精确杀或pkill -9 -x rpicam-vid-x精确匹配进程名不含命令行5MediaMTX 报unknown flag -cv1.20.1 配置文件是位置参数不支持-c直接./mediamtx自动读当前目录mediamtx.yml或./mediamtx mediamtx.yml6MediaMTX 报unknown field webrtcLocalCandidate新版配置字段名与旧文档不一致直接使用发行包自带的默认mediamtx.yml7上传的 .sh 脚本报$\r: command not foundWindows 编辑的文件是 CRLF 换行sed -i s/\r$// script.sh或干脆用 Python 字符串拼命令远程执行8apt-get install报Could not open lock file ... Permission denied管道命令中后半段没加 sudoecho 密码 | sudo -S apt-get install ...整条都走 sudo五、常用管理命令# 查看流状态是否 online、有无观看者 tail -5 /home/tom/mediamtx/mediamtx.out # 停止推流MediaMTX 会继续运行页面显示离线 pkill -x rpicam-vid; pkill -x ffmpeg # 重启推流即上方步骤 4整条命令 # 重启 MediaMTX pkill -x mediamtx cd /home/tom/mediamtx setsid ./mediamtx mediamtx.out 21 /dev/null 六、后续优化可选1. 切换 H.264 1080p30画质更好、CPU 更省待rpicam-apps完整版安装完成后dpkg -l | grep rpicam-apps确认不再是 lite把推流命令换成cd /home/tom setsid bash -c rpicam-vid -t 0 --codec h264 --width 1920 --height 1080 --framerate 30 --inline -o - 2/dev/null \ | ffmpeg -hide_banner -loglevel warning -f h264 -probesize 5000000 -analyzeduration 5000000 -i pipe:0 \ -c copy -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/cam \ /dev/null /home/tom/push_ffmpeg.log 21 H.264 是-c copy零转码直推CPU 占用几乎为 0画质和帧率都更好。2. 开机自启可选把 MediaMTX 和推流命令写成 systemd 服务/etc/systemd/system/mediamtx.service、cam-push.servicesystemctl enable即可开机自动运行。七、本次工作区生成的辅助文件清单位于C:\Users\dancejc\.cline\data\workspaces\chat\文件用途mjpg_server.py第一版方案MJPEG-over-HTTP 流服务器已上传到树莓派 /home/tom/现已被 WebRTC 方案替代setup_webrtc.shWebRTC 一键部署脚本树莓派端deploy_webrtc.py/fix_webrtc_v2.py/push_webrtc.py/start_vp8.py等本地 Python 部署/诊断脚本paramiko SSH 自动化*_log.txt各阶段部署日志文档生成时间2026-09-01 · 实测延迟200~500ms · 画面1280x720 15fps VP8
返回列表