我正在尝试用 Python 提取特定时间范围内的所有帧。例如,我想将视频的帧从
start_time = 3.25
拍摄到end_time = 5.5
。假设视频的 fps 是 60。我该怎么做?
我正在考虑做的事情的代码非常松散:
video = load_video(my_video_path)
fps = 60
start_frame = 3.25 * fps
end_frame = 5.5 * fps
sliced_video = video[start_frame:end_frame]
不确定执行以下操作的正确库和方法是什么?
您可以使用 PyAV 来实现此目的。安装
pip install av
(或 pip3,无论您的操作系统需要调用 pip)
然后使用此代码:
import numpy as np
import av
my_video_path = ...
start_time = 3.25
end_time = 5.5
container = av.open(my_video_path)
duration = container.duration * (1 / av.time_base)
print(f"Video duration: {duration:.2f} seconds")
assert start_time < end_time, "End time must be after start time"
assert end_time < container.duration / av.time_base, "End time beyond file duration"
stream = container.streams.video[0]
# seek
print(f"seeking to {start_time:.2f} seconds or earlier")
container.seek(
int(start_time / stream.time_base),
stream=stream)
# decode
frames = []
for frame in container.decode(stream):
assert frame.time == float(frame.pts * stream.time_base)
if frame.time > end_time:
print(f"Frame at {frame.time:.2f} seconds -- after end time, stopping")
break
elif frame.time < start_time:
print(f"Frame at {frame.time:.2f} seconds -- before start time, skipping")
continue
else:
print(f"Frame at {frame.time:.2f} seconds")
frame_bgr24 = frame.to_ndarray(format='bgr24')
frames.append(frame_bgr24)
print("Collected", len(frames), "frames")
Video duration: 28.17 seconds
seeking to 3.25 seconds or earlier
Frame at 0.00 seconds -- before start time, skipping
Frame at 0.03 seconds -- before start time, skipping
Frame at 0.07 seconds -- before start time, skipping
...
Frame at 3.17 seconds -- before start time, skipping
Frame at 3.20 seconds -- before start time, skipping
Frame at 3.23 seconds -- before start time, skipping
Frame at 3.27 seconds
Frame at 3.30 seconds
Frame at 3.33 seconds
Frame at 5.43 seconds
...
Frame at 5.47 seconds
Frame at 5.50 seconds
Frame at 5.53 seconds -- after end time, stopping
Collected 68 frames