Получить список I-кадров в видео в FFMPEG / Python
Я пытаюсь выбрать, скажем, 10 кадров из данного видео, возможно, с самым большим разнообразием и сценами. Я хотел бы поэкспериментировать с различными сценариями выбора, но хорошо то, что понятие I-frame
по сути означает изменение сцены! Поэтому я хотел бы получить I-кадры. Но, может быть, есть много I-кадров, так что, вероятно, мне придется их попробовать.
Как я могу получить список всех frame_number I-кадров в видео в FFMpeg или Python? Я хотел бы использовать список, чтобы выбрать только 10 из них и сохранить их в формате PNG/JPEG.
4 ответа
Получив понимание отсюда, я смог сделать это с ffprobe
:
def iframes():
if not os.path.exists(iframe_path):
os.mkdir(iframe_path)
command = 'ffprobe -v error -show_entries frame=pict_type -of default=noprint_wrappers=1'.split()
out = subprocess.check_output(command + [filename]).decode()
f_types = out.replace('pict_type=','').split()
frame_types = zip(range(len(f_types)), f_types)
i_frames = [x[0] for x in frame_types if x[1]=='I']
if i_frames:
cap = cv2.VideoCapture(filename)
for frame_no in i_frames:
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_no)
ret, frame = cap.read()
outname = iframe_path+'i_frame_'+str(frame_no)+'.jpg'
cv2.imwrite(outname, frame)
cap.release()
print("I-Frame selection Done!!")
if __name__ == '__main__':
iframes()
Это похоже на проблему X/Y, поэтому я предложу несколько разных команд:
Список отметок времени
Если вы хотите вывести список временных меток для каждого ключевого кадра:
ffprobe -v error -skip_frame nokey -show_entries frame=pkt_pts_time -select_streams v -of csv=p=0 input
0.000000
2.502000
3.795000
6.131000
10.344000
12.554000
Обратите внимание -skip_frame nokey
,
выберите фильтр
Другой метод заключается в использовании фильтра выбора с scene
опция для вывода ваших миниатюр:
ffmpeg -i input -vf "select=gt'(scene,0.4)',scale=160:-1" -vsync vfr %04d.png
Это выведет все i-кадры в виде изображений PNG.
ffmpeg -i 2.flv -vf "select=eq(pict_type\,I)" -vsync vfr frame-%02d.png
Отнесите к этому комментарию аналогичный вопрос usersuper.ru. Как извлечь все ключевые кадры из видеоклипа?
Надеюсь, это поможет. Приветствия.
Ян
Чтобы получить тип кадра для всех кадров видео, вы можете использовать следующую функцию Python. Смотрите оригинальное решение здесь .
def get_frames_metadata(file):
command = '"{ffexec}" -show_frames -print_format json "{filename}"'.format(ffexec='ffprobe', filename=file)
response_json = subprocess.check_output(command, shell=True, stderr=None)
frames = json.loads(response_json)["frames"]
frames_metadata, frames_type, frames_type_bool = [], [], []
for frame in frames:
if frame["media_type"] == "video":
video_frame = json.dumps(dict(frame), indent=4)
frames_metadata.append(video_frame)
frames_type.append(frame["pict_type"])
if frame["pict_type"] == "I":
frames_type_bool.append(True)
else:
frames_type_bool.append(False)
print(frames_type)
return frames_metadata, frames_type, frames_type_bool
Результат вывода:
['I', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'I', 'P']
Где I и P — это тип кадра.