之前介绍过,使用CentOS加上youtube-dl,获取到youtube直播的m3u8,再使用ffmpeg推流到其它地方的教程,不过经过这两年半的时间后,之前的m3u8方案已经不太好用了,所以就有了个今天这个比较新的方案。
大概过程,使用streamlink获取youtube live的直播流并转发到本地端口,然后使用ffmpeg工具转播到其它地方。
这次不单单会写转播教程,还会顺便把搭建本地nginx rtmp的过程也写上,还会顺便写一些其它的东西,比如自动录播功能等等,所以就直接收藏本文吧。
为了照顾新手,会安装宝塔面板,或者aaPanel,系统选择Debian 11,因为可以直接安装ffmpeg,CentOS的第三方的ffmpeg版本挺老的,新版的还得自己编译,怪麻烦的,所以直接用Debian省了不少事。
VPS当然得是需要国外的VPS,这个就不多说了。
安装 curl
apt-get update -y && apt-get install curl -y
安装宝塔面板
curl -sSO https://raw.githubusercontent.com/8838/btpanel-v7.7.0/main/install/install_panel.sh && bash install_panel.sh
curl -sSO https://raw.githubusercontent.com/ztkink/bthappy/main/one_key_happy.sh && bash one_key_happy.sh
或者安装aaPanel面板 (个人推荐)
wget -O install.sh http://www.aapanel.com/script/install-ubuntu_6.0_en.sh && bash install.sh aapanel
安装后记好登陆的地址,以及账号和密码
开启bbr
echo net.core.default_qdisc=fq >> /etc/sysctl.conf
echo net.ipv4.tcp_congestion_control=bbr >> /etc/sysctl.conf
sysctl -p
sysctl net.ipv4.tcp_available_congestion_control
安装sudo
apt-get install sudo
安装aria2
apt-get install aria2 -y
安装pip和pip3
apt-get install python-pip -y
sudo apt install -y python3-pip -y
后续更新pip3
python3 -m pip install --upgrade pip
安装you get
pip3 install you-get
安装youtube-dl,streamlink,screen,yt-dlp.youtube-dlc,ffmpeg等等
pip3 install --upgrade youtube-dl
pip3 install --upgrade yt-dlp
pip3 install --upgrade streamlink
sudo apt install ffmpeg -y
sudo apt install screen -y
pip3 install --upgrade youtube-dlc
更新一下系统
sudo apt update -y && sudo apt upgrade -y
自动录制部分
先说一下使用 screen工具新建终端窗口,因为screen的终端窗口可以后台运行
创建一个新窗口命令
screen -S test
查看所有后台窗口命令
screen -ls
重新打开命令
screen -r test
关掉这个后台窗口命令,注意下面的8471数字会不一样
screen -X -S 8471.test quit
使用 Screen + Streamlink + ffmpeg 在加上一些脚本自动检测twitch开播并自动录制,以及youtube开播并自动录制的脚本和命令
去/www/wwwroot/的文件夹中,新建一个文件夹,起个英文名字,比如 youtube 或者 twitch
在twitch文件夹中,新建个文件,名字是 record_twitch.sh
内容如下
#!/bin/bash
# Twitch Live Stream Recorder
if [[ ! -n "$1" ]]; then
echo "usage: $0 twitch_id [format] [loop|once] [interval]"
exit 1
fi
# Record the highest quality available by default
FORMAT="${2:-best}"
INTERVAL="${4:-10}"
while true; do
# Monitor live streams of specific channel
while true; do
LOG_PREFIX=$(date +"[%Y-%m-%d %H:%M:%S]")
echo "$LOG_PREFIX Try to get current live stream of twitch.tv/$1"
# Get the m3u8 address with streamlink
M3U8_URL=$(streamlink --stream-url "twitch.tv/$1" "$FORMAT")
(echo "$M3U8_URL" | grep -q ".m3u8") && break
echo "$LOG_PREFIX The stream is not available now."
echo "$LOG_PREFIX Retry after $INTERVAL seconds..."
sleep $INTERVAL
done
# Record using MPEG-2 TS format to avoid broken file caused by interruption
FNAME="twitch_${1}_$(date +"%Y%m%d_%H%M%S").ts"
echo "$LOG_PREFIX Start recording, stream saved to \"$FNAME\"."
# Start recording
#streamlink -o "$FNAME" twitch.tv/$1 best
streamlink -o "$FNAME" --twitch-disable-ads twitch.tv/$1 best
# ffmpeg -i "$M3U8_URL" -codec copy -f mpegts "$FNAME" > "$FNAME.log" 2>&1
# Exit if we just need to record current stream
LOG_PREFIX=$(date +"[%Y-%m-%d %H:%M:%S]")
echo "$LOG_PREFIX Live stream recording stopped."
[[ "$3" == "once" ]] && break
done
依然是使用screen工具,新建个窗口,执行
cd /www/wwwroot/twitch
./record_twitch.sh thebs_chen best loop
thebs_chen 是twitch主播的id,可以换,best是指录制最好的画质,loop是循环执行,直播开始后就录制,直播完成后就继续执行检测命令,等待下次开播。
运行这个命令后,会每隔10秒检测一下twitch的频道,主播开播后会自动录制。
接下来是 youtube 的开播录制,youtube的开播录制比较麻烦,需要用到cookies,还需要转换成脚本用到的格式
还是在wwwroot的文件夹内新建一个文件夹,比如就叫youtube
点这里,下载这个包:https://github.com/lovezzzxxx/liverecord/archive/refs/heads/master.zip
解压,把 record_twitcast.py 、record_new.sh 、record.sh 这三个文件上传到youtube的文件夹
在youtube的文件夹内手动新建两个txt文件,分别命名为 you-cookies.txt 和 you-config.txt
用谷歌浏览器打开youtube,并登陆你的账号
按F12,打开开发人员的前端工具
按F5,刷新一下youtube的网站
在右边找到 Network
接下来就比较困难了,需要找到包含 SID 的cookies文件,不知道文件名会不会变
比如我写教程的这里,名字是这个开头,cookies的文本在这里
如图,找到cookies的文本后,把上图红框内的文本复制出来。
打开 http://tools.bugscaner.com/cookietocookiejar/
作用域写
.youtube.com
下面把刚才复制过来的文本粘贴过去,转化一下
把上图中下面转化好的文本,复制粘贴到 you-cookies.txt 里面保存
打开 you-config.txt
http-cookie=SID=这里是文本
http-cookie=HSID=这里是文本
http-cookie=SSID=这里是文本
http-cookie=APISID=这里是文本
http-cookie=SAPISID=这里是文本
把 you-cookies.txt 里面的cookies文本手动一条条的复制到 you-config.txt 中,文本格式是上面的代码
完成后如图
youtube文件夹内的最终文件
依然是新建个screen窗口,然后依次执行
cd /www/wwwroot/youtube
./record_new.sh youtubeffmpeg "UC7QVieoTCNwwW84G0bddXpA" --you-cookies "./you-cookies.txt" --you-config "./you-config.txt" -f 1080p,720p,480p,360p,worst -l 30 -o "/www/wwwroot/youtube"
大概意思是 使用 record_new.sh 文件命令执行,检测 UC7QVieoTCNwwW84G0bddXpA 这个Youtube博主的个人地址,这里可以换成你想自动录制的博主id
--you-cookies "./you-cookies.txt" --you-config "./you-config.txt" 是调用cookies,这个不用管
-f 1080p,720p,480p,360p,worst 这个是录制视频的画质选择,默认从高到低,哪个最好用哪个
-l 30 -o "/www/wwwroot/youtube"
-l 是命令循环运行,等博主开播了就自动录视频,录完了就继续检测等待下次开播。
30 是指每30秒检测一次,建议就用30就行了,太快了不知道会不会被Youtube ban掉。
-o "/www/wwwroot/youtube" 这个就是录制的视频文件保存的位置了。
使用yt-dlp下载youtube视频的命令,推荐
yt-dlp --format "bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best" --merge-output-format mp4 https://www.youtube.com/watch?v=_X31LkqbO3Q
下载youtube视频的命令,使用aria2多线程下载,不推荐,容易封IP,推荐用上面那一行
yt-dlp --format "bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best" --merge-output-format mp4 https://www.youtube.com/watch?v=Iajwh9a1NA0 --external-downloader aria2c --external-downloader-args "-x 16 -k 1M"
现在YouTube 高分辨率画质的mp4编码也有vp9了,所以如果你想避开vp9编码的mp4,可以使用这个方法查看和单独下载avc编码的mp4
先是用 -F 的命令,查看一下纯音频和纯avc编码的视频的编号,然后使用 -f数字+数字下载,看下面两行代码就懂了。
yt-dlp -F https://www.youtube.com/watch?v=TI_pyr-5GLs
yt-dlp -f 137+140 https://www.youtube.com/watch?v=TI_pyr-5GLs
如果下载的youtube视频是vp9编码,可以用ffmpeg本地转码一下,以下三个分别是核显,amd,英伟达的GPU加速的转码代码
ffmpeg -i input.mp4 -c:v h264_qsv -b:v 8000k output.mp4
ffmpeg -i input.mp4 -c:v h264_amf -b:v 8000k output.mp4
ffmpeg -i input.mp4 -c:v h264_nvenc -b:v 8000k output.mp4
录像默认是ts格式,转换mp4代码
ffmpeg -i youtube.ts -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4
附送一个合并功能的代码,可以手动把下载的mp4视频流和m4a音频流合并
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -strict experimental output.mp4
转播部分
登录你的宝塔面板,或者sspanel面板,一样,以下简称宝塔面板
登陆后不要一键安装环境,手动去商店中安装php以及nginx工具
下载nginx-rtmp-module,先在终端运行
cd /www/server/
git clone https://github.com/arut/nginx-rtmp-module.git
Nginx安装
软件商店 > 应用搜索:nginx > 安装 > 编译安装 > 添加自定义模块
模块名称:nginx_rtmp_module
描述: nginx rtmp
参数:--add-module=/www/server/nginx-rtmp-module
如上图,点编译安装,添加个自定义模块,最后安装前,别忘了勾选。
等待安装完成后,去网站里面,添加网站,比如 live.hercd.com,网站路径目录则是 /www/wwwroot/live.hercd.com
手动去这个目录新建几个文件夹,hls live tmp video
手动去新建目录:/www/server/nginx/conf/rtmp, 在目录下新建两个文件:
nginx-rtmp.conf 和 nginx-rtmp-play.conf
注意改成你的网址
# nginx-rtmp.conf
rtmp {
server {
listen 1935;
ping 30s;
chunk_size 4000;
notify_method get;
application live { # 推流地址rtmp://ip:1935/live/密钥,同拉流播放地址
live on;
record off; # 是否开启记录 off, all,用于录制直播视频以便回放重播
record_unique on; # 记录值唯一
record_max_size 200M; # 记录文件大小
record_path "/www/wwwroot/live.hercd.com/video"; # 记录文件位置
record_suffix -%Y-%m-%d-%H_%M_%S.flv; # 记录文件命名
#on_publish http://127.0.0.1:8686/auth; # 开始推流的回调地址
#on_done 'http://when live stop call this url'; # 结束推流的回调地址
#on_play http://127.0.0.1:8686/auth; # 开始播放的回调地址
}
application hls { # 推流地址rtmp://ip:1935/hls/密钥,开启HLS协议进行m3u8直播
live on;
hls on; # 开启hls, hls的推流会产生一个m3u8的ts视频文件索引,同时保存一个个视频片段缓存,可以拿到再次播放。
hls_path /www/wwwroot/live.hercd.com/hls; # 视频切片ts文件存放的位置
hls_sync 100ms;
hls_fragment 15s; # 视频切片的大小,ts文件大小
hls_cleanup on; #对多余的切片进行删除
hls_playlist_length 30s; #保存m3u8列表长度时间,默认是30秒
#exec_push ffmpeg -i rtmp://127.0.0.1/hls/$name -c:v copy -c:a copy -f flv rtmp://destination_server/live/output_stream;
#exec_push ffmpeg -i rtmp://127.0.0.1/hls/$name -c:v copy -c:a copy -f flv rtmp://destination_server/live/output_stream;
#exec_push ffmpeg -i rtmp://127.0.0.1/hls/$name -vn -c:a libmp3lame -b:a 128k -f mp3 icecast://source:password@127.0.0.1:1354/chatcyf.mp3;
}
#application vod { # 用于视频点播flv/mp4
# play /www/wwwroot/live.hercd.com/video; # 本地视频MP4文件存放地址,作为流播放视频: rtmp://ip:1935/vod/视频名称.mp4
#}
#application vod_http { # 播放远程http链接的视频,rtmp://ip:1935/vod_http/视频名称.mp4
# play http://localhost:8080/vod/;
#}
}
}
# nginx-rtmp-play.conf
server {
listen 1000;
location /stat { # http://ip:1000/stat, 监控流的地址
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /www/server/nginx-rtmp-module/;
}
location /hls { # http拉流的地址,http://ip:1000/hls/密钥.m3u8
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /www/wwwroot/live.hercd.com/;
expires -1;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
以下示例均用 live.hercd.com
编辑nginx.conf
引入配置:include /www/server/nginx/conf/rtmp/nginx-rtmp.conf;
引入配置:include /www/server/nginx/conf/rtmp/nginx-rtmp-play.conf;
重启Nginx,并去安全,放行1000和1935端口
好了,到这里,已经可以用obs给你的服务器推流了,看上面 nginx-rtmp.conf 代码,默认开启了live和hls推流,vod的没开,简单说一下,live是flv格式的,hls是m3u8的,vod是flv或者mp4的。
比如用hls和live的演示,还是用 live.hercd.com ,推流地址分别是
rtmp://live.hercd.com:1935/hls
rtmp://live.hercd.com:1935/live
推流密码写个单词就行,比如test,一般情况下,用hls的方式比较多,可以直接生成.m3u8的文件
其实这个时候,去你的网址目录看,就可以看到hls文件夹或者live文件夹内,已经有m3u8以及ts文件,或者flv的文件,已经可以直接用http调用这些文件
live推流的拉流地址 rtmp://live.hercd.com:1935/live/test
hls拉流地址 https://live.hercd.com/hls/test.m3u8
还可以在live.hercd.com中,新建个index.html
可以使用西瓜播放器制作一个:https://h5player.bytedance.com/generate/
又或者下载另外一个比较简洁的播放器
下载:1694440743-live.hercd.com.zip
使用 Streamlink 搭配 ffmpeg 反代理和转推
反代理部分
新建一个新的 screen 终端窗口,运行
streamlink --player-external-http --player-external-http-port 12345 --retry-open 30 --hls-segment-timeout 600 --hls-timeout 900 --http-stream-timeout 900 --ringbuffer-size 4M https://www.youtube.com/channel/UC7QVieoTCNwwW84G0bddXpA/live best
这个是youtube的命令,twitch的需要用这个
streamlink --twitch-disable-ads --player-external-http --player-external-http-port 12345 --retry-open 30 --hls-segment-timeout 600 --hls-timeout 900 --http-stream-timeout 900 --ringbuffer-size 4M https://www.twitch.tv/thebs_chen best
如果看到正常运行后,最下面会有个网址,应该是 http://127.0.0.1:12345
这个就是把上面youtube的直播反代理到VPS本地的12345端口了,外界访问则是你的ip加上12345端口,当然别忘了防火墙打开端口。
可以用Potplayer之类的播放器,直接播放这个反代理后的地址,http://youip:12345
还有一个关于跨域的问题,以及CloudFlare的CORS跨域问题
如果你不存在跨域的问题,不用管这里。
vps那边,网站的config里面,手动添加几行这个,添加完后重新载入和重启一下nginx
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
CloudFlare那边,去 规则 - 转换规则 - 修改响应头 - 创建规则,填写 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 的内容就行
转推部分
可以去别的vps上,使用ffmpeg转推刚刚生成12345端口的流媒体,也可以本地新建个终端窗口,本地转推到别的地方,命令如下
ffmpeg -re -i http://youip:12345/ -rw_timeout 30000000 -vcodec copy -acodec copy -f flv -bsf:a aac_adtstoasc -y rtmp://live.hercd.com:1935/hls/test
这个是可以把视频流转推到自己vps的,但是vps需要提前安装nginx,以及nginx的rtmp模块的一个代码,就是上面那一段介绍安装的部分。
环境搭建好之后,可以直接本地推流成.m3u8的流媒体,直接引用
streamlink --twitch-disable-ads https://www.twitch.tv/thebs_chen best -O | ffmpeg -re -i pipe:0 -vcodec copy -acodec copy -strict -2 -f flv rtmp://127.0.0.1:1935/hls/chatcyf
streamlink https://www.youtube.com/channel/UC7QVieoTCNwwW84G0bddXpA/live best -O | ffmpeg -re -i pipe:0 -vcodec copy -acodec copy -strict -2 -f flv rtmp://127.0.0.1:1935/hls/chatcyf
当然,上面的内容都是手动执行的,如果需要自动转发到本地,可以用这个脚本试试:https://github.com/gav-X/RepushStream
后来又用chatgpt写了个脚本,这里:https://github.com/loadream/loadream.github.io/
还有一点就是,这上面的几个运行命令,都是把直播间的流媒体转发到本地的带rtmp的nginx,如果需要借助nginx把拉取到的流转发到更多地方,可以把上面的/www/server/nginx/conf/rtmp/nginx-rtmp.conf 这个文件夹中
把 #exec_push ffmpeg -i rtmp://127.0.0.1/hls/$name -c:v copy -c:a aac -f flv rtmp://destination_server/live/output_stream; 这一行内容的 # 去掉
这样每次1935端口接收到流媒体的时候,会自动使用ffmpeg转推出去,当然别忘了修改成你的推流地址,以及重启一下nginx服务。
如果需要转推更多平台,又或者用纯音频转推成icecast之类的,可以安装docker,使用docker安装restreamer后,借助restreamer这工具,转推到更多地方。
docker run -d --restart=always --name restreamer \
-v /opt/restreamer/config:/core/config \
-v /opt/restreamer/data:/core/data \
-p 8080:8080 \
-p 1936:1936 \
-p 6000:6000/udp \
datarhei/restreamer:latest
下面的内容是随便整理的,随便看看吧。
顺便介绍一个 使用ffmpeg 循环推流mp4文件的命令
ffmpeg -re -stream_loop -1 -i url.mp4 -vcodec copy -acodec copy -f flv -y rtmp://live.hercd.com:1935/hls/test
ffmpeg推流多个mp4文件的方法
ffmpeg -re -stream_loop -1 -f concat -safe 0 -i list.txt -rw_timeout 30000000 -codec copy -f flv -bsf:a aac_adtstoasc -y rtmp://youip/youpassword
注意这个list文件,以及list.txt的文件内容,大概如下就行
file '1.mp4'
file '2.mp4'
file '3.mp4'
还要借助.sh脚本做循环,比如起名 push.sh
#!/bin/bash
while true
do
ffmpeg -re -f concat -safe 0 -i list.txt -vcodec copy -acodec copy -f flv "rtmp://rtmp地址/你的直播码"
done
最后执行 sh push.sh
如果你想无缝推流的话,可以使用 mkfifo 的管道,然后把所有视频文件连起来使用ts推流
mkfifo push
#!/bin/bash
while true
do
ffmpeg -re -f concat -safe 0 -i list.txt -f mpegts -vcodec copy -acodec aac -vbsf h264_mp4toannexb pipe:1.ts | cat - >> push
done
ffmpeg -re -i push -c:v copy -c:a aac -f flv "rtmp://rtmp地址/你的直播码"