When creating a video from a list of frames at an assigned framerate using PyAV, the videos end up being shorter that expected by a few seconds, while the framerate in the video metadata is correct. Here is a sample code of the function to save the videos:
def save_video(video_name,imlist,framerate,bitrate):
container = av.open(video_name, mode='w')
stream = container.add_stream('h264', framerate)
stream.codec_context.bit_rate = bitrate*1e3 # Bitrate in kbps
stream.width = image_width
stream.height = image_height
stream.pix_fmt = 'yuv420p'
for image in imlist:
image = av.VideoFrame.from_ndarray(image)
packet = stream.encode(image)
container.mux(packet)
container.close()
For example, when making a video from 600 frames at 30fps, the result is an 18s video instead of 20s. Loading the video again, it looks like some frames were dropped.
I would like to stick with PyAV as I can easily set the bitrate. I have tried using OpenCV, which works but produces very large video files.
What am I missing?
We have to flush the remaining packets from encoder before closing the container.
Flushing the encoder is done by encoding
Noneand muxing the output packets.Add the following code before
container.close():Code sample for testing: