推荐使用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 命令语法小知识:
\
然后另起一行。“公网上的推流服务器”就是由多行组成的,如果你想再另起一行写后续命令,别忘了在结尾加\
。如果你想在一行的末尾添加参数,也要加在\
的前面。
相关讨论:内网用户同时看同一直播,怎么保证流畅
https://hu60.cn/q.php/bbs.topic.102308.2.html?floor=36#36
@admpub:
相关开源项目: