prinsss / live-stream-recorder

Monitor and record live streams from YouTube, OPENREC, TwitCasting, etc. Made for VTuber fans. (VTuber 直播自动录像脚本)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Live Stream Recorder

一系列简陋的 Bash 脚本,可以实现 YouTube、OPENREC、Twitch、TwitCasting 等平台主播开播时自动录像。

因为我喜欢的 VTuber 神楽めあ 是个喜欢突击直播还不留档的惯犯,所以我写了这些脚本挂在 VPS 上监视直播动态,一开播就自动开始录像,这样就算错过了直播也不用担心。

脚本的工作原理很简单,就是每隔一段时间检查一次直播状态(这个延迟可以通过脚本调用参数调节),如果在播就开始录像,没在播就继续轮询,非常简单粗暴(因为我懒得用 PubSubHubbub,而且我这台 VPS 就是专门为了录像买的,所以不用在意性能之类的问题)。

这些脚本支持的直播平台基本上覆盖了 mea 的活动范围,如果有其他希望支持的平台也可以开 issue。

前置依赖

本脚本依赖以下程序,请自行安装并保证能在 $PATH 中找到。

  • ffmpeg
  • youtube-dl
  • streamlink

需要注意的是,各大 Linux 发行版官方软件源中的 ffmpeg 版本可能过旧(3.x 甚至 2.x),录像时会出现奇怪的问题,推荐在 这里 下载最新版本(4.x)的预编译二进制文件。

关于 ffmpeg 4.x,Ubuntu 用户可以通过 PPA 进行简易安装:

sudo add-apt-repository ppa:jonathonf/ffmpeg-4
sudo apt update
sudo apt install ffmpeg

youtube-dl 和 streamlink 都可以直接使用 pip 进行安装,以下为相关安装指南:

YouTube 自动录像

./record_youtube.sh url [format] [loop|once] [interval]

# Example
./record_youtube.sh "UCWCc8tO-uUl_7SJXIKJACMw"
./record_youtube.sh "https://www.youtube.com/channel/UCWCc8tO-uUl_7SJXIKJACMw/live" best loop 30
./record_youtube.sh "https://www.youtube.com/watch?v=NeQrejV3JnE" best once
./record_youtube.sh "https://youtu.be/WMu7SGeUTG4" 480p

第一个参数为 YouTube 频道 ID(就是频道 URL youtube.com/channel 后面的那个),或者待机室的 URL(即在频道 URL 后面添加 /live),这样可以实现无人值守监视开播。参数也可以是某次直播的直播页面 URL(如示例三),不过这样就只能对这一场直播进行录像,录不到该频道的后续直播,所以推荐使用前者。

第二个参数为可选参数,指定录像的画质,默认为可用的最高画质。更多可以使用的格式字符串请参考 streamlink STREAM 参数的文档。e.g. 指定为 720p,480p,best 即可以最高不大于 720p 的格式录像。

第三个参数为可选参数,如果指定为 once,那么当前直播的录像完成后脚本会自动退出,而不会继续监视后续直播。

第四个参数为每次直播流状态检查之间的间隔(单位为秒,默认值为 10,即每隔 10s 检查一次)。

录像文件默认保存在脚本文件所在的目录下,文件名格式为 youtube_{id}_YYMMDD_HHMMSS.ts。输出的视频文件使用 MPEG-2 TS 容器格式保存,因为 TS 格式有着可以从任意位置开始解码的优势,就算录像过程中因为网络波动等问题造成了中断,也不至于损坏整个视频文件。如果需要转换为 MP4 格式,可以使用以下命令:

ffmpeg -i xxx.ts -codec copy xxx.mp4

为了避免下播后 ffmpeg 录像进程依然挂起(因为我没做输入流的可用性判断,所以以前的脚本会有进程挂起的问题,可能造成挂起期间内无法录像等问题),以及支持 HLS Seeking(即从中途开始运行也能从当前直播的开头处开始录像,不过只在有限的情况下可用),本脚本使用 streamlink 而非 ffmpeg 进行录像。另外,当前直播的元信息(ID、标题、概要栏等)保存在 视频文件名.info.txt 文件中,录像时 streamlink 进程的详细输出会写入至 视频文件名.log 日志文件,使用 tail -f xxx.log 命令可以实时查看。

OPENREC 自动录像

./record_openrec.sh openrec_id [format] [loop|once] [interval]

# Example
./record_openrec.sh KaguraMea 480p
./record_openrec.sh 23_kanae best once

此脚本依赖 curl 以从用户频道页面获取当前的直播信息。

第一个参数为 OPENREC 用户名,就是用户主页 URL 中 openrec.tv/user 后面的那个。第二、三、四个参数与 YouTube 的脚本相同。

录像的文件名格式为 openrec_{id}_YYMMDD_HHMMSS.ts,其他与上面的相同。

另外,streamlink v0.14.2 对 OPENREC 的支持有问题,你需要参照这个 issue 手动加载更新后的 streamlink OPENREC 插件,或者等待 streamlink 本体发布新版本。如果运行中出现了 error: 'ascii' codec can't encode character 错误,那么你可能需要升级 Python 2.x 至 Python 3.x,或者在 streamlink/plugins/openrectv.py 文件的头部添加以下代码:

