時間戳列表

時間戳列表

我試圖從給定影片中選擇 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是幀類型。

相關內容