登录 立即注册

首页 > 绿虎论坛 > 建站 > 教程 (发帖)

标题: [精]玩转直播流:使用SRS搭建推流服务器;使用SRS+ffmpeg中转推流;OBS推流到自建服务器;使用ffmpeg把直播流复制到多个网站

作者: @Ta

时间: 2021-12-30发布,2022-02-22修改

点击: 26743

推荐使用Linux,Windows建议在WSL2中进行尝试。

使用SRS搭建推流服务器

1a. Ubuntu安装docker教程(Windows忽略)

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

1b. Windows安装WSL2+docker教程(Linux忽略)

https://post.smzdm.com/p/a259kqlp/

image.png

装好后请打开一个 WSL2 Ubuntu 命令行窗口,执行第2步。

2. 安装ffmpeg

sudo apt update
sudo apt install ffmpeg

3. 安装SRS推流服务器

任选一个版本:

3a. 使用SRS3(稳定版)

docker run --restart=always --name srs -d -it --network=host registry.cn-hangzhou.aliyuncs.com/ossrs/srs:3

3b. 使用SRS4(beta版)

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的默认端口,所以可以省略)

4. 用ffmpeg中转推流

4a. 尝试用ffmpeg命令行中转推流

-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。

4b. 写一个循环,失败时自动重启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,或者直接关掉终端(命令行窗口)。

关于ffmpeg的-re参数

推流请务必在开头加-re参数,否则可能会遇到间歇性卡顿,原因是流的发送/接收速度不稳定。对于直播流,如果网络延迟导致发送/接收速度跟不上,就应该直接丢帧,而不是后期加速发送。如果不加-re,播放的时候就会遇到流速不一致的问题,一会儿快一会儿慢,于是这里卡一下那里卡一下。-rerealtime,实时)参数保证了流的速度始终是1x,不会忽快忽慢导致卡顿。

观看地址

查看流状态:
http://localhost:8080/console/ng_index.html#/streams?port=1985

image.png

点预览就能观看,如果预览容易卡,可以尝试把观看地址后缀.flv改成.m3u8,可能会更流畅,例如:

http://ossrs.net/players/srs_player.html?vhost=__defaultVhost__&app=live&stream=livestream.m3u8&server=localhost&port=8080&autostart=false&schema=http

image.png

所有观看地址(按可靠程度排序,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

这样就有两个流可以看了。

image.png


用 OBS Studio 推流到自建服务器

如果是自制节目,也可以直接通过 OBS Studio 推流到SRS服务器,URL填写rtmp://localhost/live(如果是远程推流,localhost换成机器IP),流名称填写livestream

image.png

image.png

image.png


使用ffmpeg把直播流复制到多个网站

首先介绍一下直播网站的推流码和RTMP推流地址的关系。当你在直播网站看到以下信息时:

image.png

把“服务器地址”和“串流密钥”用/相连(如果服务器地址结尾已经有/,无需再加/),就得到可在ffmpeg命令行中使用的RTMP推流地址了。

所有直播网站都可以获得服务器地址和串流密钥,只是有的网站把它藏在了难以找到的地方。

哔哩哔哩推流码

https://link.bilibili.com/p/center/index?#/my-room/start-live

先注册成为主播,然后点击开播后可见

image.png

  • 服务器地址: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

先注册成为主播,然后点击开播后可见

image.png

  • 服务器地址: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开播一次,可以顺便人脸识别实名认证。

图片.png

  • 从虎牙网站复制的推流地址可直接在ffmpeg中使用: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推流到以下服务器,你就可以同时在多个网站开播了:

  • URL:rtmp://localhost:1945/live
  • 流名称:livestream

image.png


推流的同时录像

以下是保存直播录像到/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的输入和输出

你们应该看出来了,ffmpeg的命令是可以自由组合的。它分成输入和输出两部分,输入只能有一个,输出可以有多个。只要把一个输入和至少一个输出放在一起,就可以构成完整的命令。

Linux Shell 命令语法小知识:

  1. 任意两个参数之间都要用空格隔开,当我们说“加在后面”或者“放在一起”时,别忘了打空格。
  2. 如果一行太长,可以在结尾加\然后另起一行。“公网上的推流服务器”就是由多行组成的,如果你想再另起一行写后续命令,别忘了在结尾加\。如果你想在一行的末尾添加参数,也要加在\的前面。

输入

采集现有直播流

支持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 命令语法小知识:

  1. 任意两个参数之间都要用空格隔开,当我们说“加在后面”或者“放在一起”时,别忘了打空格。
  2. 如果一行太长,可以在结尾加\然后另起一行。“公网上的推流服务器”就是由多行组成的,如果你想再另起一行写后续命令,别忘了在结尾加\。如果你想在一行的末尾添加参数,也要加在\的前面。

[隐藏样式|查看源码]


『回复列表(9|隐藏机器人聊天)』

1.

相关讨论:内网用户同时看同一直播,怎么保证流畅
https://hu60.cn/q.php/bbs.topic.102308.2.html?floor=36#36

@admpub

可以采用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加速。

(/@Ta/2023-01-28 15:30//)

2.
🐯🐮🍺plus
(/@Ta/2021-12-30 12:18//)

4. 厉害👍🏻
(/@Ta/2021-12-30 13:33//)

5. 👍👍👍正在尝试。@老虎会游泳
(/@Ta/2021-12-30 13:34//)

6.

来了
小米MIX2s(白)

(/@Ta/2021-12-30 14:21//)

7. 这是啥啊?直播源地址放电视吗?
(/@Ta/2021-12-30 20:40//)

8.

@MFVPNHAHA,创建局域网内的直播服务器

(/@Ta/2021-12-30 21:56//)

9. 使用推流到虎牙错误 @老虎会游泳
image.png
(/@Ta/2022-01-11 23:11//)

10.

@胡椒舰长,可通过添加参数-vtag 7 -atag 10解决,我已经更新教程。

(/@Ta/2022-01-12 00:49//)

回复需要登录

11月27日 19:14 星期三

本站由hu60wap6华为CPU驱动

备案号: 京ICP备18041936号-1