# 파일 분할

FFMPEG에서 파일을 분할하는 방법은 매우 다양하며, 다양한 기준에 따라 파일을 나눌 수 있다. 이 장에서는 파일 분할의 여러 가지 방법을 다루며, 명령어와 함께 그 원리를 설명한다.

#### 시간 기반 파일 분할

비디오 또는 오디오 파일을 특정 시간대별로 분할할 수 있다. 이를 위해 `-ss`와 `-t` 옵션을 사용하여 원하는 시작 시간과 지속 시간을 설정한다.

```bash
ffmpeg -i input.mp4 -ss 00:00:00 -t 00:05:00 -c copy output1.mp4
```

이 명령어는 `input.mp4` 파일을 처음부터 5분 동안의 비디오만 `output1.mp4`로 복사하는 것이다. 중요한 점은 `-c copy`를 사용하여 인코딩 없이 파일을 복사하는 것이므로, 속도가 빠르고 품질 손실이 없다.

**시간 분할의 수학적 표현**

비디오 파일을 시간적으로 분할할 때, 이를 수학적으로 표현할 수 있다. 비디오의 전체 길이를 $T$라고 할 때, $t\_1$와 $t\_2$가 시작 시간과 끝 시간이라면, 분할된 비디오의 길이는 다음과 같이 표현된다.

$$
\Delta t = t\_2 - t\_1
$$

여기서 $\Delta t$는 분할된 비디오의 길이를 의미한다.

#### 프레임 기반 파일 분할

시간 대신 특정 프레임 단위로도 파일을 분할할 수 있다. FFMPEG에서는 `-vf` 필터 옵션을 통해 프레임을 제어한다. 예를 들어, 초당 프레임 수(Frames per second, FPS)를 기준으로 분할할 수 있다.

```bash
ffmpeg -i input.mp4 -vf "select='gte(n\,300)'" -c copy output2.mp4
```

이 명령어는 300번째 프레임 이후의 비디오를 `output2.mp4`로 복사하는 것이다. `n`은 현재 프레임 번호를 나타낸다.

**프레임 기반 분할의 수학적 모델**

영상 파일은 보통 초당 프레임 수로 구성된다. 프레임 기반으로 파일을 분할할 때는, 특정 프레임 번호 $n$에서부터 분할할 수 있다. 총 프레임 수를 $N$로 두고, $t$는 시간, $f$는 프레임 속도(FPS)를 나타낸다면, 특정 프레임에서 분할된 비디오의 시작 시간은 다음과 같다.

$$
t = \frac{n}{f}
$$

이때 $n$은 시작하는 프레임 번호이고, $f$는 초당 프레임 수(FPS)이다.

#### 크기 기반 파일 분할

파일 크기를 기준으로 분할할 수 있다. 이 경우, FFMPEG은 자체적으로 파일 크기를 제한하는 옵션을 제공하지 않지만, 이를 위한 다양한 스크립트나 방법을 사용할 수 있다. 예를 들어, 파일 크기를 기준으로 일정 크기마다 파일을 분할하려면, `split` 명령어를 사용하는 방법이 있다.

다음은 Linux에서 파일을 크기 기반으로 분할하는 예시이다.

```bash
split -b 100M input.mp4 output_prefix
```

이 명령어는 `input.mp4` 파일을 100MB씩 분할하여, 파일 이름이 `output_prefixaa`, `output_prefixab` 등으로 나뉜다. 이후 각 분할된 파일은 다시 FFMPEG으로 처리하거나 병합할 수 있다.

**파일 크기 분할의 수학적 표현**

파일 크기를 기반으로 분할할 때, 파일의 총 크기를 $S$, 분할하려는 파일의 크기를 $s$라고 하자. 그렇다면, 총 몇 개의 분할 파일이 나올지를 계산하는 식은 다음과 같다.

$$
n = \left\lceil \frac{S}{s} \right\rceil
$$

여기서 $n$은 분할된 파일의 개수를 의미하며, $\lceil \cdot \rceil$는 올림 연산을 뜻한다. 이를 통해 전체 파일 크기에 따라 몇 개의 파일로 분할할지를 예측할 수 있다.

#### 키 프레임 기반 파일 분할

비디오 파일을 분할할 때, 특정 키 프레임(Key Frame)을 기준으로 분할할 수 있다. 키 프레임은 비디오 압축 방식에서 중요한 역할을 하며, 이를 기준으로 분할하면 자연스러운 비디오 전환이 가능하다.

```bash
ffmpeg -i input.mp4 -c copy -f segment -segment_frames 1000 -reset_timestamps 1 output%03d.mp4
```

이 명령어는 `input.mp4` 파일을 1000개의 프레임 단위로 분할하여 각 분할 파일의 이름을 `output001.mp4`, `output002.mp4` 등으로 생성한다.

**키 프레임 분할의 수학적 모델**

키 프레임을 기준으로 파일을 분할하는 경우, 특정 구간에서 첫 번째 키 프레임을 찾는 것이 중요하다. 이때, $n$번째 키 프레임에서 비디오를 분할한다면, 다음과 같은 수식으로 나타낼 수 있다.

$$
\mathbf{k}\_n = { \text{frame} \mid \text{key\_frame}(n) = 1 }
$$

여기서 $\mathbf{k}\_n$은 $n$번째 키 프레임을 의미하며, `key_frame` 함수는 특정 프레임이 키 프레임인지 여부를 반환하는 함수이다. 이를 통해 특정 키 프레임에서 자연스러운 비디오 분할이 가능해진다.

#### 장면 기반 파일 분할

장면 전환을 감지하여 비디오 파일을 분할할 수도 있다. 이 방법은 주로 장면 변화가 극명한 비디오에서 유용하며, FFMPEG의 `-vf` 필터에서 `select` 옵션을 활용하여 장면 변화를 감지할 수 있다.

```bash
ffmpeg -i input.mp4 -vf "select='gt(scene\,0.4)'" -vsync vfr output%d.mp4
```

이 명령어는 장면 변화가 40% 이상 감지된 지점에서 비디오를 분할하여 `output1.mp4`, `output2.mp4` 등의 파일을 생성한다. 여기서 `scene` 값은 장면 전환의 민감도를 조절하며, 값이 높을수록 더 큰 변화에서만 장면이 분할된다.

**장면 기반 분할의 수학적 모델**

장면 전환을 감지하여 비디오를 분할할 때, 영상의 프레임별 픽셀 값 변화 정도를 분석하여 장면 변화를 감지한다. 특정 장면에서의 프레임 변화를 $\Delta P$라고 할 때, $\Delta P$가 설정된 임계값 $\theta$보다 클 경우, 그 지점에서 비디오가 분할된다.

$$
\Delta P = \sum\_{i,j} \left| I(i,j,t) - I(i,j,t-1) \right|
$$

여기서 $I(i,j,t)$는 시간 $t$에서 픽셀 $(i,j)$의 밝기값을 의미하며, $\Delta P$는 두 프레임 간의 차이를 나타낸다. 이 값이 임계값 $\theta$를 넘으면, 장면 변화가 발생했다고 판단한다.

#### 파일 분할 자동화

FFMPEG은 다양한 방식으로 파일 분할을 자동화할 수 있다. 예를 들어, 비디오를 일정 시간 간격으로 분할하려는 경우, `-f segment` 옵션을 사용할 수 있다.

```bash
ffmpeg -i input.mp4 -c copy -f segment -segment_time 60 output%03d.mp4
```

이 명령어는 `input.mp4`를 60초마다 분할하여 파일을 생성한다. 각 파일은 `output001.mp4`, `output002.mp4` 등의 형식으로 저장된다. `-segment_time` 옵션은 분할 시간 간격을 지정하며, 이 옵션을 사용하면 비디오가 자동으로 여러 파일로 나뉜다.

**자동 분할의 수학적 표현**

시간 간격을 기준으로 자동 분할하는 경우, 총 시간 $T$를 일정 간격 $\Delta t$로 나누어 분할할 수 있다. 분할된 파일의 개수는 다음과 같다.

$$
n = \left\lceil \frac{T}{\Delta t} \right\rceil
$$

여기서 $n$은 생성된 분할 파일의 개수를 나타내며, $\Delta t$는 분할 간격(초)을 의미한다.

#### 파일 분할 후 재병합

분할된 파일을 다시 하나로 병합하는 것도 가능하다. 이를 위해 `concat` 명령어를 사용하여 여러 파일을 하나로 병합할 수 있다.

먼저, 병합할 파일 목록을 텍스트 파일에 작성한다.

```bash
file 'output1.mp4'
file 'output2.mp4'
file 'output3.mp4'
```

그 후, 다음 명령어를 통해 이 파일들을 하나로 병합한다.

```bash
ffmpeg -f concat -safe 0 -i filelist.txt -c copy merged_output.mp4
```

**병합의 수학적 모델**

파일 병합은 각각의 분할 파일을 시간 축에서 다시 연결하는 과정이다. 만약 각각의 분할 파일의 길이가 $T\_1, T\_2, \dots, T\_n$이라면, 병합된 파일의 총 길이는 다음과 같이 계산된다.

$$
T\_{\text{merged}} = \sum\_{i=1}^{n} T\_i
$$

이때 $T\_{\text{merged}}$는 병합된 파일의 총 시간을 나타낸다.
