我在 S3 存储桶中存储了一组视频,我希望使用 Python 和 Lambda 自动将这些视频转换为 GIF 的过程。每个生成的 GIF 长度应恰好为 10 秒,并且应包含从相应视频的不同部分采样的随机帧。我所说的随机帧是指每个视频的开头、中间和结尾的帧,创建动态 GIF 体验。
我已经开始在 Python Lambda 函数中使用 ffmpeg 实现此功能,但在实现预期结果方面遇到了困难。
有人可以提供如何有效完成这项任务的指导吗?如果您能深入了解 Lambda 函数和 ffmpeg 命令的 Python 代码,我们将不胜感激。
注释在代码中。
import imageio.v3 as iio # pip install imageio | pip install imageio[ffmpeg] | pip install imageio[pyav]
import numpy as np
#######################################################
# The example below only was tested using MP4 videos #
#######################################################
# make sure it will be the best for your scenario.,.. maybe you will need to improve it!
def get_total_frames(file:str) -> int:
props = iio.improps(file, plugin="pyav")
# Make sure the codec knows the number of frames
assert props.shape[0] != -1
return props.shape[0]
def extract_Nseconds_into_frames(file:str, n_seconds:int) -> np.ndarray:
# default is to have 30 frames per second to have a good feel... but change as you wish
totalframes = get_total_frames(file)
print(f"Total frames: {totalframes}")
fps = iio.immeta(file, plugin="pyav")["fps"]
print(f"Video FPS: {fps}")
step = int((totalframes/fps) / n_seconds)
print(f"Step to achieve number of seconds: {step}")
if step > totalframes:
raise Exception("Your video file dont have frames enough to be extract in desire FPS")
frames_to_be_extracted = []
for idx in range(0, totalframes, step):
frames_to_be_extracted.append(idx)
print(f"Selected frames (total): {len(frames_to_be_extracted)}")
img_list = []
for idx in frames_to_be_extracted:
img_list.append(iio.imread("imageio:cockatoo.mp4", index=idx))
print(f"Stacking frames")
frames = np.stack(img_list, axis=0)
return frames
def frames_to_gif(gif_path:str, frames:np.ndarray):
print(f"Converting frames into GIF")
iio.imwrite(gif_path, frames)
frames = extract_Nseconds_into_frames("imageio:cockatoo.mp4", 3)
frames_to_gif("cockatoo.gif", frames)