import sys
reload(sys)
sys.setdefaultencoding('utf8')

Twitch 自动录像

./record_twitch.sh twitch_id [format] [loop|once] [interval]

# Example
./record_twitch.sh kagura0mea 480p
./record_twitch.sh wuyikoei best once

第一个参数为 Twitch 用户名,就是直播页面 URL 中 twitch.tv 后面的那个。第二、三、四个参数与 YouTube 的脚本相同。

录像的文件名格式为 twitch_{id}_YYMMDD_HHMMSS.ts,其他与上面的相同。

TwitCasting 自动录像

./record_twitcast.sh twitcasting_id [loop|once] [interval]

# Example
./record_twitcast.sh kaguramea
./record_twitcast.sh twitcasting_jp once

第一个参数为 TwitCasting 用户名,就是直播页面 URL 中 twitcasting.tv 后面的那个。第二个参数为可选参数,如果指定为 once,那么当前直播的录像完成后脚本会自动退出,而不会继续监视后续直播。此脚本无法指定要抓取的直播流的画质。

录像的文件名格式为 twitcast_{id}_YYMMDD_HHMMSS.ts(画质较差),其他与上面的相同。

另外,由于 TwitCasting 的高清录像必须通过 WebSocket 获取,而且 bash 脚本在这方面比较力不从心,所以推荐配合 livedl 这个工具来实现 TwitCasting 平台的高清录像。将构建好的 livedl 可执行文件放在与此脚本相同的目录下即可,脚本会自动调用(由于上游限制,高清录像的文件名格式固定为 {twitcasting_id}_{movie_id}.ts)。

其他直播平台自动录像

基本上 streamlink 支持的直播站点 都支持(包括国内的斗鱼、熊猫什么的)。

./record_streamlink.sh live_url [format] [loop|once] [interval]

# Example
./record_streamlink.sh "https://www.douyu.com/3614"
./record_streamlink.sh "https://www.panda.tv/371037"

第一个参数为直播间 URL,第二、三、四个参数与 YouTube 的脚本相同。

录像的文件名格式为 stream_YYMMDD_HHMMSS.ts,其他与上面的相同。

通过 .m3u8 地址手动录像

此脚本适用于任何已知 .m3u8 地址的情况,不过只能对传入的该场直播进行录像,无法监视后续直播与自动录像。

如果上面的脚本没有适配某个平台(比如 Mirrativ、SHOWROOM),你也可以自己抓取出 .m3u8 地址手动开始录像。

./record_m3u8.sh "https://record.mirrativ.com/archive/hls/39/0018438274/playlist.m3u8"

第一个参数为 .m3u8 地址,录像的文件名格式为 stream_YYMMDD_HHMMSS.ts

第二个参数为可选参数,指定为 loop 可以让脚本每隔一段时间(第三个参数)尝试下载该 .m3u8 地址。

转播推流

这些脚本虽然是用来录像的,但是稍微修改一下也可以用于推流转播至其他直播平台。

将各脚本中的:

ffmpeg -i "$M3U8_URL" -codec copy -f mpegts "$FNAME" > "$FNAME.log" 2>&1

修改为:

RTMP_URL="这里填你的 RTMP 推流地址"
ffmpeg -i "$M3U8_URL" \
  -codec copy -f mpegts "$FNAME" \ # 不需要录像的可以去掉这一行
  -vcodec copy -acodec aac -strict -2 -f flv "$RTMP_URL" \
  > "$FNAME.log" 2>&1

即可实现同时录像与转播推流。

后台运行脚本

如果用上面那些方式运行脚本,终端退出后脚本就会停止,所以你需要使用 nohup 命令将脚本放到后台中运行:

nohup ./record_youtube.sh "UCWCc8tO-uUl_7SJXIKJACMw" > mea.log &

这会把脚本的输出写入至日志文件 mea.log(文件名自己修改),你可以随时使用 tail -f mea.log 命令查看实时日志。

其他脚本同理:

nohup ./record_twitch.sh kagura0mea > mea_twitch.log &
nohup ./record_twitcast.sh kaguramea > mea_twitcast.log &
nohup ./record_openrec.sh KaguraMea > mea_openrec.log &

使用命令 ps -ef | grep record 可以列出当前正在后台运行的录像脚本,其中第一个数字即为脚本进程的 PID:

root      1166     1  0 13:21 ?        00:00:00 /bin/bash ./record_youtube.sh ...
root      1558     1  0 13:25 ?        00:00:00 /bin/bash ./record_twitcast.sh ...
root      1751     1  0 13:27 ?        00:00:00 /bin/bash ./record_twitch.sh ...
root      1755     1  0 13:29 ?        00:00:00 /bin/bash ./record_openrec.sh ...

如果需要终止正在后台运行的脚本,可以使用命令 kill {pid}(比如要终止上面的第一个 YouTube 录像脚本,运行 kill 1166 即可)。

开源许可

MIT License (c) 2018-2019 printempw

About

Monitor and record live streams from YouTube, OPENREC, TwitCasting, etc. Made for VTuber fans. (VTuber 直播自动录像脚本)

License:MIT License


Languages

Language:Shell 100.0%