标题: [精]玩转直播流:使用SRS搭建推流服务器;使用SRS+ffmpeg中转推流;OBS推流到自建服务器;使用ffmpeg把直播流复制到多个网站
时间: 2021-12-30发布,2022-02-22修改
推荐使用Linux,Windows建议在WSL2中进行尝试。
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
https://post.smzdm.com/p/a259kqlp/
装好后请打开一个 WSL2 Ubuntu 命令行窗口,执行第2步。
sudo apt update
sudo apt install ffmpeg
任选一个版本:
docker run --restart=always --name srs -d -it --network=host registry.cn-hangzhou.aliyuncs.com/ossrs/srs:3
docker run --restart=always --name srs -d -it --network=host registry.cn-hangzhou.aliyuncs.com/ossrs/srs:4 ./objs/srs -c conf/docker.conf
SRS控制面板:http://localhost:8080/
推流服务器:rtmp://localhost:1935(1935是RTMP的默认端口,所以可以省略)
-i
后面可以接各种资源,包括视频文件、m3u8地址、flv地址等。
如果音频编码不是aac,可以删掉-bsf:a aac_adtstoasc
参数。
请给网址打引号,防止生出各种麻烦。
ffmpeg -re -i 'http://cctvalih5ca.v.myalicdn.com/live/cctv13_2/index.m3u8' -f flv -c copy -bsf:a aac_adtstoasc 'rtmp://localhost/live/livestream'
按ctrl+c关闭ffmpeg。
4a
参数调好,确认没问题之后再进行。
请务必进行此步骤,否则任何风吹草动都可能会导致推流停止。
while true; do ffmpeg -re -i 'http://cctvalih5ca.v.myalicdn.com/live/cctv13_2/index.m3u8' -f flv -c copy -bsf:a aac_adtstoasc 'rtmp://localhost/live/livestream'; done
因为循环会不断重启ffmpeg,如果要结束推流,需要不断按ctrl+c,或者直接关掉终端(命令行窗口)。
-re
参数推流请务必在开头加-re
参数,否则可能会遇到间歇性卡顿,原因是流的发送/接收速度不稳定。对于直播流,如果网络延迟导致发送/接收速度跟不上,就应该直接丢帧,而不是后期加速发送。如果不加-re
,播放的时候就会遇到流速不一致的问题,一会儿快一会儿慢,于是这里卡一下那里卡一下。-re
(realtime
,实时)参数保证了流的速度始终是1x,不会忽快忽慢导致卡顿。
查看流状态:
http://localhost:8080/console/ng_index.html#/streams?port=1985
点预览就能观看,如果预览容易卡,可以尝试把观看地址后缀.flv
改成.m3u8
,可能会更流畅,例如:
所有观看地址(按可靠程度排序,flv最不可靠,可能会卡住,不推荐;如果是远程观看,localhost
换成机器IP):
把推流地址rtmp://localhost/live/livestream
里的livestream
改成其他内容,就可以形成不同的流。
第一个终端里执行:
while true; do ffmpeg -re -i 'http://cctvalih5ca.v.myalicdn.com/live/cctv13_2/index.m3u8' -f flv -c copy -bsf:a aac_adtstoasc 'rtmp://localhost/live/cctv13'; done
第二个终端里执行:
while true; do ffmpeg -re -i 'http://cctvalih5ca.v.myalicdn.com/live/cctv2_2/index.m3u8' -f flv -c copy -bsf:a aac_adtstoasc 'rtmp://localhost/live/cctv2'; done
这样就有两个流可以看了。
如果是自制节目,也可以直接通过 OBS Studio 推流到SRS服务器,URL填写rtmp://localhost/live
(如果是远程推流,localhost
换成机器IP),流名称填写livestream
。
首先介绍一下直播网站的推流码和RTMP推流地址的关系。当你在直播网站看到以下信息时:
把“服务器地址”和“串流密钥”用/
相连(如果服务器地址结尾已经有/
,无需再加/
),就得到可在ffmpeg
命令行中使用的RTMP推流地址了。
所有直播网站都可以获得服务器地址和串流密钥,只是有的网站把它藏在了难以找到的地方。
https://link.bilibili.com/p/center/index?#/my-room/start-live
先注册成为主播,然后点击开播后可见
rtmp://live-push.bilivideo.com/live-bvc/
?streamname=live_123456_7890123456&key=不能告诉你&schedule=rtmp&pflag=1
ffmpeg
命令行中使用的RTMP推流地址:rtmp://live-push.bilivideo.com/live-bvc/?streamname=live_123456_7890123456&key=不能告诉你&schedule=rtmp&pflag=1
https://mp.douyu.com/live/main
先注册成为主播,然后点击开播后可见
rtmp://sendtc3.douyu.com/live
12345678abcdEFGH?wsSecret=不能告诉你&wsTime=61cd25c4&wsSeek=off&wm=0&tw=0&roirecognition=0&record=flv&origin=tct
ffmpeg
命令行中使用的RTMP推流地址:rtmp://sendtc3.douyu.com/live/12345678abcdEFGH?wsSecret=不能告诉你&wsTime=61cd25c4&wsSeek=off&wm=0&tw=0&roirecognition=0&record=flv&origin=tct
教程:http://help.huya.com/355
页面:https://i.huya.com/index.php?m=ProfileSetting#ktylts
需要用虎牙官方软件开播一次才可进入主播设置。建议先用虎牙手机app开播一次,可以顺便人脸识别实名认证。
rtmp://tx.direct.huya.com/huyalive/保密-保密-0-保密-保密-A-保密-1?seq=保密&type=simple
下面是同时推流到哔哩哔哩和斗鱼的例子:
while true; do
ffmpeg -re -f flv -listen 1 -i rtmp://0.0.0.0:1945/live/livestream \
-f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy \
'rtmp://live-push.bilivideo.com/live-bvc/?streamname=live_123456_7890123456&key=不能告诉你&schedule=rtmp&pflag=1' \
-f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy \
'rtmp://sendtc3.douyu.com/live/12345678abcdEFGH?wsSecret=不能告诉你&wsTime=61cd25c4&wsSeek=off&wm=0&tw=0&roirecognition=0&record=flv&origin=tct' \
# end
done
因为循环会不断重启ffmpeg,如果要结束推流,需要不断按ctrl+c,或者直接关掉终端(命令行窗口)。
不断重复以下几行就能推流到更多网站:
-f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy \
'rtmp://服务器地址/串流密钥' \
如果你想同时推流到SRS服务器,那么串流密钥随便写就可以,比如:
rtmp://localhost/live/aaa
rtmp://localhost/live/bbb
不同的串流密钥就形成不同的流,可以分别观看。
最后,OBS推流到以下服务器,你就可以同时在多个网站开播了:
rtmp://localhost:1945/live
livestream
以下是保存直播录像到/home/hu60/Videos/我的直播录像-日期-时间.flv
,并同时推流到哔哩哔哩和斗鱼的例子:
while true; do
ffmpeg -re -f flv -listen 1 -i rtmp://0.0.0.0:1945/live/livestream \
-f flv -flvflags no_duration_filesize -c copy "/home/hu60/Videos/我的直播录像-$(date '+%F_%H-%M-%S').flv" \
-f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy \
'rtmp://live-push.bilivideo.com/live-bvc/?streamname=live_123456_7890123456&key=不能告诉你&schedule=rtmp&pflag=1' \
-f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy \
'rtmp://sendtc3.douyu.com/live/12345678abcdEFGH?wsSecret=不能告诉你&wsTime=61cd25c4&wsSeek=off&wm=0&tw=0&roirecognition=0&record=flv&origin=tct' \
# end
done
你们应该看出来了,ffmpeg
的命令是可以自由组合的。它分成输入和输出两部分,输入只能有一个,输出可以有多个。只要把一个输入和至少一个输出放在一起,就可以构成完整的命令。
Linux Shell 命令语法小知识:
\
然后另起一行。“公网上的推流服务器”就是由多行组成的,如果你想再另起一行写后续命令,别忘了在结尾加\
。如果你想在一行的末尾添加参数,也要加在\
的前面。支持m3u8、rtmp等多种格式
-re -i 'http://cctvalih5ca.v.myalicdn.com/live/cctv13_2/index.m3u8'
支持几乎所有视频文件格式
-re -i './我的视频.flv'
比如可以使用OBS推流给ffmpeg
0.0.0.0
是监听IP,1945
是监听端口。live
是推流路径,livestream
是推流码,其实两者都可以省略不写,推流时只会产生一条警告说路径不匹配,并不会影响实际推流。-re -f flv -listen 1 -i rtmp://0.0.0.0:1945/live/livestream
也可以输出成mp4、mkv等,但是建议使用flv,不容易损坏,而且和推流的兼容性高(RTMP推流推送的就是类似flv的数据结构)。
-f flv -flvflags no_duration_filesize -c copy "文件名.flv"
live
是推流路径,livestream
是推流名称。把livestream
改成其他名称就可以生成多个不同的流。
如果推流服务器不在局域网内,延迟和网速都不能保证,就不能用这个命令,因为这个命令一旦推流卡顿就会自动退出,导致直播中断。
公网推流应该使用后面的公网专用命令,当然局域网推流也可以用那个命令,可能会更稳定。
-f flv -c copy 'rtmp://localhost/live/livestream'
如果推流时报错说要加-bsf:a aac_adtstoasc
,就把它加在-c copy
的后面:
-f flv -c copy -bsf:a aac_adtstoasc 'rtmp://localhost/live/livestream'
drop_pkts_on_overflow
是卡顿时自动丢帧,该选项非常重要,否则一旦出现卡顿就无法自动缓解了,推流可能会一直卡顿下去。attempt_recovery
是掉线时自动重连。recover_any_error
是无论发生什么错误都自动重连。 -f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy \
'rtmp://视频网站给出的推流服务器地址/视频网站给出的串流密钥'
如果推流时报错说要加-bsf:a aac_adtstoasc
,就把它加在-c copy
的后面:
-f fifo -fifo_format flv -map 0:v -map 0:a -vtag 7 -atag 10 \
-flags +global_header -flvflags no_duration_filesize \
-drop_pkts_on_overflow 1 -attempt_recovery 1 -recover_any_error 1 -c copy -bsf:a aac_adtstoasc \
'rtmp://视频网站给出的推流服务器地址/视频网站给出的串流密钥'
-vtag 7 -atag 10
它们用于指定视频和音频编码,-vtag 7
表示AVC(H.264)
视频,-atag 10
表示AAC
音频。
如果你的音频格式是MP3
,可改成-vtag 7 -atag 2
。
-vtag
2 = Sorenson H.263
3 = Screen video
4 = On2 VP6
5 = On2 VP6 with alpha channel
6 = Screen video version 2
7 = AVC(H.264)
-atag
0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
4 = Nellymoser 16 kHz mono
5 = Nellymoser 8 kHz mono
6 = Nellymoser
7 = G.711 A-law logarithmic PCM , reserved
8 = G.711 mu-law logarithmic PCM , reserved
9 = reserved
10 = AAC (supported in Flash Player 9,0,115,0 and higher)
11 = Speex (supported in Flash Player 10 and higher)
14 = MP3 8 kHz , reserved
15 = Device-specific sound , reserved
如果你要推视频文件,建议推流前进行编码转换,转为FLV
格式,视频编码H.264/AVC
,音频编码AAC
。
ffmpeg也许支持在推流时进行编码转换,但不建议使用,我没成功过。
Linux Shell 命令语法小知识:
\
然后另起一行。“公网上的推流服务器”就是由多行组成的,如果你想再另起一行写后续命令,别忘了在结尾加\
。如果你想在一行的末尾添加参数,也要加在\
的前面。『回复列表(9|显示机器人聊天)』
相关讨论:内网用户同时看同一直播,怎么保证流畅
https://hu60.cn/q.php/bbs.topic.102308.2.html?floor=36#36
可以采用webrtc+p2p来进行播放,可以节省带宽流量。
例如:
http://www.hifilm.top/film/tv?media=http://cctvalih5ca.v.myalicdn.com/live/cctv15_2/index.m3u8
可以把上述网址中的media值改为其它m3u8网址
相关开源项目:
P2P技术使观看相同内容的用户之间可以相互分享数据,不仅能效降低视频/直播网站的带宽成本,还可以提升用户的播放体验,降低卡顿、二次缓存的发生率。 另外,随着H5的普及,flash逐渐被淘汰已成为不可逆转的趋势。而在H5采用的视频传输格式中,hls由于兼容ios和android、可以穿过任何允许HTTP数据通过的防火墙、容易使用内容分发网络来传输媒体流和码率自适应等众多优势而在业界得到广泛使用。通过使用hls.js这个第三方库,几乎所有现代浏览器都可以播放hls视频。hls天生分片传输的优势,使其可以采用p2p的方式进行传输,从而减小服务器的负担。在web端,无插件化实现p2p传输能力的最好选择就是WebRTC技术,与hls.js类似,WebRTC也支持几乎所有现代浏览器。本项目是一个hls.js的插件,通过WebRTC datachannel技术,在不影响用户体验的前提下,最大化p2p率,是面向未来的Web P2P技术。
CBPlayer 是基于 DPlayer 开发的,内置 CDNBye P2P 插件的 H5 播放器,加入了记忆播放等实用功能,右键可以查看p2p实时数据。支持HLS、MP4和MPEG-DASH三种格式的P2P加速。