GiGaFotress / Vtuber-recorder

VTB多平台全自动录制
MIT License
70 stars 8 forks source link

录播参数求助 #1

Closed Metric-Void closed 4 years ago

Metric-Void commented 4 years ago

主要使用的是Bilibili录制,始终找不到合适的参数。


以下代码(现在的master branch head)会在文件达到1G时截断且无法写入元数据。看日志像是磁盘满了,无法写入更多数据一样。录制时不向硬盘写入文件,只有在达到1G并崩溃之后才会写入硬盘。 加了换行以便看得清楚。实际使用的时候没有换行。

ffmpeg
   -user_agent "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" \
   -headers "referer: https://live.bilibili.com/" \
   -i "$M3U8_URL"  -codec copy -map 0:a -map 0:v \
   -f hls -hls_time 3600 -hls_list_size 0 "$5$FNAME" \
   > "${5}log/${FNAME}.log" 2>&1

日志尾部:

av_interleaved_write_frame(): Operation not permitted
[hls @ 0x6376780] Opening '/mnt2/****/testbil/bil_*****_20200602_0839270.ts' for writing
[hls @ 0x6376780] Opening '/mnt2/****/testbil/bil_*****_20200602_083927.ts.tmp' for writing
Error writing trailer of /mnt2/****/testbil/bil_*****_20200602_083927.ts: Operation not permitted
frame=77246 fps= 24 q=-1.0 Lsize=N/A time=00:53:38.57 bitrate=N/A speed=0.99x
video:913358kB audio:98510kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Conversion failed!

以下代码会在遇到断流时中断并卡住ffmpeg进程。日志的最后一行是"Non-Monotonous DTS"。 加了换行以便看得清楚。实际使用的时候没有换行。

ffmpeg
    -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 15 \
    -user_agent "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" \
    -headers "referer: https://live.bilibili.com/" \
    -i "$M3U8_URL" -codec copy -map 0:a -map 0:v \
    -f mpegts "$5$FNAME" \
    > "${5}log/${FNAME}.log" 2>&1

日志尾部(在这之后ffmpeg卡住了,但是没有退出)

[mpegts @ 0x7711380] Non-monotonous DTS in output stream 0:0; previous: 1309987172, current: 184894500; changing to 1309987173. This may result in incorrect timestamps in the output file.
[mpegts @ 0x7711380] Non-monotonous DTS in output stream 0:1; previous: 1309944855, current: 184895460; changing to 1309944856. This may result in incorrect timestamps in the output file.
[mpegts @ 0x7711380] Non-monotonous DTS in output stream 0:0; previous: 1309987173, current: 184896590; changing to 1309987174. This may result in incorrect timestamps in the output file.
[mpegts @ 0x7711380] Non-monotonous DTS in output stream 0:0; previous: 1309987174, current: 184898680; changing to 1309987175. This may result in incorrect timestamps in the output file.
[mpegts @ 0x7711380] Non-monotonous DTS in output stream 0:1; previous: 1309944856, current: 184899150; changing to 1309944857. This may result in incorrect timestamps in the output file.

两个代码分别在CentOS和Debian上测试,都有一样的问题。虚拟机8c8t, 8G内存,位于境内,使用BBR。磁盘是LVM,文件系统btrfs,剩余空间充足。

GiGaFotress commented 4 years ago

我部署了一下环境试了一下,新版本ffmpeg对分片的存储进行了改动,以前是直接产生m3u8和分片文件,现在需要等到录制达到分片条件后才会实际产出第一个分片文件和m3u8列表文件,而程序内设计是每小时一次分片,结合日志没看懂你说的1GB就停止了是啥情况

这个似乎是你的类似情况,我太困了你自己先看看

DTS那个是b站烂时间戳的老毛病了,理论上不影响文件的产出但是得手修时间戳,不过我没见过在这个地方卡顿的情况,试试-f flv? 然后如果你不需要省硬盘你可以考虑使用我注释掉的biliroku来处理,不过我项目里带着的是老版本了,新的得编译一下

GiGaFotress commented 4 years ago

av_interleaved_write_frame(): Operation not permitted muxing overhead: unknown Conversion failed! 这个错误在能复现的情况下试试更换为-f flv是否还出现bug,我在centos7 ext4上测试两种都没问题

Metric-Void commented 4 years ago

如果使用-f flv的话,文件后缀名还是ts吗?

