猫咪如厕检测与分类识别系统系列~进阶【一】视频流推流及网页实时展示
前情提要
家里养了三只猫咪,其中一只布偶猫经常出入厕所。但因为平时忙于学业,没法时刻关注牠的行为。我知道猫咪的如厕频率和时长与健康状况密切相关,频繁如厕可能是泌尿问题,停留过久也可能是便秘或不适。为了更科学地了解牠的如厕习惯,我计划搭建一个基于视频监控和AI识别的系统,自动识别猫咪进出厕所的行为,记录如厕时间和停留时长,并区分不同猫咪。这样即使我不在家,也能掌握猫咪的健康状态,更安心地照顾它们。
🎓 各位的关注与点赞是我持续分享的最大动力,衷心感谢大家的支持!
📢 欢迎正在攻读硕博学位的同学,或是对人工智能充满热情的朋友们,关注我的个人公众号。在这里,我将持续更新博士期间阅读的前沿论文解读、项目实战经验分享,以及我对AI技术趋势的思考与探讨。
✨ 无论你是科研工作者、工程开发者,还是AI初学者,都能在这里找到干货与灵感。让我们一起交流、成长、探索人工智能的无限可能!
已完成工作:
✅猫咪如厕检测与分类识别系统系列【一】 功能需求分析及猫咪分类特征提取
✅猫咪如厕检测与分类识别系统系列【二】多图上传及猫咪分类特征提取更新
✅猫咪如厕检测与分类识别系统系列【三】 融合yolov11目标检测
✅猫咪如厕检测与分类识别系统系列【四】融合检测日志输出及前端展示界面制作
✅猫咪如厕检测与分类识别系统系列【五】信息存储数据库改进+添加猫咪页面制作+猫咪躯体匹配算法架构更新
✅猫咪如厕检测与分类识别系统系列【六】分类模型训练+混合检测分类+未知目标自动更新
✅猫咪如厕检测与分类识别系统系列【七】 当前阶段总结报告
✅猫咪如厕检测与分类识别系统系列【八】 检测推理事件整合+视频推流架构分析
✅猫咪如厕检测与分类识别系统系列【九】 视频检测区域在线绘制+支持摄像头+网络摄像头+整体构建【上】
✅猫咪如厕检测与分类识别系统系列【九】 视频检测区域在线绘制+支持摄像头+网络摄像头+整体构建【下】
✅猫咪如厕检测与分类识别系统系列【十】 视频检测区域动态监测及实时更新
✅猫咪如厕检测与分类识别系统系列【十一】区域进入事件相应逻辑鲁棒性更新
✅猫咪如厕检测与分类识别系统系列【十二】猫咪进出事件逻辑及日志优化【上】
✅猫咪如厕检测与分类识别系统系列【十三】猫咪进出事件逻辑及日志优化【下】
本小节将实现进阶功能,将检测画面实时推送到流媒体服务器(如 RTMP / RTSP / WebRTC) ,并在前端网页上实时观看效果。
使用 FFmpeg + RTMP 推流
📺 架构简图:
[摄像头] → [检测 + 标注帧] → [FFmpeg 推流] → [ZLMediaKit视频服务器] → [网页播放]
效果图:
开始推流后推流服务器显示数据:
开始推流后FFMPEG显示数据
电脑端访问 FLV 推流地址:
使用DEBUG 模式测试手机端访问 HLV 地址:
FFmpeg 子进程推流
📌 步骤:
- 安装
ffmpeg
,并保证在系统路径中可用 - 启动子进程,把每帧传给 FFmpeg(pipe)
- FFmpeg 推送到 RTMP 地址(如:
rtmp://server/live/stream
)
代码(Python 推送检测帧)
import subprocess
import cv2class StreamPusher:def __init__(self, width=960, height=720, fps=25, rtmp_url="rtmp://localhost/live/stream"):self.process = subprocess.Popen(['ffmpeg','-y','-f', 'rawvideo','-pix_fmt', 'bgr24','-s', f'{width}x{height}','-r', str(fps),'-i', '-', # 从 stdin 读取'-c:v', 'libx264','-preset', 'ultrafast','-f', 'flv',rtmp_url], stdin=subprocess.PIPE)def write(self, frame):self.process.stdin.write(frame.tobytes())def close(self):self.process.stdin.close()self.process.wait()
✅ 使用方式:
pusher = StreamPusher(rtmp_url="rtmp://your_server/live/catstream")while True:ret, frame = cap.read()annotated = detector.process(frame) # 检测 + 标注pusher.write(annotated)
✅ Web 页面播放
只需要用 Video.js 或 hls.js 实现网页播放:
<video id="player" autoplay controls width="960" height="720"><source src="rtmp://your_server/live/catstream" type="rtmp/flv">
</video>
或使用中转转为 HLS (.m3u8
) 或 WebRTC 以兼容所有浏览器。
我使用的是ZLMediaKit服务器,它支持非常丰富的流媒体协议,想在 HTML 网页中播放实时视频,推荐使用 HLS (HTTP Live Streaming) ,它是:
✅ 浏览器原生支持(通过 <video>
标签或 hls.js)
✅ ZLMediaKit 默认就支持 HLS 输出
✅ 相比 RTMP 更适合网页端播放
✅ 实现目标:检测结果 ➜ HLS 推送 ➜ HTML 页面播放
步骤:
① FFmpeg 推流至 ZLMediaKit(RTMP 输入)
你从 Python 使用 FFmpeg
把检测帧推到:
rtmp://<your_server_ip>/live/your_stream_name
ZLMediaKit 自动会转码成:
http://<your_server_ip>:8080/live/your_stream_name/hls.m3u8
② 网页中播放(用 HLS.js)
<video id="video" controls autoplay width="960" height="720"></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>var video = document.getElementById('video');var videoSrc = 'http://<your_server_ip>:8080/live/your_stream_name/hls.m3u8';if (Hls.isSupported()) {var hls = new Hls();hls.loadSource(videoSrc);hls.attachMedia(video);} else if (video.canPlayType('application/vnd.apple.mpegurl')) {video.src = videoSrc;}
</script>
替换 <your_server_ip>
和 your_stream_name
即可。
③ FFmpeg + Python 推流代码(StreamPusher)
import subprocess
import cv2class StreamPusher:def __init__(self, width=960, height=720, fps=25, rtmp_url="rtmp://127.0.0.1/live/cat"):self.width = widthself.height = heightself.process = subprocess.Popen(["ffmpeg","-y","-f", "rawvideo","-vcodec", "rawvideo","-pix_fmt", "bgr24","-s", f"{width}x{height}","-r", str(fps),"-i", "-","-c:v", "libx264","-preset", "ultrafast","-tune", "zerolatency","-f", "flv",rtmp_url], stdin=subprocess.PIPE)def write(self, frame):if frame is not None and frame.shape[0] == self.height and frame.shape[1] == self.width:self.process.stdin.write(frame.tobytes())def close(self):self.process.stdin.close()self.process.wait()
🧪 示例地址结构(ZLMediaKit 默认)
协议 | 示例地址 |
---|---|
RTMP 推流 | rtmp://your_ip/live/cat |
HTTP-FLV | http://your_ip:8080/live/cat.live.flv |
HLS(推荐) | http://your_ip:8080/live/cat/hls.m3u8 |
WebRTC(更低延迟) | http://your_ip:8000/index/api/webrtc?app=live&stream=cat |
下面是ZLMediaKit启动成功后的界面:
以下是一个完整的 基于 HLS(m3u8)格式的 HTML 页面 ,可直接在网页中播放你用 ZLMediaKit 推送的猫咪检测视频流
cat_stream.html
(完整版 HTML,支持所有主流浏览器)
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>猫咪检测实时流</title><style>body {background: #f0f0f0;font-family: sans-serif;text-align: center;padding-top: 30px;}video {border: 4px solid #333;border-radius: 8px;}h2 {color: #444;}</style>
</head>
<body><h2>🐱 猫咪实时检测流(HLS)</h2><video id="video" width="960" height="720" controls autoplay muted></video><script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script><script>const video = document.getElementById('video');const streamUrl = 'http://<你的服务器IP>:8080/live/cat/hls.m3u8'; // ← 替换为你的真实地址if (Hls.isSupported()) {const hls = new Hls();hls.loadSource(streamUrl);hls.attachMedia(video);hls.on(Hls.Events.MANIFEST_PARSED, () => {video.play();});} else if (video.canPlayType('application/vnd.apple.mpegurl')) {// Safari 支持原生 HLSvideo.src = streamUrl;video.addEventListener('loadedmetadata', () => {video.play();});} else {alert("当前浏览器不支持 HLS 播放!");}</script>
</body>
</html>
使用说明:
内容 | 填写 |
---|---|
<你的服务器IP> | 如:192.168.0.100 或公网 IP |
cat | 为你的推流名,如 rtmp://ip/live/cat 推的就用 cat |
示例地址:
假设你推到:
rtmp://192.168.0.88/live/cat
那么播放地址是:
http://192.168.0.88:8080/live/cat/hls.m3u8
ZLMediaKit 默认支持 HTTP-FLV(.flv
)播放 ,它的优点是:
✅ 延迟比 HLS 更低
✅ 浏览器兼容性好(配合 flv.js 使用)
✅ 使用方式简单(不需要编码器支持 WebRTC)
✅ cat_stream_flv.html(FLV 播放版本)
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>猫咪检测实时流(FLV)</title><style>body {background: #f5f5f5;font-family: sans-serif;text-align: center;padding-top: 30px;}video {border: 3px solid #222;border-radius: 6px;}h2 {color: #444;}</style>
</head>
<body><h2>🐱 猫咪检测实时流(FLV)</h2><video id="videoElement" controls autoplay muted width="960" height="720"></video><!-- 引入 flv.js --><script src="https://cdn.jsdelivr.net/npm/flv.js@latest/dist/flv.min.js"></script><script>const videoElement = document.getElementById('videoElement');const flvUrl = 'http://<你的服务器IP>:8080/live/cat.live.flv'; // 替换为你的实际流地址if (flvjs.isSupported()) {const flvPlayer = flvjs.createPlayer({type: 'flv',url: flvUrl});flvPlayer.attachMediaElement(videoElement);flvPlayer.load();flvPlayer.play();} else {alert("❌ 当前浏览器不支持 FLV 播放,请使用 Chrome 或新版 Edge");}</script>
</body>
</html>
使用说明
项目 | 内容 |
---|---|
推流地址 | rtmp://your_server_ip/live/cat(用 FFmpeg) |
FLV 播放地址 | http://your_server_ip:8080/live/cat.live.flv |
视频标签 | 原生video标签 + flv.js 注入播放能力 |
示例
如果你推流到:
rtmp://192.168.0.88/live/cat
那么播放地址是:
http://192.168.0.88:8080/live/cat.live.flv
下一章节:把这个界面集成到主界面上去,然后给该界面设置一个开起关闭视频展示的功能
融合推流和视频展示的任务管理界面如下: