总体思路
- 使用ffmpeg推流到nginx
- nginx将RTSP 转为 HLS,保存为ts切片
- 前端使用hls进行播放
ffmpeg
运行命令
ffmpeg -rtsp_transport tcp -re -i rtsp://admin:123456@192.168.1.64:554/h265/ch1/main/av_stream -c copy -s 2688x1520 -f flv -r 25 rtmp://192.168.1.17:1935/hls/testtv
| 属性 | 详解 | 对应代码 |
|---|---|---|
| rtmp链接 | nginx-rtmp-module 中开启的地址。推流到nginx上。 | rtmp://192.168.1.17:1935/hls/testtv |
| rtsp链接 | 摄像头的rtsp链接地址。拉流 | rtsp://admin:123456@192.168.1.64:554/h265/ch1/main/av_stream |
| 解决花屏问题 | 强制使用tcp连接 | -rtsp_transport tcp |
| 设置画面大小 | -s 2688x1520 | |
| 设置编码方式 | -f flv | |
| 设置帧率 | -r 25 | |
| 去除音频 | -an |
nginx-rtmp
window下编译麻烦,使用别人下载好的包。原链接找不到了,感谢原作者的无情分享。 链接:pan.baidu.com/s/1nod1Iv9_… 提取码:e0nt
配置
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;
rtmp {
server {
listen 1935;
application myapp {
live on;
# gop_cache on; #打开 GOP 缓存,减少首屏等待时间 }
}
application live {
live on;
}
application hls { #ffmpeg推流到的地址
live on;
hls on;
hls_path temp/hls; #存放切片的地址
hls_fragment 3s; #切片长度
}
}
}
http {
server {
listen 8822;
location / {
root html;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root html;
}
location /test {
alias html/test;
autoindex on;
}
location /hls { #前端访问地址
#server hls fragments
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias temp/hls;
expires -1;
add_header Cache-Control no-cache;
}
}
}
cmd到nginx.exe目录下
| 功能 | 命令 |
|---|---|
| 启动 | start nginx |
| 重启 | nginx -s reload |
| 停止 | stop nginx |
推流地址
以rtmp://192.168.1.17:1935/hls/testtv
- 192.168.1.17 为本机ip地址
- 1935为rtmp模块的端口号
- /hls 为application 中配置的地址
- testtv 为文件名,随便起,后面访问需要用到。
web访问地址
http://192.168.1.17:8822/hls/testtv.m3u8
- 192.168.1.17 为本机ip地址
- 8822为http模块的端口号
- /hls 为location中配置的地址
- testtv为文件名,需要和推流中的文件名一致。
VLC 测试工具
下载地址
链接:pan.baidu.com/s/1YGLlxkzH… 提取码:ngjw
使用
ctrl + n
点击播放即可
web前端展示
安装hls插件
npm install hls.js
使用
这里以vue3 ts 为例
<template>
<video id="videoElement" controls autoplay muted width="300px" height="200px">
</video>
</template>
<script setup lang="ts">
import Hls from 'hls.js';
import { onMounted } from 'vue';
const url = "/hls/testtv.m3u8"
onMounted(() => {
const videoElement = document.getElementById('videoElement') as HTMLMediaElement;
initHls(videoElement)
})
const initHls = (videoElement: HTMLMediaElement) => {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(videoElement);
}
</script>
解决跨域问题
vite.config.ts 设置 代理
export default defineConfig({
plugins: [
vue(),
vueJsx(),
VueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
//代码开始
server:{
proxy:{
'/hls':{//要代理的地址标识
target: 'http://192.168.1.17:8822/',//转发到目标地址
changeOrigin: true,
// rewrite: path => path.replace(/^\/hls/, 'hls')
}
}
}
//代码结束
})
以http://localhost/hls/testtv.m3u8为例 匹配到目标地址/hls,转发到target中的目标地址:http://192.168.1.17:8822 最终地址:http://192.168.1.17:8822/hls/testtv.m3u8
参考文档
在Web网页播放网络摄像机(海康、大华等)RTSP视频流方案汇总_web摄像头项目-CSDN博客