1G那个不是给出链接中的问题。给出链接中的是mxf filter的bug。我的日志中的Operation not permitted 更像是文件达到限制 无法继续写入。我唯一能想到的1G来自哪里就是支持大页内存(CPUID +pdpe1gb) (我的两个环境swap都是2G,且在录制过程中基本零占用)

Metric-Void commented 4 years ago

用-f flv开始测试了,要几个小时,之后回报。

GiGaFotress commented 4 years ago

后缀名在FNAME里面,默认是ts,但是内部视频结构实际上只跟解编码器有关系

Metric-Void commented 4 years ago

flv测好了,在连接突然断开的时候仍然会卡住。日志结尾没有Non-monotonous DTS. 日志结尾:

frame=583362 fps= 24 q=-1.0 size= 7907328kB time=06:45:06.70 bitrate=2665.0kbits/s speed=   1x

就这样卡住不动了

GiGaFotress commented 4 years ago

你找个直播间我测试一下吧,我这边复现不了

Metric-Void commented 4 years ago

我一直都是随便在b站上搜索"24小时" 现在用这个测试的 https://live.bilibili.com/5854051 直播丢包不是很好模拟,所以我是重设虚拟网卡观察效果

GiGaFotress commented 4 years ago

DTS那个提示一般在哪里出现都有,他是个接收到的数据有错误的提示

是不是你断开网络的时候ssh也断开了?不用nohub/screen在后台运行的话ssh断开录制也会断开的

Metric-Void commented 4 years ago

我用screen开的录制线程 用VNC重设的interface

Metric-Void commented 4 years ago

刚才我自己摸了下参数,发现了stream_segment这个muxer。可以分段,文件会实时写入硬盘而不是cache. 重设interface之后似乎可以恢复?进程没卡住,马上看看最终文件发生了什么

ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 15 \
    -user_agent "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" \
    -headers "referer: https://live.bilibili.com/" -i "$M3U8_URL" -codec copy -map 0:a -map 0:v \
    -f ssegment -segment_list "${FNAME_BARE}.ffconcat" -segment_list_flags live -segment_time 3600 \
    "$5${FNAME_BARE})part%04d.ts" > "${5}log/${FNAME}.log" 2>&1
Metric-Void commented 4 years ago

以上代码的测试

给虚拟机设了两个网卡,一个连公网,default路由。一个内网,只有内网的路由。通过内网网卡连进ssh, tail -f 观察进度。 通过hypervisor拔掉公网网卡之后,进度卡住。 通过hypervisor接回公网网卡,帧位跳变(估计肯定的吧,中间应该丢了,马上拉下来看),并且继续录制

GiGaFotress commented 4 years ago

-segment_list_flags live实时写入应该是这个flag控制,我测试了一下效果和hls分段差不多但是不会生成m3u8文件,以及可以不需要写入segmentlist那段参数 至于你说的进度卡住应该数秒内会自动结束写入吧?

GiGaFotress commented 4 years ago

我试了试断网,一两秒仍然能补上似乎,再长就断开连接重新检测live状态了,没能复现你说的卡住的情况

Metric-Void commented 4 years ago

至于你说的进度卡住应该数秒内会自动结束写入吧?

没有,它就是.... 卡在那里。我等了15秒,参数中的重连时间,它还是卡在那里,联网之后就又继续了

不会生成m3u8文件

我是用segment_list生成了一个ffconcat文件,可以用ffmpeg -f concat -i "xxx.ffconcat" 来合并。这是我的使用方法,所以这么做了

GiGaFotress commented 4 years ago

一开始不分片不就完了么```你还想拖下来合并么?算了这个你自己处理

frame=14036 fps= 23 q=-1.0 size=N/A time=00:09:44.81 bitrate=N/A speed=0.966x    
[https @ 0x6b99100] Last chunk received, closing conn
No more output streams to write to, finishing.
[hls @ 0x6bac380] Opening '/home/centos/Vtuber-recorder/savevideo/bil_5854051_郭德纲于谦晚安相声音频24小时轮播_20200617_1305080.ts' for writing
[file @ 0x6e13b40] Setting default whitelist 'file,crypto,data'
[AVIOContext @ 0x6dafc00] Statistics: 0 seeks, 760 writeouts
[hls @ 0x6bac380] Opening '/home/centos/Vtuber-recorder/savevideo/bil_5854051_郭德纲于谦晚安相声音频24小时轮播_20200617_130508.ts.tmp' for writing
[file @ 0x6dbae00] Setting default whitelist 'file,crypto,data'
EXT-X-MEDIA-SEQUENCE:0
[AVIOContext @ 0x6dafc00] Statistics: 0 seeks, 1 writeouts
frame=14113 fps= 23 q=-1.0 Lsize=N/A time=00:09:48.02 bitrate=N/A speed=0.969x    
video:170674kB audio:17060kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Input file #0 (https://d1--cn-gotcha04.bilivideo.com/live-bvc/195896/live_8156551_5688965.flv?cdn=cn-gotcha04&expires=1592373912&len=0&oi=3751747669&pt=web&qn=10000&trid=47281b057a6443a3a616f2dbfeaed36b&sigparams=cdn,expires,len,oi,pt,qn,trid&sign=18390171a4aba57f8eb521677dfc00b2&ptype=0):
  Input stream #0:0 (audio): 25323 packets read (17469019 bytes); 
  Input stream #0:1 (video): 14113 packets read (174770159 bytes); 
  Total: 39436 packets (192239178 bytes) demuxed
Output file #0 (/home/centos/Vtuber-recorder/savevideo/bil_5854051_郭德纲于谦晚安相声音频24小时轮播_20200617_130508.ts):
  Output stream #0:0 (audio): 25323 packets muxed (17469019 bytes); 
  Output stream #0:1 (video): 14113 packets muxed (174770159 bytes); 
  Total: 39436 packets (192239178 bytes) muxed
0 frames successfully decoded, 0 decoding errors
[AVIOContext @ 0x6baa100] Statistics: 192952422 bytes read, 0 seeks

我这边大概五六秒钟检测到真的断网会自己完成写入,你试试更新下ffmpeg?

Metric-Void commented 4 years ago
[root@rock log]# ffmpeg -version
ffmpeg version N-53005-gc0f01eaf12-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil      56. 49.100 / 56. 49.100
libavcodec     58. 89.100 / 58. 89.100
libavformat    58. 43.100 / 58. 43.100
libavdevice    58.  9.103 / 58.  9.103
libavfilter     7. 83.100 /  7. 83.100
libswscale      5.  6.101 /  5.  6.101
libswresample   3.  6.100 /  3.  6.100
libpostproc    55.  6.100 / 55.  6.100

并不是总能恢复... 有时候仍然会卡住。top可以看到ffmpeg进程还在那里,但是log和文件写入都停了。

GiGaFotress commented 4 years ago

情况很怪,直接用ssh没使用screen,断网可能导致进程没退出去

        ├─sshd─┬─7*[sshd───sftp-server]
        │      ├─2*[sshd───bash───record_bil.sh───ffmpeg]
        │      └─sshd───bash───pstree
GiGaFotress commented 4 years ago

你试试编译一个biliroku来处理流试试,网上都是怎么让ffmpeg退出而不是我们这种他自己不退出

Metric-Void commented 4 years ago

现代C++和CMake是我的知识盲区.... 就比如Download the CURL source and compile it;吧 我压根不知道compile完放在哪里 我就只会Makefile

GiGaFotress commented 4 years ago

稳定复现似乎,我怀疑是ffmpeg搞出来的问题,但是测试的时候没有用过这种蓄意断网15秒以上的

Metric-Void commented 4 years ago

在自己的电脑上裸测了一下。Arch Linux.

ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 15 \
    -user_agent "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" \
    -headers "referer: https://live.bilibili.com/" -i "$(streamlink --stream-url https://live.bilibili.com/21564812 best)" -codec copy -map 0:a -map 0:v \
    -f ssegment -segment_list "test.ffconcat" -segment_list_flags live -segment_time 3600 \
    "test_part%04d.ts"
ffmpeg -reconnect 0 -reconnect_streamed 0 \
    -user_agent "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" \
    -headers "referer: https://live.bilibili.com/" -i "$(streamlink --stream-url https://live.bilibili.com/21564812 best)" -codec copy -map 0:a -map 0:v \
    -f ssegment -segment_list "test.ffconcat" -segment_list_flags live -segment_time 3600 \
    "test_part%04d.ts"

断网都不会结束录制。

Metric-Void commented 4 years ago

找到方法了,在http protocol里加一个timeout 下面是测试结果

[allen@allen-pc Downloads]$ ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 10 -timeout 2000 \
    -user_agent "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0" \
    -headers "referer: https://live.bilibili.com/" -i "$(streamlink --stream-url https://live.bilibili.com/21564812 best)" -codec copy -map 0:a -map 0:v \
    -f ssegment -segment_list "test.ffconcat" -segment_list_flags live -segment_time 3600 \
    "test_part%04d.ts"
ffmpeg version n4.2.3 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 10.1.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-nvdec --enable-nvenc --enable-omx --enable-shared --enable-version3
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
[https @ 0x560fe37f93c0] No trailing CRLF found in HTTP header. Adding it.
Input #0, flv, from 'https://d1--cn-gotcha05.bilivideo.com/live-bvc/292508/live_11203281_28590136.flv?cdn=cn-gotcha05&expires=1592381644&len=0&oi=2917543671&pt=web&qn=10000&trid=ce13cdae39634bb6a02eb96693b5c689&sigparams=cdn,expires,len,oi,pt,qn,trid&sign=ad914357469c34d4bbc495433f26b3d6&ptype=0':
  Metadata:
    Rawdata         : 
    displayWidth    : 1280
    displayHeight   : 720
    fps             : 30
    profile         : 
    level           : 
    encoder         : libobs/23.1.0 LiveHime/3.15.0 (Windows)
  Duration: 00:00:00.00, start: 0.022000, bitrate: N/A
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1280x720, 1536 kb/s, 30 fps, 30 tbr, 1k tbn, 60 tbc
    Stream #0:1: Audio: aac (LC), 44100 Hz, stereo, fltp, 131 kb/s
[stream_segment,ssegment @ 0x560fe3e1acc0] Opening 'test.ffconcat' for writing
[stream_segment,ssegment @ 0x560fe3e1acc0] Opening 'test_part0000.ts' for writing
Output #0, stream_segment,ssegment, to 'test_part%04d.ts':
  Metadata:
    Rawdata         : 
    displayWidth    : 1280
    displayHeight   : 720
    fps             : 30
    profile         : 
    level           : 
    encoder         : Lavf58.29.100
    Stream #0:0: Audio: aac (LC), 44100 Hz, stereo, fltp, 131 kb/s
    Stream #0:1: Video: h264 (High), yuv420p(tv, bt709, progressive), 1280x720, q=2-31, 1536 kb/s, 30 fps, 30 tbr, 90k tbn, 30 tbc
Stream mapping:
  Stream #0:1 -> #0:0 (copy)
  Stream #0:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
[tls @ 0x560fe37fb800] Error in the pull function.10 bitrate=N/A speed=1.31x    
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 0 second(s), error=Input/output error.
[tcp @ 0x560fe3ecd000] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 1 second(s), error=Input/output error.
[tcp @ 0x560fe3ecd000] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 3 second(s), error=Input/output error.
[tcp @ 0x560fe3e45480] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 7 second(s), error=Input/output error.
[tcp @ 0x560fe3e41b80] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
    Last message repeated 1 times
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 0 second(s), error=Input/output error.
[tcp @ 0x560fe3e45480] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 1 second(s), error=Input/output error.
[tcp @ 0x560fe38a2940] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 3 second(s), error=Input/output error.
[tcp @ 0x560fe3e57740] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
[https @ 0x560fe37f93c0] Will reconnect at 1407007 in 7 second(s), error=Input/output error.
[tcp @ 0x560fe38a2980] Failed to resolve hostname 0gr4uqmtt8y41hcjzgazdrpbz.ourdvsss.com: Name or service not known
[tls @ 0x560fe37fb800] The specified session has been invalidated for some reason.
frame=  219 fps=7.9 q=-1.0 Lsize=N/A time=00:00:07.24 bitrate=N/A speed=0.261x    
video:1250kB audio:114kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

开始录制后一会断网,重连失败后自动退出。

GiGaFotress commented 4 years ago

测试了18年的ffmpeg版本也有这个情况,开始没有测试过用户拔线的情况,应该算是个隐藏的bug,我也改一下脚本

注意一下,那个timemout的单位恐怕是微秒,对于b站用那么低可能会导致期待外的断流

Metric-Void commented 4 years ago

啊 我看了下 还真是microsecond... 加三个零 问题都没了 我close了