타임스탬프 목록

타임스탬프 목록

저는 주어진 비디오에서 아마도 가장 다양성과 장면이 있는 10개의 프레임을 선택하려고 합니다. 다양한 선택 시나리오를 실험해보고 싶은데 좋은 점은 이라는 개념이 I-frame본질적으로 장면 전환을 의미한다는 것입니다! 그래서 I-프레임을 얻고 싶습니다. 하지만 아마도 I-프레임이 많아서 샘플링을 해야 할 것 같습니다.

FFMpeg 또는 Python의 비디오에 있는 모든 I-프레임의 프레임_번호 목록을 어떻게 얻을 수 있습니까? 목록을 이용하여 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는 프레임 유형입니다.

관련 정보