특정 시간대 비디오 추출
FFmpeg을 사용하여 비디오 파일에서 특정 시간대의 영상을 추출하는 것은 매우 유용한 기능이다. 이 작업은 주로 긴 영상에서 중요한 부분만 따로 저장하거나, 원하는 구간만 분리하여 편집할 때 사용된다.
기본 명령어
특정 시간대의 비디오를 추출하기 위해서는 -ss와 -to 옵션을 사용한다.
-ss: 추출할 시작 시간을 설정한다.-to: 추출할 끝 시간을 설정한다.
이 명령어들은 초 단위로 시간 입력을 받으며, HH:MM:SS 또는 초 단위로 직접 입력할 수 있다.
예를 들어, 30초에서 1분 30초 사이의 구간을 추출하려면 다음과 같은 명령어를 사용한다.
ffmpeg -i input.mp4 -ss 00:00:30 -to 00:01:30 -c copy output.mp4위 명령어는 원본 input.mp4 파일에서 30초부터 1분 30초까지의 영상을 복사하여 output.mp4 파일로 저장하는 방법이다.
옵션 설명
-i: 입력 파일을 지정한다. 여기서는
input.mp4가 입력 파일로 사용된다.-ss: 시작 시간을 의미하며, 여기서
00:00:30은 30초부터 시작한다는 의미이다.-to: 끝 시간을 의미하며, 여기서
00:01:30은 1분 30초까지 추출한다는 의미이다.-c copy: 인코딩을 하지 않고, 원본 스트림을 그대로 복사한다. 이를 통해 빠르게 추출할 수 있다.
시간 설정 방법
시간은 HH:MM:SS 형태 또는 초 단위로 지정할 수 있다. 예를 들어 30초를 지정하려면 00:00:30 또는 30으로 입력할 수 있다.
시작 시간과 끝 시간을 동시에 지정하지 않고, 시작 시간만 지정할 수도 있다. 이 경우 비디오 파일의 끝까지를 추출하게 된다.
예시:
이 명령어는 input.mp4의 1분(60초)부터 파일의 끝까지를 output.mp4로 추출하는 명령어이다.
더 정확한 추출
FFmpeg에서 시간 기반 추출을 보다 정확하게 하기 위해서는 -accurate_seek 옵션을 사용할 수 있다.
FFmpeg의 기본 동작은 키프레임에 맞춰 시크(seek)하는 것이기 때문에, 추출한 영상의 시작이 지정한 시간보다 약간 뒤로 밀릴 수 있다.
이 문제를 해결하기 위해서는 재인코딩을 거치거나, -accurate_seek 옵션을 사용하여 정확하게 시간대를 지정할 수 있다.
여기서 -c:v libx264와 -c:a aac는 각각 비디오와 오디오 코덱을 지정하여 재인코딩을 수행한다.
수학적 개념 적용
비디오 시퀀스를 시간 범위로 추출하는 과정은 시간 축 상의 구간 추출로 생각할 수 있다. 이를 수식으로 나타내면, 다음과 같은 형태로 설명할 수 있다.
주어진 비디오 파일을 $f(t)$라고 할 때, $t$는 시간 변수이다. FFmpeg을 사용하여 $t_1$에서 $t_2$ 사이의 비디오 구간을 추출한다고 하면, 우리는 함수 $f(t)$의 구간 $[t_1, t_2]$를 추출하는 것이다. 이를 수식으로 나타내면:
이때 $\mathbf{f}_{extract}(t)$는 $[t_1, t_2]$ 범위에서만 원본 비디오 $f(t)$의 데이터를 포함하고, 그 외 구간에서는 0이 되는 함수이다.
예제: 특정 구간 오디오와 비디오 함께 추출
비디오와 오디오를 함께 추출할 수 있다. 예를 들어 5분 20초에서 8분 10초까지의 구간을 추출하고 싶다면 다음 명령어를 사용할 수 있다.
위 명령어는 input.mp4에서 5분 20초부터 8분 10초까지의 비디오와 오디오를 추출하여 output.mp4로 저장하는 명령어이다. 이 경우에는 재인코딩이 발생한다.
오디오만 추출하기
FFmpeg를 사용하면 특정 시간대의 오디오만 추출할 수도 있다. 비디오를 제외하고 오디오만 추출하려면 -vn 옵션을 사용하면 된다. -vn은 비디오를 포함하지 않는다는 뜻이다. 예를 들어 10초에서 1분 10초까지의 오디오만 추출하는 명령어는 다음과 같다.
위 명령어는 input.mp4에서 10초부터 1분 10초까지의 오디오를 output_audio.mp3로 추출하며, 비디오를 포함하지 않는다.
옵션 설명
-vn: 비디오를 포함하지 않겠다는 의미이다. 오디오만 추출할 때 사용한다.
-c:a copy: 오디오 스트림을 인코딩하지 않고 그대로 복사한다.
비디오만 추출하기
마찬가지로, 오디오 없이 비디오만 추출할 수도 있다. 오디오를 포함하지 않고 비디오만 추출하려면 -an 옵션을 사용한다. -an은 오디오를 포함하지 않겠다는 의미이다. 예를 들어, 특정 구간의 비디오만 추출하고 싶다면 다음과 같은 명령어를 사용할 수 있다.
위 명령어는 input.mp4에서 2분부터 4분까지의 비디오를 추출하며, 오디오는 포함하지 않는다.
옵션 설명
-an: 오디오를 포함하지 않겠다는 의미이다.
-c:v copy: 비디오 스트림을 인코딩하지 않고 그대로 복사한다.
다중 구간 추출
여러 구간을 추출하여 하나의 파일로 병합하고 싶을 때는 FFmpeg 단일 명령어로는 어렵지만, 별도의 스크립트를 작성하거나 추출된 구간을 병합하는 방식으로 해결할 수 있다. 각 구간을 개별적으로 추출한 후, FFmpeg의 파일 병합 기능을 사용하여 구간들을 하나의 파일로 결합할 수 있다. 이를 위해서는 먼저 각 구간을 추출한 뒤, 이를 텍스트 파일로 정리해야 한다.
예시: 각 구간 추출 및 병합
다음과 같은 명령어로 여러 구간을 각각 추출할 수 있다.
이후 두 개의 파일을 병합하려면, 다음 명령어를 사용할 수 있다.
여기서 file_list.txt는 병합할 파일들의 목록을 포함하고 있어야 한다. 텍스트 파일의 내용은 다음과 같다.
이 명령어는 두 개의 추출된 비디오 구간을 병합하여 output_merged.mp4로 저장한다.
시간 설정의 정확성
특정 시간대를 추출할 때, 정확한 프레임 단위로 추출할 수 있도록 설정하는 방법도 고려할 수 있다. 이를 위해서는 FFmpeg의 -r 옵션을 사용하여 프레임 레이트를 명시적으로 설정할 수 있다. 프레임 레이트는 시간대 추출 시 정확한 프레임을 지정하는 데 중요한 요소가 될 수 있다.
프레임 레이트와 키프레임
특정 시간대에서 비디오를 정확하게 추출할 때 주의해야 할 중요한 사항 중 하나는 프레임 레이트와 키프레임이다. FFmpeg은 기본적으로 키프레임 단위로 시크(seek) 작업을 수행하므로, 원하는 시점이 정확히 키프레임이 아닐 경우 추출된 영상의 시작 지점이 약간 밀릴 수 있다.
프레임 레이트 조정
만약 프레임 레이트가 불균형하거나 정확한 시간대에 맞게 추출되지 않는다면, 프레임 레이트를 명시적으로 지정할 수 있다. 이는 -r 옵션을 사용하여 설정할 수 있으며, 이는 출력 파일의 프레임 레이트를 설정하는 데 도움이 된다.
여기서 -r 30은 출력 비디오의 프레임 레이트를 30fps로 설정한다.
키프레임 문제 해결
FFmpeg는 기본적으로 키프레임에 맞춰 비디오를 시크하므로, 지정한 시간에서 약간 다른 시작 지점이 될 수 있다. 이 문제를 해결하기 위해서는 재인코딩을 하거나, -ss를 입력 파일 앞에 두는 방식으로 시크(seek) 작업을 더 정확하게 할 수 있다.
이 방식에서는 입력 파일을 처리하기 전에 시크를 먼저 수행하므로, 키프레임 문제를 해결할 수 있다. 다만, 이 방법은 인코딩 시간이 늘어날 수 있다.
수학적 접근: 프레임 계산
비디오에서 특정 시간대를 추출할 때, 해당 시간대에 해당하는 프레임을 수학적으로 계산할 수 있다. 이를 위해서는 비디오의 프레임 레이트를 알고 있어야 하며, 시간에 따른 프레임 수는 다음과 같은 수식으로 계산할 수 있다.
비디오의 프레임 레이트를 $r$ (fps)라고 하고, 추출할 구간의 시작 시간을 $t_1$, 끝 시간을 $t_2$라고 하면, 해당 구간의 시작 프레임 $\mathbf{F_1}$과 끝 프레임 $\mathbf{F_2}$는 다음과 같이 계산할 수 있다.
따라서, 구간 $[t_1, t_2]$에 해당하는 프레임 수는 $\mathbf{F_2 - F_1}$이다.
예를 들어, 프레임 레이트가 30fps인 비디오에서 1분 10초($t_1 = 70s$)에서 2분 20초($t_2 = 140s$)까지의 구간을 추출하려면, 시작 프레임과 끝 프레임은 다음과 같이 계산된다.
따라서, 추출해야 하는 프레임 수는 $4200 - 2100 = 2100$ 프레임이다.
이 계산을 바탕으로 특정 시간대의 프레임을 정확하게 추출할 수 있으며, FFmpeg의 프레임 처리 옵션을 조정하여 보다 세밀한 제어가 가능한다.
비디오 포맷 변환 후 추출
특정 시간대의 비디오를 추출한 후 포맷을 변경해야 할 경우, FFmpeg을 사용하여 동시에 추출과 변환 작업을 수행할 수 있다. 예를 들어, MP4 형식의 비디오에서 특정 구간을 추출하고 이를 AVI 형식으로 변환하려면 다음 명령어를 사용할 수 있다.
이 명령어는 input.mp4 파일에서 30초부터 1분 30초까지의 구간을 추출하고, 이를 output.avi 파일로 변환하여 저장한다.
오디오 및 비디오 동기화 문제
특정 시간대에서 오디오와 비디오를 추출할 때, 가끔 동기화 문제가 발생할 수 있다. 이는 주로 프레임 드롭이나 인코딩 과정에서 발생하는 문제로, 이러한 문제를 해결하기 위해서는 -async 옵션을 사용하여 오디오와 비디오의 동기화를 강제할 수 있다.
여기서 -async 1 옵션은 오디오와 비디오를 동기화하며, 특히 인코딩 시 발생하는 동기화 문제를 해결할 수 있다.
Last updated