Transcoding a video
The following codes show an example of encoding and muxing a new video file. Although we are transcoding a video, the input of the encoder could be any data.
import mpegCoder
d = mpegCoder.MpegDecoder()
d.setParameter(nthread=4)
opened = d.FFmpegSetup('test-video.mp4') # Setup the decoder
e = mpegCoder.MpegEncoder()
e.setParameter(decoder=d, codecName='libx265', videoPath='test-video-x265.mp4', nthread=8) # inherit most of parameters from the decoder.
opened = opened and e.FFmpegSetup() # Setup the encoder.
if opened: # If either the decoder or the encoder is not loaded successfully, do not continue.
p = True
while p is not None:
p = d.ExtractGOP() # Extract current GOP.
if p is not None:
for i in p: # Iterate every frame.
e.EncodeFrame(i) # Encode current frame.
e.FFmpegClose() # End encoding, and flush all frames in cache.
e.clear() # Clean configs of the encoder.
d.clear() # Close configs of the decoder.
In this example, we decode an existing video file, and encode a new video by x265
codec. The most widely used video codecs are libxvid
, libx264
, libx265
, libvp9
, libsvtav1
. Most of the encoder configurations are copied from the opened decoder. So the output video would share the same GOP size, consecutive B frame number, picture size, bit rate and frame rate of the input video. We also reconfigure the thread number of the encoder by 8
.
info
Some codec may not work with multi-threading. In this case, after we call FFmpegSetup()
, the configuration of the threading number would be corrected as 1
automatically.
In each while loop, we read a GOP, iterate the GOP, and encode the data frame-by-frame. After all frames are encoded, the mp4
file tail would be dumped into the output video.
If user trigger Ctrl+C during the while loop, the video could be still completed safely. However, if users hit Ctrl+C by twice, the output video would be broken, because the video tail has not been written correctly.
Optimize the output video
In the above example, the output video may not be encoded by an optimized configuration. The x265 codec could accept a maximal consecutive B frame number of <=16
. We could also configure the output bit rate manually. Therefore, if we change the configuraitons like the following example, the output video file size would be reduced significantly.
...
e = mpegCoder.MpegEncoder()
e.setParameter(decoder=d, codecName='libx265', videoPath='test-video-x265.mp4', GOPSize=24, maxBframe=16, bitRate=48.0, nthread=8)
opened = opened and e.FFmpegSetup()
...
Rescaling and resampling
In some cases, we may want to rescale the output video size, and resample the output frames,
...
e = mpegCoder.MpegEncoder()
e.setParameter(decoder=d, codecName='libx265', videoPath='test-video-x265.mp4', width=720, height=486, frameRate=(5, 1), nthread=8)
opened = opened and e.FFmpegSetup()
...
This example would rescale the output frame to 720x486, and resample the output frame rate as 5 FPS. In this case, when we call e.EncodeFrame(i)
, the frame i
may be not in the size of 720x486, but MpegEncoder
could scale it automatically.