FFmpeg를 사용하여 비디오 속도를 높이는 것과 관련하여 이미 다음과 같은 질문이 있습니다.이 하나.
내 질문은: 외부 CSV를 통해 속도를 높일 여러 섹션을 지정하는 방법도 있습니까?
내 CSV는 다음과 같습니다
start, end
00:00:03.296, 00:00:14.372,
00:00:16.388, 00:00:33.635,
00:00:33.693, 00:00:39.428,
00:00:39.460, 00:00:50.355,
00:00:50.355, 00:01:17.892,
00:01:17.892, 00:01:19.845,
00:01:19.845, 00:01:47.616,
이는 10배 속도가 빨라지는 정확한 섹션(라인당 하나의 섹션, 각 섹션의 시작과 끝을 정의하는 두 개의 타임스탬프)입니다. 나머지는 원래 재생 속도를 유지합니다.
이를 수행할 수 있는 방법이 있습니까?
답변1
다음을 사용하여 각 비디오 프레임의 원하는 PTS 타임스탬프를 설정할 수 있습니다.설정정교한 중첩 if
표현으로 필터링합니다.
다음 대답은 프로그래밍 방식으로 필요한 더 복잡한 표현을 만드는 지식이 있다고 가정할 때 "개념 증명"일 뿐입니다. 솔루션에서는 입력 비디오의 프레임 속도가 고정되어 있고 입력 프레임 번호에서 입력 타임스탬프를 계산하는 것이 간단하다고 가정합니다.
참고:
타임스탬프를 설정하여 비디오의 일부를 가속하면 VFR(가변 프레임 속도) 비디오가 생성되는데, 이는 모든 비디오 플레이어에서 제대로 재생되지 않을 수 있습니다.
모든 비디오의 속도를 10배로 높여 고정 프레임 속도 비디오를 생성하고 각 프레임을 원래 속도 부분에서 10번 복제하는 것이 더 나을 수 있습니다.
OpenCV로 프레임을 읽고 OpenCV(또는 FFmpeg로 더 나은 파이프)를 사용하여 쓰는 Python 스크립트를 사용하면 프레임을 복제하는 것이 상대적으로 간단합니다.
다음과 같은 입력 파일(1fps에서 40프레임)이 있다고 가정합니다.
ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=40 -c:v libx264 -g 1 input.mp4
입력 비디오의 타임스탬프는 다음과 같습니다.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
[0, 19] 및 [30, 39] 범위에서 속도를 높이고 다음과 같은 출력 타임스탬프를 얻는다고 가정합니다.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 21.1, 21.2, 21.3, 21.4, 21.5, 21.6, 21.7, 21.8, 21.9,
다음 FFmpeg 명령을 사용할 수 있습니다.
ffmpeg -y -r 100 -i input.mp4 -fps_mode:v passthrough -vf "setpts='(if(lt(N,10), N, if(lt(N,20), ((N-10)/10)+10, if(lt(N,30), 11+(N-20), 21+(N-30)/10))))/TB'" -c:v libx264 -g 1 output.mp4
-r 100
패킷 기간을 10msec로 설정하는 데 사용됩니다(패킷 기간이 짧을수록 타임스탬프의 해상도가 높아집니다).-fps_mode:v passthrough
- 각 입력 프레임을 입력에서 출력으로 전달합니다(100fps 속도로 인해 프레임을 복제하지 않음).-vf "setpts='(if(lt(N,10), N, if(lt(N,20), ((N-10)/10)+10, if(lt(N,30), 11+(N-20), 21+(N-30)/10))))/TB'"
-if
타임스탬프를 조정하기 위해 표현식과 일부 수학을 사용합니다. if(조건, true인 경우 값, false인 경우 값) 표현식이 적용됩니다
. 입력 프레임 번호입니다. 0부터 계산을 시작합니다. 처음 10개 프레임에 대해 PTS를 설정합니다 . 초 단위의 시간을 시간 기준으로 나눕니다.if
N
if(lt(N,10), N, ...
N
/TB
-g 1
- 테스트를 위해 GOP 크기를 1로 설정합니다(제거). FFprobe를 사용할 때 PTS 정렬을 유지합니다.
FFprobe를 사용하여 출력 타임스탬프 확인:
ffprobe -select_streams v:0 -of default=noprint_wrappers=1 -show_entries packet=pts_time output.mp4
출력은 예상대로입니다.
pts_time=0.000000
pts_time=1.000000
pts_time=2.000000
pts_time=3.000000
pts_time=4.000000
pts_time=5.000000
pts_time=6.000000
pts_time=7.000000
pts_time=8.000000
pts_time=9.000000
pts_time=10.000000
pts_time=10.100000
pts_time=10.190000
pts_time=10.300000
pts_time=10.400000
pts_time=10.500000
pts_time=10.600000
pts_time=10.700000
pts_time=10.800000
pts_time=10.900000
pts_time=11.000000
pts_time=12.000000
pts_time=13.000000
pts_time=14.000000
pts_time=15.000000
pts_time=16.000000
pts_time=17.000000
pts_time=18.000000
pts_time=19.000000
pts_time=20.000000
pts_time=21.000000
pts_time=21.100000
pts_time=21.200000
pts_time=21.300000
pts_time=21.400000
pts_time=21.500000
pts_time=21.600000
pts_time=21.700000
pts_time=21.800000
pts_time=21.900000
출력을 보여주는 애니메이션 GIF:
(을 사용하여 생성됨 ffmpeg -y -i output.mp4 -filter_complex "[0:v]split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -r 1 output.gif
)