FFmpeg를 사용하는 비디오의 의미있는 썸네일


80

FFmpeg는 비디오를 나타내는 썸네일로 사용할 수있는 비디오에서 이미지를 캡처 할 수 있습니다. 이를 수행하는 가장 일반적인 방법은 FFmpeg Wiki에 있습니다.

그러나 일정 간격으로 임의의 프레임을 선택하고 싶지 않습니다. 장면 변경 사항을 캡처하기 위해 FFmpeg에서 필터를 사용하는 몇 가지 옵션을 찾았습니다.

필터 thumbnail는 비디오에서 가장 대표적인 프레임을 찾으려고합니다.

ffmpeg -i input.mp4 -vf  "thumbnail,scale=640:360" -frames:v 1 thumb.png

다음 명령은 이전과 비교하여 40 % 이상의 변경 사항이있는 프레임 만 선택하고 장면 변경 일 수 있습니다. 5 개의 PNG 시퀀스를 생성합니다.

ffmpeg -i input.mp4 -vf  "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png

Fabio Sonnati 에게 상기 명령에 대한 정보 제공 . 두 번째 이미지는 n 개의 이미지를 가져 와서 가장 잘 선택할 수 있으므로 더 좋아 보였습니다. 나는 그것을 시도하고 동일한 이미지를 5 번 생성했습니다.

더 많은 조사로 나를 이끌었습니다.

ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr  out%02d.png

-vsync vfr다른 이미지를 얻을 수 있습니다. 여전히 비디오의 첫 번째 프레임을 선택합니다. 대부분의 경우 첫 번째 프레임은 크레딧 / 로고이며 의미가 없으므로 -ss3을 추가 하여 비디오의 처음 3 초를 버립니다.

마지막 명령은 다음과 같습니다.

ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg

이것이 내가 할 수있는 최선이었다. 5 개의 비디오 만 선택했기 때문에 모든 비디오가 대부분 비디오의 시작 부분이며 비디오에서 나중에 발생하는 중요한 장면을 놓칠 수 있습니다.

다른 더 나은 옵션을 위해 당신의 두뇌를 선택하고 싶습니다.


좋은 명령 예제. FWIW, 나는 OS X (10.8, FFmpeg 1.1 이하)에서 FFmpeg로 생성 된 JPEG 사진에 아무런 문제가 없었습니다. 두 번째에서 마지막 명령은 나에게도 잘 맞으며 마지막에도 잘 작동하며 빈 JPG 파일에는 이러한 결과가 없습니다. 나는 libopenjpeg..로 컴파일 했는지 차이가 ​​있는지 확실하지 않습니다.
slhck

고마워요 slhck. ffmpeg 구성 / 버전 세부 사항으로 질문을 편집했습니다. 이 컴퓨터에서 1.1로 업그레이드하지 않았습니다. 그렇게하고 결과가 변경되는지 확인합니다.
d33pika

1
우분투에 있습니까? 정적 빌드 또는 직접 컴파일하여 다시 실행 하여 최신 Git Master 버전을 사용해 볼 수 있습니까 ? 또는 최신 안정. 난 그냥이 사용 검사 mjpeg뿐만 아니라 나를 위해 인코더를하고, 또한 확인 jpegoptim하고 exiv2귀하의 예제 명령에서 모든 JPG 결과와 나를 위해 잘 작동 둘.
slhck

1
업데이트했는데 이제 작동합니다! 이전 버전에 버그가있는 것 같습니다.
d33pika

계속해서 새로운 버전으로 솔루션을 게시 할 수 있습니까? 변경 로그에 대한 링크를 통해 발생하는 버그를 표시하고 이후에 새 버전으로 수정 한 것이 있습니까?
Lizz

답변:


29

시간 범위가 비디오의 첫 번째, 두 번째, 세 번째, 네 번째 및 다섯 번째 20 % 인 각 5 개의 시간 범위 내에서 첫 번째> 40 % 변경 프레임을 찾는 것이 가장 좋습니다.

크레딧을 피하기 위해 6 개의 시간 범위로 나누고 첫 번째 시간을 무시할 수도 있습니다.

