我正在运行一个ffmpeg
命令,将原始H.265数据复制到MP4文件中,该命令从未完成。该文件不大,只有10秒钟的数据价值。这是我正在运行的命令:
$ ffmpeg -rtsp_transport tcp -i rtsp://user:pass@71.185.124.195:554/c1/b1558830329/e1558830339/replay/ -vcodec copy -y test_clip.mp4
然后我得到这样的输出:
ffmpeg version 3.4.6-0ubuntu0.18.04.1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
configuration: --prefix=/usr --extra-version=0ubuntu0.18.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Guessed Channel Layout for Input Stream #0.1 : mono
Input #0, rtsp, from 'rtsp://user:pass@71.85.104.195:554/c1/b1558830329/e1558830339/replay/':
Metadata:
title : ONVIF RTSP Server
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: h264 (High), yuvj420p(pc, bt709, progressive), 1920x1080, 30 fps, 30 tbr, 90k tbn, 60 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 @ 0x55b71ce31900] Too many bits 8832.000000 > 6144 per frame requested, clamping to max
Output #0, mp4, to 'test_clip.mp4':
Metadata:
title : ONVIF RTSP Server
encoder : Lavf57.83.100
Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709, progressive), 1920x1080, q=2-31, 30 fps, 30 tbr, 90k tbn, 90k tbc
Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 8000 Hz, mono, fltp, 48 kb/s
Metadata:
encoder : Lavc57.107.100 aac
[mp4 @ 0x55b71ce17e00] Non-monotonous DTS in output stream 0:0; previous: 18000, current: 3000; changing to 18001. This may result in incorrect timestamps in the output file.
[mp4 @ 0x55b71ce17e00] Non-monotonous DTS in output stream 0:0; previous: 18001, current: 6000; changing to 18002. This may result in incorrect timestamps in the output file.
[mp4 @ 0x55b71ce17e00] Non-monotonous DTS in output stream 0:0; previous: 18002, current: 9000; changing to 18003. This may result in incorrect timestamps in the output file.
[mp4 @ 0x55b71ce17e00] Non-monotonous DTS in output stream 0:0; previous: 18003, current: 12000; changing to 18004. This may result in incorrect timestamps in the output file.
[mp4 @ 0x55b71ce17e00] Non-monotonous DTS in output stream 0:0; previous: 18004, current: 15000; changing to 18005. This may result in incorrect timestamps in the output file.
[mp4 @ 0x55b71ce17e00] Non-monotonous DTS in output stream 0:0; previous: 18005, current: 18000; changing to 18006. This may result in incorrect timestamps in the output file.
frame= 44 fps=0.0 q=-1.0 size= 256kB time=00:00:01.43 bitrate=1463.4kbits/frame= 60 fps= 57 q=-1.0 size= 512kB time=00:00:01.96 bitrate=2132.9kbits/frame= 76 fps= 48 q=-1.0 size= 768kB time=00:00:02.50 bitrate=2516.7kbits/frame= 92 fps= 44 q=-1.0 size= 1024kB time=00:00:03.03 bitrate=2765.6kbits/frame= 108 fps= 41 q=-1.0 size= 1024kB time=00:00:03.56 bitrate=2352.0kbits/[NULL @ 0x55b71cdfa540] SEI type 5 size 2208 truncated at 1944
frame= 123 fps= 39 q=-1.0 size= 1280kB time=00:00:04.06 bitrate=2578.6kbits/frame= 139 fps= 38 q=-1.0 size= 1536kB time=00:00:04.60 bitrate=2735.5kbits/frame= 155 fps= 37 q=-1.0 size= 1536kB time=00:00:05.13 bitrate=2451.3kbits/frame= 171 fps= 36 q=-1.0 size= 1792kB time=00:00:05.66 bitrate=2590.7kbits/frame= 187 fps= 36 q=-1.0 size= 2048kB time=00:00:06.20 bitrate=2706.1kbits/frame= 203 fps= 35 q=-1.0 size= 2304kB time=00:00:06.73 bitrate=2803.2kbits/frame= 219 fps= 35 q=-1.0 size= 2304kB time=00:00:07.26 bitrate=2597.4kbits/frame= 235 fps= 34 q=-1.0 size= 2560kB time=00:00:07.80 bitrate=2688.7kbits/frame= 246 fps= 33 q=-1.0 size= 2560kB time=00:00:08.16 bitrate=2568.0kbits/frame= 267 fps= 34 q=-1.0 size= 3072kB time=00:00:08.86 bitrate=2838.3kbits/frame= 282 fps= 34 q=-1.0 size= 3072kB time=00:00:09.36 bitrate=2686.8kbits/frame= 298 fps= 33 q=-1.0 size= 3328kB time=00:00:09.90 bitrate=2753.9kbits/frame= 314 fps= 33 q=-1.0 size= 3328kB time=00:00:10.43 bitrate=2613.1kbits/^Cspeed=1.11x
该命令永远不会完成,我需要使用Ctrl-C
将其杀死。
我还尝试添加选项-nostdin -loglevel error
并将其附加到命令末尾:> /dev/null 2>&1 < /dev/null
,但无济于事。
我正在测试上面的代码,因为它模仿了我正在开发的实际代码,该代码利用Python包包装了对ffmpeg
的调用。下面的Python代码在笔记本电脑上运行良好,但在EC2上都挂起(均为Ubuntu 18.04):
import argparse
import datetime
import ffmpeg
# ------------------------------------------------------------------------------
if __name__ == "__main__":
# USAGE
# $ python collect_and_store.py --rtsp rtsp://user:pass1@71.85.125.110:554 \
# --duration 30 --count 10
# construct the argument parser and parse the arguments
args_parser = argparse.ArgumentParser()
args_parser.add_argument("--rtsp",
required=True,
type=str,
help="RTSP URL for video stream")
args_parser.add_argument("--duration",
required=True,
type=int,
help="duration of saved clips (in seconds)")
args_parser.add_argument("--count",
required=True,
type=int,
help="number of clips to save")
args = vars(args_parser.parse_args())
# sanity check for some of the arguments
if not args["rtsp"].lower().startswith("rtsp://"):
raise ValueError("Invalid input URL -- only RTSP supported")
seconds_per_clip = args["duration"]
start = int(datetime.datetime.now().strftime("%s"))
end = start + seconds_per_clip
number_of_files_to_collect = args["count"]
while number_of_files_to_collect > 0:
# build URL with start and end times
# NOTE URL is for Uniview RTSP, add options for other camera types
url = args["rtsp"] + f"/c1/b{start}/e{end}/replay/"
# file where we'll write clip data
temp_file = f"clip_b{start}_e{end}.mp4"
# create the equivalent of the ffmpeg command:
# $ ffmpeg -i <rtsp_url> -vcodec copy -y -rtsp_transport tcp <output_mp4>
stream = ffmpeg.input(url)
stream = ffmpeg.output(stream, temp_file,
**{"codec:v": "copy",
"rtsp_transport": "tcp",
"y": None
}
)
ffmpeg.run(stream)
print(f"\n\nMP4 file created: {temp_file}")
number_of_files_to_collect -= 1
start = end + 1
end = start + seconds_per_clip
答案 0 :(得分:0)
我可以通过在-t
命令中添加持续时间参数(ffmpeg
)来解决此问题。因此,在此示例中,我没有指定RTSP URL中的开始和结束时间,而是仅包含开始时间,并通过ffmpeg
选项将持续时间用作-t
的参数。 10秒剪辑的命令行版本如下所示:
$ ffmpeg -rtsp_transport tcp -i rtsp://user:pass@71.185.124.195:554/c1/b1558830329/replay/ -t 00:00:10 -vcodec copy -y test_clip.mp4
我的Python脚本具有对ffmpeg
的等效调用,现在是这样:
import argparse
import datetime
import ffmpeg
# ------------------------------------------------------------------------------
if __name__ == "__main__":
# USAGE
# $ python collect_and_store.py --rtsp rtsp://user:pass1@71.85.125.110:554 \
# --duration 30 --count 10
# construct the argument parser and parse the arguments
args_parser = argparse.ArgumentParser()
args_parser.add_argument("--rtsp",
required=True,
type=str,
help="RTSP URL for video stream")
args_parser.add_argument("--duration",
required=True,
type=int,
help="duration of saved clips (in seconds)")
args_parser.add_argument("--count",
required=True,
type=int,
help="number of clips to save")
args = vars(args_parser.parse_args())
# sanity check for some of the arguments
if not args["rtsp"].lower().startswith("rtsp://"):
raise ValueError("Invalid input URL -- only RTSP supported")
seconds_per_clip = args["duration"]
start = int(datetime.datetime.now().strftime("%s"))
end = start + seconds_per_clip
number_of_files_to_collect = args["count"]
while number_of_files_to_collect > 0:
# build URL with start and end times
# NOTE URL is for Uniview RTSP, add options for other camera types
url = args["rtsp"] + f"/c1/b{start}/replay/"
# url = args["rtsp"] + f"/c1/b{start}/e{end}/replay/"
# file where we'll write clip data
temp_file = f"clip_b{start}_e{end}.mp4"
# create the equivalent of the ffmpeg command:
# $ ffmpeg -i <rtsp_url> -vcodec copy -y -rtsp_transport tcp <output_mp4>
stream = ffmpeg.input(url)
stream = ffmpeg.output(stream, temp_file,
**{"codec:v": "copy",
"rtsp_transport": "tcp",
"t": f"00:00:{str(seconds_per_clip).zfill(2)}",
"y": None
}
)
ffmpeg.run(stream)
print(f"\n\nMP4 file created: {temp_file}")
number_of_files_to_collect -= 1
start += seconds_per_clip
end += seconds_per_clip