如何使用cv2.VideoWriter输出x265压缩视频

时间:2020-04-16 21:16:57

标签: python-3.x opencv rendering codec

我正在对45分钟的1.2GB视频进行一些渲染,每个视频80,0000帧,大小为1344x756,视频为mp4格式,我正在尝试输出x265压缩的视频,问题是当我我正在使用cv2.VideoWriter,视频的10分钟输出大小超过2GB,这不是我想要的最终结果,因此我在mac osx和ubuntu 18上尝试了以下操作:

Team.matches

我得到的只是运行时警告:

Team.matchs

我想要实现的不一定是最高质量的输出,而应该是高质量和最小的尺寸。

1 个答案:

答案 0 :(得分:2)

据我所知,OpenCV VideoWriter还不支持HEVC编码。

我建议您使用FFmpeg作为子流程,并将渲染的帧PIPE到stdin的{​​{1}}输入流中。

您可以像ffmpeg-python那样为ffmpeg使用Python绑定,也可以使用Python subprocess执行ffmpeg

ffmpeg相比,使用ffmpeg对视频编码参数的控制要多得多(cv2.VideoWriter是为简化灵活性而设计的。)

这是一个示例代码,可渲染50帧,流向cv2.VideoWriter的帧,并使用HEVC视频编解码器对MP4视频文件进行编码:

ffmpeg

注意:

  • import cv2 import numpy as np import subprocess as sp import shlex width, height, n_frames, fps = 1344, 756, 50, 25 # 50 frames, resolution 1344x756, and 25 fps output_filename = 'output.mp4' # Open ffmpeg application as sub-process # FFmpeg input PIPE: RAW images in BGR color format # FFmpeg output MP4 file encoded with HEVC codec. # Arguments list: # -y Overwrite output file without asking # -s {width}x{height} Input resolution width x height (1344x756) # -pixel_format bgr24 Input frame color format is BGR with 8 bits per color component # -f rawvideo Input format: raw video # -r {fps} Frame rate: fps (25fps) # -i pipe: ffmpeg input is a PIPE # -vcodec libx265 Video codec: H.265 (HEVC) # -pix_fmt yuv420p Output video color space YUV420 (saving space compared to YUV444) # -crf 24 Constant quality encoding (lower value for higher quality and larger output file). # {output_filename} Output file name: output_filename (output.mp4) process = sp.Popen(shlex.split(f'ffmpeg -y -s {width}x{height} -pixel_format bgr24 -f rawvideo -r {fps} -i pipe: -vcodec libx265 -pix_fmt yuv420p -crf 24 {output_filename}'), stdin=sp.PIPE) # Build synthetic video frames and write them to ffmpeg input stream. for i in range(n_frames): # Build synthetic image for testing ("render" a video frame). img = np.full((height, width, 3), 60, np.uint8) cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (255, 30, 30), 20) # Blue number # Write raw video frame to input stream of ffmpeg sub-process. process.stdin.write(img.tobytes()) # Close and flush stdin process.stdin.close() # Wait for sub-process to finish process.wait() # Terminate the sub-process process.terminate() 可执行文件必须位于Python脚本的执行路径中。

  • 对于Linux,如果ffmpeg不在执行路径中,则可以使用完整路径:

    ffmpeg

    (假设 process = sp.Popen(shlex.split(f'/usr/bin/ffmpeg -y -s {width}x{height} -pixel_format bgr24 -f rawvideo -r {fps} -i pipe: -vcodec libx265 -pix_fmt yuv420p -crf 24 {output_filename}'), stdin=sp.PIPE) 可执行文件位于ffmpeg中)。

  • Python 3's f-Strings语法需要Python 3.6或更高版本。