之前介绍过,使用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

 

如果提示 error: externally-managed-environment 报错,这里分享几个解决办法

第一种,那就把所有python的命令后面加上 --break-system-packages

比如上面的后续更新pip3的那个,则是这样

python3 -m pip install --upgrade pip --break-system-packages

其他命令运行出现错误也是如此

 

第二种,删掉这个 python3.11/EXTERNALLY-MANAGED

sudo rm /usr/lib/python3.11/EXTERNALLY-MANAGED

 

第三种,给 ~/.config/pip/pip.conf 添加一个设置部分,但说真的这个我不太会,所以推荐第二种

[global] break-system-packages = true

 

安装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地址/你的直播码"