
特定のビデオから、できるだけ多様性とシーンが最も豊富な 10 フレームを選択しようとしています。さまざまな選択シナリオを試してみたいのですが、良いことに、 という概念はI-frame
本質的にシーンの変更を意味します。そのため、I フレームを取得したいと思います。ただし、I フレームが多数ある可能性があるため、おそらくそれらをサンプリングする必要があります。
FFMpeg または Python でビデオ内のすべての I フレームの frame_number のリストを取得するにはどうすればよいですか? リストを使用して 10 個だけを選択し、PNG/JPEG として保存したいと思います。
答え1
これは 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
答え2
これにより、すべての i フレームが PNG 画像として出力されます。
ffmpeg -i 2.flv -vf "select=eq(pict_type\,I)" -vsync vfr frame-%02d.png
このコメントは、superuser.com の同様の質問に対するものです。 ビデオクリップからすべてのキーフレームを抽出するにはどうすればいいですか?
お役に立てれば幸いです。乾杯。
イアン
答え3
洞察を得るここ、私は以下でそれを行うことができました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()
答え4
ビデオ内のすべてのフレームのフレームタイプを取得するには、次の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 はフレーム タイプです。