须知
市面上大部分网络摄像头都支持RTSP协议视频流,web端无法直接使用RTSP实现视频预览,需要通过转换变成video标签能直接访问的视频流。
原理
- ffmpeg视频工具将从摄像头获取到的RTSP协议视频流转换为flv格式的视频流
- 将flv视频推送到Nginx的某个端口
- 前端video标签直接绑定nginx的url
工具安装
下载三方工具养成好习惯,将下载的文件放到 /opt
目录下
安装gcc&gcc-c++
由于后面的工具都会用到C和C++编译,所以需要先安装gcc&gcc-c++
yum install -y gcc gcc-c++
安装Nginx
安装pcre
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
tar -zxvf pcre-8.35.tar.gz
cd pcre-8.35
./configure
make && make install
安装zlib
wget http://zlib.net/zlib-1.2.13.tar.gz
tar -zxf zlib-1.2.13.tar.gz
cd zlib-1.2.13
./configure
make && make install
安装openssl
wget http://www.openssl.org/source/openssl-fips-2.0.10.tar.gz
tar -zxvf openssl-fips-2.0.10.tar.gz
cd openssl-fips-2.0.10
./config && make && make install
下载nginx的flv模块
此模块为第三方模块,需要从Github上下载
git clone https://github.com/winshining/nginx-http-flv-module.git
完成nginx安装
wget http://nginx.org/download/nginx-1.10.2.tar.gz
tar zxvf nginx-1.10.2.tar.gz
cd nginx-1.10.2
# 编译时指定nginx-http-flv-module的目录
./configure --add-module=/opt/nginx-http-flv-module
make && make install
完成安装的nginx位于 /usr/local/nginx
目录下
nginx配置
完整的配置参考nginx-http-flv-module最后给出的example configuration
这里是我的nginx配置
# /usr/local/nginx/conf/nginx.conf
worker_processes 1;
error_log logs/error.log error;
events {
worker_connections 4096;
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
# 重要 http-flv 转流配置
location /myapp {
flv_live on; #打开 HTTP 播放 FLV 直播流功能
chunked_transfer_encoding on; #支持 'Transfer-Encoding: chunked' 方式回复
add_header 'Access-Control-Allow-Origin' '*'; #添加额外的 HTTP 头-跨域
add_header 'Access-Control-Allow-Credentials' 'true'; #添加额外的 HTTP 头
add_header 'Cache-Control' 'no-cache';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s; #log模块在access.log中记录日志的间隔时间,对调试非常有用
log_size 1m; #log模块用来记录日志的缓冲区大小
server {
# 此端口是ffmpeg推送视频流给nginx的端口
listen 1935;
# 注意myapp要和上面80端口配置的location一致
application myapp {
live on;
gop_cache on; #打开GOP缓存,减少首屏等待时间
}
}
}
启动nginx
cd /usr/local/nginx/sbin
./nginx
安装ffmpeg
关于ffmpeg,参考官网,简单来说就是一个音视频领域的处理工具。
因为ffmpeg是不原生支持H264格式的视频的,而flv又需要H264,咱们先手动安装x264
安装x264
安装nasm
wget https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/nasm-2.13.03.tar.gz
tar -xvf nasm-2.13.03.tar.gz
cd nasm-2.13.03/
./configure
make && make install
# 验证是否已安装
[root@CAP nasm-2.13.03]# nasm -version
NASM version 2.13.03 compiled on Apr 7 2024
安装yasm
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0/
./configure
make && sudo make install
# 验证是否已安装
[root@CAP yasm-1.3.0]# yasm --version
yasm 1.3.0
Compiled on Apr 3 2024.
Copyright (c) 2001-2014 Peter Johnson and other Yasm developers.
Run yasm --license for licensing overview and summary.
安装x264
git clone https://code.videolan.org/videolan/x264.git
cd x264/
./configure --enable-shared --enable-static
make && make install
# 验证是否已安装
[root@CAP x264]# x264 --version
x264 0.164.3190 7ed753b
built on Apr 7 2024, gcc: 4.8.5 20150623 (Red Hat 4.8.5-44)
x264 configuration: --chroma-format=all
libx264 configuration: --chroma-format=all
x264 license: GPL version 2 or later
安装pkg
# 检查是否已安装pkg
[root@CAP opt]# pkg-config --version
0.27.1
# 如已安装可跳过此安装步骤
wet https://pkg-config.freedesktop.org/releases/pkg-config-0.27.1.tar.gz
tar -zxvf pkg-config-0.27.1.tar.gz
cd pkg-config-0.27.1
./configure
make
make check
make install
安装ffmpeg
wget http://www.ffmpeg.org/releases/ffmpeg-4.1.tar.gz
tar -zxvf ffmpeg-4.1.tar.gz
# 创建ffmpeg文件夹,指定安装目录
mkdir /opt/ffmpeg
cd /opt/ffmpeg-4.1
./configure --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-static --disable-shared --enable-encoder=libx264 --extra-libs=-ldl
make && make install # 这一步很慢,大概5-10分钟
# 配置环境变量
vi /etc/profile
# 在最后PATH添加环境变量:
export PATH=$PATH:/usr/local/ffmpeg/bin
# 保存退出
source /etc/profile
# 将ffmepg的lib目录和x264的lib链接到系统库中
vi /etc/ld.so.conf
# 在文档后追加
/opt/ffmpeg/lib/
/usr/local/lib/ # 可以通过 find / -name 'libx264.so.164' 查找x264的lib目录
# 使配置生效
ldconfig
# 查看版本,测试是否生效
ffmpeg --version
# 验证安装
[root@CAP opt]# ffmpeg -version
ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44)
configuration: --prefix=/usr/local/ffmpeg --enable-gpl --enable-libx264 --enable-static --disable-shared --enable-encoder=libx264 --extra-libs=-ldl
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
到此ffmpeg和nginx都已经安装完成了,接下只需要执行ffmepg相关的命令开始推流进行转换操作,之后配和nginx对转换后的流进行访问,就可以在页面上实现实时预览了
ffmpeg转换并推流
ffmpeg -ss 0:01 -rtsp_transport tcp -i rtsp://admin:Huit@1688@192.168.50.13:554/Streaming/Channels/101 -c:v libx264 -c:a copy -f flv rtmp://127.0.0.1:1935/myapp/101
命令参数介绍
-ss 0:01
: 指定从源视频的开始算起1秒处开始处理。这可以用来跳过视频的开始部分,或从指定的时间点开始处理视频-rtsp_transport tcp
: 指定使用TCP协议来接收RTSP流-i rtsp://admin:Huit@1688@192.168.50.13:554/Streaming/Channels/101
: -i 参数后面跟着的是输入源的地址。这里使用RTSP协议接收来自摄像头或流媒体服务器的流。URL包含了认证信息(用户名和密码),IP地址,端口号以及流的路径-c:v libx264
: 指定视频编码器为libx264,这意味着视频流会被转码为H.264编码。这是一种广泛使用的视频压缩标准,兼容性很好-c:a copy
: 对于音频,这个参数告诉FFmpeg直接复制音频流,不进行转码。这样可以保留原始音频质量并减少处理时间-f flv
: 指定输出格式为FLV(Flash视频)rtmp://127.0.0.1:1935/myapp/101
: 指定输出的RTMP服务器地址,也就是上面nginx配置的rtmp部分
执行上面的命令看到下列面输出即表示转换并推流成功
Web取流
取流地址
http://192.168.30.103:80/myapp?port=1935&app=myapp&stream=101
地址说明:
http://192.168.30.103:80/myapp
: 这是上面nginx配置的http部分port=1935
: 上面nginx配置的rtmp部分的端口app=myapp
: 上面nginx配置的rtmp部分的application部分stream=101
: 表示通道号,这里要和上面ffmpeg转换命令中的通道号对应
注意:
- 单个摄像头如果有多个通道,通道号既可以是从高1开始,也可以从101开始,比如101,102...
- 如果是录像机连接的多个摄像头,比如
rtsp://admin:Huit@1688@192.168.50.13:554/Streaming/Channels/101
这个地址连接的事录像机,那么通道就应该是101,201,301...这样的
vue2示例
安装flv.js
npm install flv.js
代码
在template标签中放入下面的代码
<div class="xpanel">
<video id="videoElement" ref="videoElement" controls autoplay muted style="width: auto; height: 100%;" />
</div>
下面是script部分
<script>
import flvjs from 'flv.js'
export default {
name: 'FlvPlayer',
mounted() {
this.createFlvPlayer()
},
beforeDestroy() {
this.destroyFlvPlayer()
},
methods: {
createFlvPlayer() {
if (flvjs.isSupported()) {
const videoElement = this.$refs.videoElement
const flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://192.168.30.103:80/myapp?port=1935&app=myapp&stream=101'
})
flvPlayer.attachMediaElement(videoElement)
flvPlayer.load()
flvPlayer.play()
this.flvPlayer = flvPlayer // Store the player for later use
}
},
destroyFlvPlayer() {
if (this.flvPlayer) {
this.flvPlayer.destroy()
this.flvPlayer = null
}
}
}
}
</script>
附
参考
https://blog.csdn.net/weixin_55775322/article/details/132338524
https://blog.csdn.net/Jason_i7/article/details/126598504
纯html示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FLV Stream Test</title>
<script src="https://cdn.jsdelivr.net/npm/flv.js@1.5.0/dist/flv.min.js"></script>
</head>
<body>
<video id="videoElement" controls autoplay muted style="width: 40%; height: auto;"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://192.168.30.103:80/myapp?port=1935&app=myapp&stream=101'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</body>
</html>
评论区