실제로 이것은 장면 변경 확인과 비디오의 첫 번째 비트를 버리는 인수를 적용하면서 fps를 낮은 숫자로 설정하는 것을 의미합니다.

... 같은 것 :

ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.4)" -frames:v 5 -vsync vfr -vf fps=fps=1/600 out%02d.jpg

1
완전히 검은 색 또는 흰색 이미지가 촬영되는 경우 어떻게 피합니까?
d33pika

1
블랙 프레임과 그 시퀀스를 감지하는 필터가 있습니다 ( ffmpeg.org/ffmpeg-filters.html#blackframe 또는 ffmpeg.org/ffmpeg-filters.html#blackdetect ). 하나의 라이너로 작업 할 수는 없지만 검은 색 프레임을 제거하고 (별도의 단계) 결과 비디오에서 축소판을 추출 할 수 있어야합니다.
AM

5
흰색 프레임의 경우 이제는 점점 복잡해지고 있지만 여전히 방법이 있습니다. 1. 검은 색 프레임 제거 2. 부정 (흰색이 검은 색으로 바 3.) 3. 흰색 프레임 제거 4. 다시 부정함 5. 썸네일 추출 (특히 한 줄에 검은 색 또는 흰색 프레임을 제거 할 수 있다면 여기에 다시 게시 할 수 있습니까? 나는 미래 독자들을위한 답변에 추가 할 수 있습니다. ... 또는 실제로 새로운 질문과 답변을 만들 수 있습니다 그것을 확실히 찬성합니다.)
AM

3
일반 흑백과 같은 지루한 이미지를 피하려면 : 필요한 것보다 많은 섬네일을 생성하고 jpeg로 압축 한 다음 파일 크기가 더 큰 이미지를 선택하십시오. 괜찮은 섬네일을 얻기 위해 놀랍게도 잘 작동합니다.
Sam Watkins

2
이 명령이 작동하지 않아 오류가 발생했습니다 Unable to find a suitable output format for 'fps=fps=1/600'. 해결책은 -vf인수 앞에 추가 하는 것입니다 ( stackoverflow.com/questions/28519403/ffmpeg-command-issue 참조 )
John Wiseman

7

의미있는 정의 는 어렵지만 전체 비디오 파일에 걸쳐 N 썸네일을 효율적으로 만들려면 사용자가 업로드 한 컨텐츠로 프로덕션에서 썸네일을 생성하는 데 사용합니다.

의사 코드

for X in 1..N
  T = integer( (X - 0.5) * D / N )  
  run `ffmpeg -ss <T> -i <movie>
              -vf select="eq(pict_type\,I)" -vframes 1 image<X>.jpg`

어디:

  • D- ffmpeg -i <movie>혼자 읽 거나 ffprobeJSON 출력 라이터 btw가있는 비디오 지속 시간
  • N-원하는 총 섬네일 수
  • X-1부터 N까지의 썸네일 번호
  • T-썸네일의 시점

위의 내용은 영화의 각 파티션의 가운데 키 프레임을 기록합니다. 예를 들어 영화 길이가 300 초이고 썸네일 3 개를 원한다면 50, 150, 250 초 후에 하나의 키 프레임이 필요합니다. 5 개의 썸네일의 경우 30, 90, 150, 210, 270입니다. 동영상 길이 D에 따라 N을 조정할 수 있습니다. 예를 들어 5 분 동영상에는 3 개의 썸네일이 있지만 1 시간 이상에는 20 개의 썸네일이 있습니다.

공연

ffmpeg명령을 호출 할 때마다 ~ 1GB H.264에 대해 초 (!)의 시간이 걸립니다. 그 즉시로 점프하기 때문이다 <time>(마음을 배치 -ss하기 전에 -i)과 실질적으로 완전한 JPEG입니다 첫 번째 키 프레임을합니다. 영화를 정확한 시간 위치에 맞추기 위해 낭비되는 시간은 없습니다.

후 처리

위의 scale방법이나 다른 크기 조정 방법을 혼합 할 수 있습니다 . 단색 프레임을 제거하거나와 같은 다른 필터와 혼합 해 볼 수도 있습니다 thumbnail.


2
와우 이전 -ss N으로 이동 하는 -i것은 놀라운 팁입니다. 감사합니다!
apinstein

2

한 번 비슷한 작업을했지만 비디오의 모든 프레임 (1fps)을 내보내고 이미지 간의 차이를 계산하는 펄 유틸리티와 비교했습니다. 각 프레임을 이전 축소판과 비교하고 모든 축소판과 다른 경우 축소판 컬렉션에 추가했습니다. 여기서 장점은 비디오가 장면 A에서 B로 이동하고 A로 돌아 오면 ffmpeg가 A의 두 프레임을 내보내는 것입니다.


두 이미지를 비교하기 위해 어떤 요소를 사용 했습니까?
d33pika

불행히도 나는 기억이 안납니다. 그것은 꽤 오래 전에였습니다. 사용할 비교 방법을 먼저 결정한 다음 올바른 요인을 찾기 위해 몇 가지 테스트를 수행해야합니다. 오래 걸리지 않아야합니다.
Eran Ben-Natan

나는 여기서 크게 생각하고 있지만 이것이 더 나쁜 옵션은 아닌가? 비디오에서 내 보낸 이미지 2 개를 비교할 때 이미 일부 정보가 손실되었습니다. 내 말은, 2 장의 사진보다 코덱 정보에서 유사성을 계산하는 것이 더 쉽습니까? 최근 이미지를 비교하기 위해 일부 알고리즘 / 라이브러리를 살펴 보았지만 이미지가 제대로 작동하지 않을 수도 있습니다.
사무엘

ffmpeg를 사용하면 same_quality 플래그를 사용하여 품질 손실없이 프레임을 추출 할 수 있습니다. 코덱 정보를 사용하는 경우 Iframe 만 가져 오지 않았는지 확인해야합니다. 어쨌든 perl 유틸리티는 나에게 잘 작동했으며 매우 구성 가능합니다. 여기 봐 : search.cpan.org/~avif/Image-Compare-0.3/Compare.pm
, 둘다 벤 나탄

2

이 시도

 ffmpeg -i input.mp4 -vf fps= no_of_thumbs_req/total_video_time out%d.png

이 명령을 사용하여 전체 비디오를 나타내는 필요한 수의 축소판을 생성 할 수 있습니다.


에 대한 정확한 공식은하지 않을 fps(no_of_frames_req * fps_of_vid) / total_video_frames?
flolilo

반대의 해결책을 찾고 있습니다. 카메라가 더 안정적이고 움직이지 않는 기간에서 더 많은 프레임을 선택 하시겠습니까? (연속 프레임 간의 차이가 적을수록 높지 않음). 그렇게 할 방법이 있습니까?
Tina J

1

다음은 포스터로 사용할 라이브 m3u8 스트림에 대한 주기적 썸네일을 생성하는 방법입니다. 축소판을 생성하기 위해 연속 ffmpeg 작업을 실행하면 모든 CPU가 소모되므로 60 초마다 cronjob을 실행하여 스트림의 모든 축소판을 생성합니다.

#!/usr/bin/env bash

## this is slow but gives better thumbnails (takes about 1+ minutes for 20 files)
#-vf thumbnail,scale=640:360 -frames:v 1 poster.png

## this is faster but thumbnails are random (takes about 8 seconds for 20 files)
#-vf scale=640:360 -frames:v 1 poster.png
cd ~/path/to/streams

find . -type f \
  -name "*.m3u8" \
  -execdir sh -c 'ffmpeg -y -i "$0" -vf scale=640:360 -frames:v 1 "poster.png"' \
  {} \;

60 초 이상 (크론 작업 제한)보다 자주 수행해야하는 경우 while스크립트에서 루프를 수행하면 영원히 실행될 수 있습니다. sleep 30주파수를 30 초로 변경하려면 a 를 추가하십시오 . 그러나 다음 실행이 시작되기 전에 이전 실행이 완료되지 않을 수 있기 때문에 많은 수의 비디오로이 작업을 수행하지 않는 것이 좋습니다.

이상적으로 cronjob을 사용하면 5 분마다 실행합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.