前言
最近捣鼓了一下直播,花了差不多半个月的时间吧(开学了搞技术的时间就少),差不多实现了直播推流+拉流和弹幕发送功能,使用Frp内网穿透之后延迟极限可以达到2秒。
想了解各种直播相关协议推荐观看这个视频:
最终效果
也可以到本站直播页观看使用本教程方法搭建的直播平台,不定时开播
视频教程
哔哩哔哩:
准备工作(前提条件)
1.一个Linux系统环境,这里推荐Ubuntu
可以使用物理机安装、VMWare虚拟机安装、购买安装Ubuntu系统的VPS、WSL2、手机Termux跑proot/chroot容器等方式运行Ubuntu,具体过程这里就不赘述了
2.国际互联网环境
由于众所周知的原因,可能会遇到无法连接到github或nginx官网的情况,这时候有国际互联网环境就可以完美解决这个问题,工具自找
3.一个公网IP地址(可选,如果你不局限于内网观看直播的话)
要满足这个条件,最简单的,可以使用VPS搭建直播服务器;如果家中有公网IP,可以使用家中设备搭建直播服务器;再不行,可以使用Frp这类型的内网穿透工具来映射至公网(我就使用这种方法)
正式部分
编译Nginx
Nginx是目前主流的高性能开源Web服务器,但是原生Nginx并不支持RTMP协议,需要将RTMP模块编译进Nginx
如果之前有安装Nginx最好卸载掉
1 | apt autopurge nginx* |
1. 安装软件包依赖
复制运行以下命令:
1 | apt update |
2.下载Nginx源代码
到Nginx下载页面下载源码的tar.gz压缩文件,推荐nginx-1.22.0.tar.gz,目前Ubuntu官方软件源中的Nginx就是这个版本,当然你也可以选择更新的
使用命令下载并解压nginx-1.22.0.tar.gz:
1 | wget https://nginx.org/download/nginx-1.22.0.tar.gz |
3.下载nginx-http-flv-module
nginx-http-flv-module是一个基于nginx-rtmp-module的第三方模块,包含所有nginx-rtmp-module的功能。项目中文文档
克隆模块仓库
1 | git clone https://github.com/winshining/nginx-http-flv-module.git |
4.编译并安装
配置编译器
1 | ./configure --prefix=/usr/local/nginx \ |
编译并安装
1 | make |
将编译出来的nginx二进制文件链接到/usr/local/sbin/目录中
1 | ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ |
查看Nginx版本
1 | nginx -v |
正常情况下会输出你编译的Nginx版本
nginx version: nginx/1.22.0
配置RTMP推流服务器
使用你喜爱的文本编辑器打开nginx配置文件,我使用vim
1 | vim /usr/local/nginx/conf/nginx.conf |
在event块和http之间添加rtmp块:
1 | rtmp { |
配置HTTP-FLV和HLS拉流服务器
在配置文件中的http块中添加:
1 | server { |
保存退出配置文件,启动Nginx服务器:
1 | nginx |
测试推流
这里示例使用ffmpeg进行简单推流
1 | ffmpeg -re -i /root/Videos/test.mp4 -c copy -f flv rtmp://127.0.0.1:1935/live/1 |
命令解释(ChatGPT生成):
ffmpeg
: 这是FFmpeg工具的命令行启动命令,它用于处理多媒体文件。-re
: 这是一个选项,表示以实时模式(real-time)播放输入文件。在实时模式下,FFmpeg会以与视频的帧速率相匹配的速度处理视频,而不是尽可能快地处理它。这通常用于模拟直播流,以防止过快处理视频。-i /root/Videos/test.mp4
: 这是输入文件的路径和名称。在这个例子中,输入文件是位于/root/Videos/
目录下的test.mp4
文件。-c copy
: 这是一个选项,指定了视频和音频的编解码方式。copy
表示将输入文件中的视频和音频以原样复制到输出文件,而不进行任何重新编码。这可以加快处理速度,尤其是当输入文件已经包含所需的编解码格式时。-f flv
: 这是一个选项,指定了输出文件的格式。在这个例子中,输出文件将以Flash视频(FLV)格式保存。rtmp://127.0.0.1:1935/live/1
: 这是输出文件的目标地址。它使用RTMP(Real-Time Messaging Protocol)协议,将处理后的视频数据流推送到本地主机上的RTMP服务器。具体来说,它将数据推送到127.0.0.1
(本地主机)的1935
端口上的live
应用程序,而1
是流的名称。这个地址通常用于流媒体服务器,以便将视频流发送到网络上的观众。
命令后边rtmp://127.0.0.1:1935/live/1的“1”叫推流密钥,自建服务器可以随便填写,作用类似于直播房间号,可以使一个应用处理多个直播流
FFmpeg出现比特率、视频速度等信息即为测试推流成功
测试拉流
推荐使用开源的VLC media player
以Windows端的VLC为例,点击左上角的媒体(M)
,点击打开网络串流(N)
,然后点击网络(N)
,在URL栏中输入http://[服务器IP]:8080/?port=1935&app=live&stream=1
这里的port就是服务器中RTMP推流端口,app就是推流应用程序,stream就是房间号(或者叫推流密钥)
点击播放(P)
,稍等片刻后看到FFmpeg推的视频即为测试拉流成功
使用DPlayer在支持HTML5的浏览器中拉流
为了保证直播观看的方便性,最优解就是在支持HTML5的浏览器播放直播流(除非是古董浏览器都支持HTML5)
DPlayer是一个开源的,基于css和JavaScript的HTML5网页视频播放器,在GitHub开源 开源地址
1.创建一个页面
打开Nginx配置文件,在http块中添加以下配置:
1 | server { |
保存退出,创建网站根目录文件夹
1 | mkdir /usr/local/nginx/live |
重启Nginx服务器
1 | nginx -s reload |
2.下载Dplayer、flv.js、hls.js
进入到网站根目录文件夹中,创建一个子文件夹以存放这些文件,然后下载并解压
1 | cd /usr/local/nginx/live |
3.配置DPlayer(使用flv.js)
在网站根目录创建index.html
1 | vim /usr/local/nginx/live/index.html |
这是一个示例HTML代码:
1 |
|
记得将IP改成你自己的,stream=1的1要和推流源保持一致
保存退出后,浏览器访问http://[服务器IP]:8000
,正常情况下,将出现一个DPlayer播放器,如果访问是下载文件,在地址栏添加/index.html
;如果不显示,检查HTML语法是否正确,或者查看Nginx的日志文件
1 | cat /usr/local/nginx/logs/access.log |
*配置DPlayer(使用hls.js)
由于iOS不支持Media Source Extensions,故无法播放flv.js直播流
解决方案是使用hls.js替代hls.js,缺点是延迟有30秒左右,这比起flv.js 2秒的延迟显得延迟非常大,尤其是如果要直播弹幕的话会导致别人看到是实时画面,iOS用户看的是30秒前的画面,导致iOS端弹幕画面不同步
要解决这个缺点只能去苹果公司应聘然后给iOS开发出MSE要不然就是众生平等给全端使用hls.js(
我使用子页面的方式将HTTP-FLV拉流方式和HLS拉流方式共存
在DPlayer网站根目录创建一个文件夹来存放hls.js DPlayer页面文件
1 | cd /usr/local/nginx/live |
将根目录的index.html复制到hls文件夹中并编辑
1 | cp ./index.html hls |
将HTML文件中的
1 | <script src="http://192.168.0.21:8000/dplayer/flv.min.js"></script> |
改为
1 | <script src="http://192.168.0.21:8000/dplayer/hls.min.js"></script> |
注意这里的IP仅为示例,以你为准
将HTML文件中的
1 | var dp = new DPlayer({ |
改为
1 | var dp = new DPlayer({ |
将HTML文件中的
1 | url: 'http://192.168.0.21:8080/?port=1935&app=live&stream=1', |
改为
1 | url: 'http://192.168.0.21:8080/hls/1.m3u8', |
这个1是推流密钥,确保和推流时填写的推流密钥一致
保存退出后,在之前的网址中添加/hls
即可访问使用HLS拉流的直播页面
使用Websocket+DPlayer搭建直播弹幕服务
DPlayer作为一个播放器有另一个优点:支持渲染弹幕。但是在官方文档中,只有简单的示例,在直播弹幕的版块也只是一笔略过,好在GitHub中有大佬开发出了专用于DPlayer的Websocket弹幕服务器:dplayer-live-backend
1.安装Node.js
运行以下命令安装Node.js
1 | apt install nodejs npm -y |
2.安装dplayer-live-backend
在网站目录外克隆这个仓库
1 | git clone https://github.com/Izumi-kun/dplayer-live-backend.git |
安装所需的依赖
1 | npm i |
如果出现类似于这个的输出
1 critical serverity vulnerability
To address all issues, run:
npm audit fix
Run `npm audit` for details.
就运行这个命令修复一下:
1 | npm audit fix |
3.修改server.js
此代码来自项目Issues#2
1 | vim ./server.js |
将这两个变量
1 | var hexColorRegExp = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; |
更改为以下形式,因为dplayer的消息格式发生了变化。
1 | var hexColorRegExp = /^\d{8}$/ |
4.运行弹幕服务器
运行
1 | node ./server.js |
成功运行时的输出:
WebSocket server started on port: 1207
你可以通过传递--port
参数来自定义服务器端口,如
1 | node ./server.js --port=1207 |
后台运行
1 | node ./server.js & |
5.DPlayer开启弹幕
编辑DPlayer网站HTML文件
1 | vim /usr/local/nginx/live/index.html |
将其中的
1 | danmaku: false, |
改为
1 | danmaku: true, |
然后在下面把ws地址改为服务器的IP和端口
如果有hls页面的话,也要一起改一遍
1 | vim /usr/local/nginx/live/hls/index.html |
这时DPlayer就出现了发送弹幕的按钮了,左边可以调节发送设置
正常来说到此为止就成功搭建一个直播平台了。
使用OBS Studio推流
1.下载OBS Studio
进入OBS官网,然后下载适用于你操作系统的版本
2.布局界面
OBS Studio可以制作各种各样不同的布局,可以点击下方菜单栏的+
号添加元素
3.进行推流
点击左上角文件(F)
,选择设置(S)
,点击左侧的直播
,将服务器改为自定义,然后填写RTMP服务器地址,推流密钥自建服务器随便写,拉流是填写一致的推流密钥就行,保存后点击右下角开始直播
即可开启推流
使用Frp进行内网穿透
本着能白嫖就白嫖的原则,推荐 乐青映射 完全免费, 高自由度,流量大,稳定(非广告)
需要穿透DPlayer网页服务端口、HTTPFLV-HLS服务端口、弹幕服务端口
Frp使用方法这里就不赘述了,教程一抓一大把,这里只说一下坑点:Nginx的那个DPlayer页面的内网端口要和穿透的远程端口一致,否则有可能给你重定向端口,造成无法访问
注意事项(自助纠错)
1.如果要套tls,那么套tls的http要改为https,ws要改为wss,注意如果网页套了tls那么网页内的所有资源都要套tls不然无法加载
2.OBS Studio长期运行会让电脑一直发烫容易缩短电脑寿命,Windows11以上可以在任务管理器中给进程开启效能模式来缓解,或者改用FFmpeg推流
3.如果你开启了HLS协议拉流,那么Nginx会循环往硬盘中写入直播流TS文件,长期使用会加速缩短硬盘寿命,解决方法是挂载一段内存地址然后更改缓存来存取这些TS文件(未经测试):
1 | mount -t tmpfs -o size=4g tmpfs /data |
4.OBS Studio的RTMP服务器地址填完后面一定要确保后面有斜杠/
,不然会推流失败
5.服务器配置里不要填写127.0.0.1或者localhost等本地回环地址,要填写内网/公网IP,不然其它设备无法访问