发布时间:2026/9/2 12:04:59
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

相关新闻

2026/9/2 12:04:59

区赛赛道开发实战:用Supabase+Next.js快速构建微型赛事平台

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/2 11:59:59

嵌入式视觉实战:基于RV1126B与IMX415实现1080P@120FPS高帧率方案

在实际嵌入式视觉项目中,高帧率视频采集与处理是衡量方案能力的关键指标。当项目需求从传统的30FPS提升到60FPS甚至120FPS时,整个技术栈——从传感器选型、接口带宽、处理器算力到软件栈优化——都将面临全新的挑战。RV1126B作为一款面向视觉处理的SoC&a…

2026/9/2 11:59:59

Rufus 快速上手:免费制作 USB 启动盘与格式化 U 盘指南

Rufus 快速上手:免费制作 USB 启动盘与格式化 U 盘指南 【免费下载链接】rufus The Reliable USB Formatting Utility 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus 要给新买的电脑装系统,手边只有一个 U 盘和一张 Windows ISO。打开…

2026/9/2 12:20:00

一文搞懂 WSL 安全机制:从端口跟踪到命名空间隔离

一文搞懂 WSL 安全机制:从端口跟踪到命名空间隔离 【免费下载链接】WSL Windows Subsystem for Linux 项目地址: https://gitcode.com/GitHub_Trending/ws/WSL 你在 Windows 上开着 Ubuntu,容器里跑着服务,还顺手挂了个对外端口。它到…

2026/9/2 12:15:00

Tabby 配置 DeepSeek API 完整指南:2处配置接入深度代码补全

Tabby 配置 DeepSeek API 完整指南:2处配置接入深度代码补全 【免费下载链接】tabby Self-hosted AI coding assistant 项目地址: https://gitcode.com/GitHub_Trending/tab/tabby 想在本地编辑器里用上 DeepSeek 的代码补全,又不必把私有仓库推到某朵公共云上,这套组合…

2026/9/1 16:02:17

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/2 9:00:32

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/2 8:41:06

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/2 0:03:41

单片机毕业设计-基于单片机与蓝牙通讯的输液状态监测终端设计与开发 基于 STM32 或 51 单片机的液位‑滴速‑温度多参数输液监护装置设计(024005)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/9/2 0:03:41

DeepSeek字幕翻译实战:从API调用到批量SRT转中文的完整方案

这次我们来看一个很实用的 DeepSeek 落地场景:用 DeepSeek 把英文视频字幕自动翻译成中文。具体案例是《恶魔君》1989 年第 28 集的英转中字幕任务,标题写得很直白,但背后其实是一整套可以复用的技术流程:字幕解析、模型调用、批量…

2026/9/2 0:03:41

用Python搭建搞笑语音助手:从语音识别到语音合成全教程

当你家里摆着一台天猫精灵,却总希望语音助手偶尔“不正经”一点,不用官方腔回答问题,而是张口就接几句搞笑段子,会是什么体验?我最近动手验证了一下这个想法——没有去改装任何市面上现有的智能音箱,而是直…

2026/9/2 1:15:22

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/2 1:15:22

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/2 1:15:20

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…