web通过ffmpeg 、nginx-rtmp 将RTSP转为hls播放流程记录,不依赖flash(附相关文件)。

919 阅读2分钟

总体思路

  1. 使用ffmpeg推流到nginx
  2. nginx将RTSP 转为 HLS,保存为ts切片
  3. 前端使用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

image.png

点击播放即可

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博客

至此结束,实时性不是很高,欢迎评论互相学习讨论。下一步打算了解一下webrtc。