How To Output X265 Compressed Video With Cv2.videowriter
Solution 1:
As far as I know, OpenCV VideoWriter
has no support for HEVC encoding (yet).
I recommend you using FFmpeg as sub-process, and PIPE the rendered frames to stdin
input stream of ffmpeg
.
You may use Python binding for ffmpeg
like ffmpeg-python, or execute ffmpeg
using Python subprocess.
Using ffmpeg
, you have much more control over video encoding parameters compared to cv2.VideoWriter
(cv2.VideoWriter
is designed for simplicity on expanse of flexibility).
Here is a sample code that renders 50 frames, stream frames to ffmpeg
that encodes MP4 video file with HEVC video codec:
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 inrange(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()
Notes:
ffmpeg
executable must be in the execution path of the Python script.For Linux, in case
ffmpeg
is not in the execution path, you may use the full path: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)
(Assuming
ffmpeg
executable is in/usr/bin/
).Python 3's f-Strings syntax requires Python version 3.6 or above.
Post a Comment for "How To Output X265 Compressed Video With Cv2.videowriter"