如何用Python编写可变帧率视频



我在Python应用程序中有一些帧,它们具有从视频开始的相对时间戳。有没有一种方法可以使用这些时间戳来编写具有可变帧率的视频?

我已经尝试过opencv-python和scikit视频,但它似乎无法编写正确的时间戳,以防视频中FPS发生变化。

OpenCV不是媒体库。它没有给你这种灵活性。

查看PyAV

自定义PTS:的扩展示例

#!/usr/bin/env python3
# extended from https://github.com/PyAV-Org/PyAV/blob/main/examples/numpy/generate_video.py
# added: custom PTS
import numpy as np
import av
from fractions import Fraction
total_frames = 20
container = av.open('test.mp4', mode='w')
stream = container.add_stream('mpeg4', rate=25) # alibi frame rate
stream.width = 480
stream.height = 320
stream.pix_fmt = 'yuv420p'
# we'll show frames for 0.5 or 1.0 seconds
# my_pts will say when the next frame is due
# time_base is somewhat arbitrary. this is milliseconds. nice round numbers. I could use 1/2 for my desired PTSes.
stream.codec_context.time_base = Fraction(1, 1000)
my_pts = 0
# ffmpeg time is "complicated". read more at https://github.com/PyAV-Org/PyAV/blob/main/docs/api/time.rst
for frame_i in range(total_frames):
img = np.empty((480, 320, 3))
img[:, :, 0] = 0.5 + 0.5 * np.sin(2 * np.pi * (0 / 3 + frame_i / total_frames))
img[:, :, 1] = 0.5 + 0.5 * np.sin(2 * np.pi * (1 / 3 + frame_i / total_frames))
img[:, :, 2] = 0.5 + 0.5 * np.sin(2 * np.pi * (2 / 3 + frame_i / total_frames))
img = np.round(255 * img).astype(np.uint8)
img = np.clip(img, 0, 255)
frame = av.VideoFrame.from_ndarray(img, format='rgb24')
frame.pts = int(round(my_pts / stream.codec_context.time_base)) # seconds -> counts of time_base
# calculate time of *next* frame, i.e. how long *this* frame will show
# show three in quick succession, three slowly, repeat
my_pts += 0.5 if ((frame_i // 3) % 2 == 0) else 1.0
for packet in stream.encode(frame):
container.mux(packet)
# Flush stream
for packet in stream.encode():
container.mux(packet)
# Close the file
container.close()

最新更新