我可以在 OpenCV 中使用 ffmpeg 的 "stream copy" 和 VideoWriter class 吗?
Can I use the "stream copy" of ffmpeg in OpenCV with VideoWriter class?
Python: 3.6, Ubuntu 18.04, OpenCV 4.1.0
我有一台 IP 摄像机,可以流式传输 H.264 编码的视频数据。我想获取此视频流并使用 Python 将其保存在 .avi 文件中,无需任何编码或解码。使用命令行界面和 ffmpeg 命令,这很容易做到。
mycomputer@home:~$ ffmpeg -i rtsp://username:password@192.168.1.1/?framerate=30.0?streamprofile=defaultcameraprofile -acodec copy -vcodec copy output_file_name.avi
我想使用 OpenCV 在 Python 中做类似的事情。目前,我正在使用 VideoCapture class 读取每一帧,然后使用 OpenCV VideoWriter class 将这一帧写入文件。我的问题是 VideoWriter class 需要一个 four_cc 代码来指定在写入过程中要使用哪个编解码器,而我根本不想使用任何编解码器(或者更准确地说,我想使用 FFmpeg 的流副本,但据我所知没有相应的 four_cc 代码)。 OpenCV 文档指定如果我使用 FFmpeg 后端 API 并将编解码器和帧速率指定为 0,则应将原始流写入新文件。但是,当我这样做时,没有创建文件。
cap = cv2.VideoCapture("rtsp://username:password@192.168.1.1/?framerate=30.0?streamprofile=defaultcameraprofile", cv2.CAP_FFMPEG)
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
# output file, backend API, four_cc code integer, framerate, frame size tuple
out = cv2.videoWriter("output_file.avi",cv2.CAP_FFMPEG,0,0,(frame_width,frame_height))
我尝试了 videoWriter 构造函数的其他输入参数的许多组合,但所有这些组合要么重新编码流,要么不写入输出文件。例如,我几乎尝试了帧率 {0,30}、输出文件扩展名 {.avi、.mp4、.h264、.mkv、None} 和编解码器 {0、"H.264" 的所有组合, "RAW "、"DBI "、“ ”、"MPEG"、"COPY"、"NONE"}。
out = cv2.videoWriter("output_file.avi",cv2.CAP_FFMPEG,cv2.VideoWriter_fourcc('H','2','6','4'),30,(frame_width,frame_height))
是否可以使用OpenCV中的FFmpeg流复制来保存视频数据而不进行编码?如果没有,我会从 Python 中将 tact 更改为 运行 shell 命令,但如果可行的话,我更喜欢前一种方法。
经过大量额外的搜索后,我认为可能没有使用 OpenCV 中的 VideoWriter class 来执行此操作的好方法。相反,我使用了一个使用子进程模块调用的 ffmpeg 命令行命令。
command = ['ffmpeg', '-i', 'rtsp://username:password@192.168.1.1/axis-media/media.amp?framerate=30.0', '-acodec', 'copy', '-vcodec', 'copy', '-r', '30.0', 'output_file.avi']
p = subprocess.Popen(command,stdin=subprocess.PIPE)
input("Press Enter to stop capture...")
os.kill(p.pid, 15)
Python: 3.6, Ubuntu 18.04, OpenCV 4.1.0
我有一台 IP 摄像机,可以流式传输 H.264 编码的视频数据。我想获取此视频流并使用 Python 将其保存在 .avi 文件中,无需任何编码或解码。使用命令行界面和 ffmpeg 命令,这很容易做到。
mycomputer@home:~$ ffmpeg -i rtsp://username:password@192.168.1.1/?framerate=30.0?streamprofile=defaultcameraprofile -acodec copy -vcodec copy output_file_name.avi
我想使用 OpenCV 在 Python 中做类似的事情。目前,我正在使用 VideoCapture class 读取每一帧,然后使用 OpenCV VideoWriter class 将这一帧写入文件。我的问题是 VideoWriter class 需要一个 four_cc 代码来指定在写入过程中要使用哪个编解码器,而我根本不想使用任何编解码器(或者更准确地说,我想使用 FFmpeg 的流副本,但据我所知没有相应的 four_cc 代码)。 OpenCV 文档指定如果我使用 FFmpeg 后端 API 并将编解码器和帧速率指定为 0,则应将原始流写入新文件。但是,当我这样做时,没有创建文件。
cap = cv2.VideoCapture("rtsp://username:password@192.168.1.1/?framerate=30.0?streamprofile=defaultcameraprofile", cv2.CAP_FFMPEG)
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
# output file, backend API, four_cc code integer, framerate, frame size tuple
out = cv2.videoWriter("output_file.avi",cv2.CAP_FFMPEG,0,0,(frame_width,frame_height))
我尝试了 videoWriter 构造函数的其他输入参数的许多组合,但所有这些组合要么重新编码流,要么不写入输出文件。例如,我几乎尝试了帧率 {0,30}、输出文件扩展名 {.avi、.mp4、.h264、.mkv、None} 和编解码器 {0、"H.264" 的所有组合, "RAW "、"DBI "、“ ”、"MPEG"、"COPY"、"NONE"}。
out = cv2.videoWriter("output_file.avi",cv2.CAP_FFMPEG,cv2.VideoWriter_fourcc('H','2','6','4'),30,(frame_width,frame_height))
是否可以使用OpenCV中的FFmpeg流复制来保存视频数据而不进行编码?如果没有,我会从 Python 中将 tact 更改为 运行 shell 命令,但如果可行的话,我更喜欢前一种方法。
经过大量额外的搜索后,我认为可能没有使用 OpenCV 中的 VideoWriter class 来执行此操作的好方法。相反,我使用了一个使用子进程模块调用的 ffmpeg 命令行命令。
command = ['ffmpeg', '-i', 'rtsp://username:password@192.168.1.1/axis-media/media.amp?framerate=30.0', '-acodec', 'copy', '-vcodec', 'copy', '-r', '30.0', 'output_file.avi']
p = subprocess.Popen(command,stdin=subprocess.PIPE)
input("Press Enter to stop capture...")
os.kill(p.pid, 15)