视频直播知识之四:直播DEMO——RTMP推流和HTTP-FLV拉流

前言

这篇文章主要记录直播DEMO的实现,主要通过RTMP推流,通过HTTP-FLV拉流,并在页面中播放。

同系列文章:

  1. 视频直播知识之一:数据的采集和编码
  2. 视频直播知识之二:推流、拉流和服务端处理
  3. 视频直播知识之三:播放端播放
  4. 视频直播知识之四:直播DEMO——RTMP推流和HTTP-FLV拉流

1 搭建流媒体服务器

安装添加RTMP和HTTP-FLV模块的Nginx,并进行配置。
如果已安装过nginx,可以跳过安装步骤,直接添加模块,这里不再赘述。

1.1 安装Nginx

以CentOS系统为例:
首先更新CentOS系统

1
yum update

安装编译nginx所需的开发包
1
2
3
4
yum install gcc
yum install pcre pcre-devel
yum install openssl openssl-devel
yum install wget unzip

下载nginxnginx-http-flv-module(也可以用git clone)。nginx-http-flv-module基于nginx-rtmp-module,所以不用再单独安装nginx-rtmp-module
1
2
3
4
wget http://nginx.org/download/nginx-1.20.1.tar.gz # 可到http://nginx.org/download/查看stable版本
wget https://github.com/winshining/nginx-http-flv-module/archive/refs/heads/master.zip
tar -zxvf nginx-1.20.1.tar.gz
unzip master.zip

添加模块,编译和安装nginx。
1
2
3
4
cd nginx-1.20.1
./configure --with-http_ssl_module --with-http_secure_link_module --add-module=../nginx-http-flv-module-master
make
sudo make install

make install后,nginx默认会安装在/usr/local/nginx/目录下。

1.2 Nginx配置

/usr/local/nginx/conf/nginx.conf中,添加相关的配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
http {
server {
listen 80;
location /flv {
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 头
}
}
}
rtmp_auto_push on;
rtmp {
server {
listen 1935;
notify_method get;
access_log /var/log/nginx/access.log;
chunk_size 4096;
application live {
# 开启直播模式
live on;
# 允许从任何源push流
allow publish all;
# 允许从任何地方来播放流
allow play all;
# 20秒内没有push,就断开链接。
drop_idle_publisher 20s;
}
}
}

  • rtmp推流地址:
    rtmp://example.com[:port]/appname/streamname
  • http-flv拉流播放地址:
    http://example.com[:port]/dir?[port=xxx&]app=appname&stream=streamname

更多配置可以参考nginx-http-flv-module README
检查配置,重启nginx。

1
2
/usr/local/nginx/sbin/nginx -t
systemctl reload nginx

1.3 试验

可以在本地下载安装ffmpegffmpeg后,读取一个mp4文件,推流到上面搭建的直播服务,来进行试验。
命令如下,test.mp4就是你本地的视频文件名称,live是前面配置的application名称,test就是自定义的流名称。

1
ffmpeg -re -i test.mp4 -c copy -f flv "rtmp://example.com[:port]/live/test"

看到如下的信息即开始推流了。
播放流程
可以执行ffplay命令在本地观看正在直播的视频。
1
ffplay "rtmp://example.com[:port]/live/test"

2 数据采集和推流

以windows为例,首先查询本机的音视频采集设备:

1
ffmpeg -list_devices true -f dshow -i dummy

推流摄像头和麦克风内容,USB2.0 PC CAMERA麦克风 (USB2.0 MIC)是上面查询的结果。
1
ffmpeg -f dshow -i video="USB2.0 PC CAMERA":audio="麦克风 (USB2.0 MIC)" -vcodec libx264 -acodec aac -f flv "rtmp://example.com[:port]/live/test"

更多命令可以查看ffmpeg的文档

3 拉流

开发前端页面,借助flv.js拉流。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import React, { createRef, RefObject } from 'react';
import flvjs from 'flv.js/dist/flv.js';
import './index.css';

interface IProps {
}

interface IState {
}

class Live extends React.Component<IProps, IState> {

constructor(props: IProps) {
super(props);
this.state = {
};
}

_videoRef = (createRef() as RefObject<HTMLVideoElement>);

componentDidMount() {
if (flvjs.isSupported()) {
const videoElement = this._videoRef.current;
try {
const flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'https://example.com[:port]/flv?app=live&stream=test'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
} catch (e) {
console.error(e);
}
}
}

render() {
return (
<div>
<video ref={this._videoRef} className="video" controls={true} muted={true}></video>
</div>
);
}

}

export default Live;

效果如下:
直播demo

参考