我需要确保唯一的段名称:校园周围明显的 POE 电缆缺陷等导致 HikVision 摄像机流需要每天重新启动一次或两次或更多次其 ffmpeg 守护程序。 (我大部分时间都离这个校园很远,所以我更喜欢在硬件修复应用之前使用命令行修复。)当必须为摄像机重新启动 ffmpeg 时(通过后台 bash 脚本),我需要新的 .mp4 段的名称绝对不能与任何以前的名称相同。
后台 bash 进程目前可以在 ffmpeg 重启后为第一个片段指定可接受的 ddHHMM 样式的新起始名称,但在制作第一个或第二个或第三个片段后,ffmpeg 坚持将来的命名默认为不可接受的 YYYmmdd 样式,从而开始覆盖以前的片段。我用它$(date +%d%H%M)
来获得我可接受的日期样式。
我尝试了很多不同的日期代码和日期嵌入以及段和段复用器的组合;此外,除了简单的 rtsp 流复制到 .mp4 文件之外,我对 ffmpeg 通常使用的非常复杂的领域知之甚少。
从 bash 脚本内部启动的 ffmpeg 命令:bash -c 'nohup ffmpeg -nostdin -stimeout 10000000 -rtsp_transport udp -i "rtsp://192.168.0.11:6554/Streaming/channels/101" -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -c:v libx264 -f ssegment -strftime 0 -segment_time 180 -segment_format_options movflags=+faststart -reset_timestamps 0 -increment_tc 1 -avoid_negative_ts 1 -c copy -flags +global_header /var/www/camera_streams/camera_east_driveway/"$(date +%d%H%M)"_%3d.mp4 > /dev/null 2>/dev/null & '
片段命名模式是否可以像我希望的那样无限期地延续?老实说,我想知道 ffmpeg 是否不允许我特定用例的命名需求?
(是的,我知道从 udp 更改为 tcp 会有所帮助,但我不认为这是我现在希望的特定固定命名修复。我提到 HikVision 是因为已知它们的帧编码与其他摄像机存在差异)
段复用器的错误信息取决于 -strftime 是否为 0(其中我必须指定文件名)"$(date +%d%H%M)"_%3d.mp4)
或 1(其中我必须指定文件名"%Y-%m-%d_%H-%M-%S.mp4"
)
其中 strftime 为 0,则错误为:
[stream_segment,ssegment @ 0x558d8618d2c0] Could not increment global timecode, no global timecode metadata found.
[stream_segment,ssegment @ 0x558d8618d2c0] Opening '/var/www/camera_streams/camera_south_driveway/220141_001.mp4' for writing
[mp4 @ 0x558d862f3d40] Starting second pass: moving the moov atom to the beginning of the file
[stream_segment,ssegment @ 0x558d8618d2c0] Could not increment global timecode, no global timecode metadata found.
frame= 1434 fps=8.1 q=-1.0 Lsize=N/A time=00:03:00.65 bitrate=N/A speed=1.02x
video:21966kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Exiting normally, received signal 15.
其中 strftime 为 1,则错误为:
[stream_segment,ssegment @ 0x55cd7ae7e240] Opening '/var/www/camera_streams/camera_east_driveway/2022-07-22_01-23-48.mp4' for writing
Output #0, stream_segment,ssegment, to '/var/www/camera_streams/camera_east_driveway/%Y-%m-%d_%H-%M-%S.mp4':
Metadata:
title : Media Presentation
encoder : Lavf58.29.100
Stream #0:0: Video: h264 (Main), yuvj420p(pc, bt709, progressive), 2560x1440, q=2-31, 6.25 tbr, 90k tbn, 90k tbc
Stream mapping:
Stream #0:0 -> #0:0 (copy)
[stream_segment,ssegment @ 0x55cd7ae7e240] 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
[stream_segment,ssegment @ 0x55cd7ae7e240] Non-monotonous DTS in output stream 0:0; previous: 0, current: 0; changing to 1. This may result in incorrect timestamps in the output file.
[mp4 @ 0x55cd7ae959c0] Starting second pass: moving the moov atom to the beginning of the file
[stream_segment,ssegment @ 0x55cd7ae7e240] Could not increment global timecode, no global timecode metadata found.
frame= 34 fps=7.1 q=-1.0 Lsize=N/A time=00:00:25.59 bitrate=N/A speed=5.35x
video:418kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Exiting normally, received signal 15.
答案1
作为一种解决方法,我将使用标志值,-strftime 0
这样我就可以获取%3d
ffmpeg 将其 %d 重置为零后生成的特定段文件名中的值。使用 inotifywait 守护进程捕获该事件,我将终止 ffmpeg 进程并启动一个新进程,其段名称包含该小时和分钟。