我通过以下方式将 rtsp 流录制到一系列分段文件中
ffmpeg -t $((5*60*60)) \
-i 'rtsp://[email protected]:88/videoMain' \
-c copy -map 0 \
-f segment -segment_time 60 -segment_format mkv \
"recording-%03d.mkv" \
2> "${dir}log"
在 VLC 中播放这些单独的录音时,我注意到每个文件中的时间戳都在不断增加,因此最后一个文件的第一秒不是该文件的时间戳 00:00,而是 4:59:00。由于每个剪辑只有 60 秒长,因此很难用鼠标跳转到视频的某个位置,因为整个 1 分钟的剪辑只是几个小时的轨道条的一小部分。
由于所有小录音的总大小只有 1.5 GiB,我认为将它们连接起来以取消分段可能更容易。我的第一次尝试还将视频移动到 MP4 容器中,以便 Chromium 可以播放它们。
ffmpeg -f concat -safe 0 -i <(find . -name '*.mkv' -printf "file '$PWD/%p'\n"|sort) -c:v copy output.mp4
有几个问题。首先,它从错误的地方开始。recording-000.mkv 的内容与播放的视频的前 60 秒不匹配。播放完第一分钟的视频后,视频停止更新。VLC 继续推进轨道条,时间戳上升,但视频源从未更新。如果我尝试跳到视频中的任意点,就会记录一些解码错误。VLC 似乎认为它有 749 小时长。
因此,在第二次尝试中,我将其保留为 mkv,并尝试添加segment_time_metadata
,认为这也许有助于保留时间戳。但是,我一直不知道它是否有用,因为在写入输出文件约 1TiB 后,我将其关闭了。
ffmpeg -f concat -safe 0 -segment_time_metadata 1 -i <(find . -name '*.mkv' -printf "file '$PWD/%p'\n"|sort) -c:v copy output.mkv
我怀疑来自 IP 摄像机的 RTSP 流可能格式不正确。但是,如果我只将其录制到单个 mp4 文件中,VLC 就可以正常播放,并且时间戳都是正确的。因此,问题似乎是格式错误的流和分段+连接的组合。
ffmpeg version n4.3.1 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-librav1e --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. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Guessed Channel Layout for Input Stream #0.1 : mono
Input #0, rtsp, from 'rtsp://[email protected]:88/videoMain':
Metadata:
title : IP Camera Video
comment : videoMain
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: h264 (Constrained Baseline), yuvj420p(pc, progressive), 1280x720, 14.99 tbr, 90k tbn, 180k tbc
Stream #0:1: Audio: pcm_mulaw, 8000 Hz, mono, s16, 64 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (pcm_mulaw (native) -> aac (native))
Press [q] to stop, [?] for help
[aac @ 0x5641eaec06c0] Too many bits 8832.000000 > 6144 per frame requested, clamping to max
Output #0, mp4, to 'live.mp4':
Metadata:
title : IP Camera Video
comment : videoMain
encoder : Lavf58.45.100
Stream #0:0: Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuvj420p(pc, progressive), 1280x720, q=2-31, 14.99 tbr, 90k tbn, 90k tbc
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 8000 Hz, mono, fltp, 48 kb/s
Metadata:
encoder : Lavc58.91.100 aac
[mp4 @ 0x5641eaec1580] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly