# FFMPEG 개요

FFMPEG은 다양한 멀티미디어 포맷을 처리하는 강력한 오픈 소스 소프트웨어로, 비디오, 오디오, 자막 등의 파일을 변환하고 편집할 수 있는 도구이다. FFMPEG은 전 세계적으로 널리 사용되며, 비디오 및 오디오 파일을 재생, 변환, 스트리밍하는 데 필요한 다양한 기능을 제공한다.

#### FFMPEG의 역사와 발전

FFMPEG 프로젝트는 2000년에 시작되었으며, **Fabrice Bellard**가 개발하였다. 초기에는 비디오와 오디오 파일을 변환하는 간단한 도구로 출발했으나, 시간이 지나면서 여러 기여자들의 참여로 다양한 기능들이 추가되었다. 현재 FFMPEG은 강력한 비디오 및 오디오 인코딩, 디코딩, 필터링 기능을 제공하며, 다양한 플랫폼에서 사용될 수 있다. FFMPEG의 핵심 라이브러리는 **libavcodec**, **libavformat**, **libavfilter** 등으로 구성되어 있다.

* **libavcodec**: 다양한 코덱을 처리하는 라이브러리로, 비디오 및 오디오 코덱을 지원한다.
* **libavformat**: 다양한 멀티미디어 컨테이너 포맷을 처리하는 라이브러리로, 파일 포맷 간의 변환을 가능하게 한다.
* **libavfilter**: 비디오 및 오디오 데이터를 처리하기 위한 다양한 필터를 제공하는 라이브러리이다.

#### FFMPEG의 주요 기능

FFMPEG은 다양한 기능을 제공하며, 그 중 일부는 다음과 같다.

**멀티미디어 변환**

FFMPEG은 다양한 포맷의 파일을 변환할 수 있다. 예를 들어, `.mp4` 파일을 `.avi`로 변환하거나, 비디오 파일에서 오디오만 추출하여 별도의 오디오 파일로 저장할 수 있다. 이러한 변환 작업은 단일 명령어로 쉽게 수행할 수 있다.

```bash
ffmpeg -i input.mp4 output.avi
```

**비디오 및 오디오 스트리밍**

FFMPEG은 실시간 스트리밍 기능을 지원한다. 이를 통해 네트워크 상에서 비디오와 오디오를 전송할 수 있으며, RTMP(Real-Time Messaging Protocol)와 같은 프로토콜을 사용하여 스트리밍 서버로 데이터를 전송할 수 있다. FFMPEG의 스트리밍 기능은 다양한 라이브 스트리밍 플랫폼에서 활용될 수 있다.

**비디오 및 오디오 인코딩**

FFMPEG은 다양한 코덱을 지원하여 비디오 및 오디오 데이터를 인코딩할 수 있다. 사용자는 필요한 코덱을 선택하여 비디오와 오디오 데이터를 압축할 수 있으며, 이 과정에서 비트레이트, 해상도, 프레임 레이트 등을 조정할 수 있다.

```bash
ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
```

위 명령어에서 `-c:v libx264`는 비디오 코덱으로 **H.264**를 사용한다는 의미이며, `-crf 23`은 Constant Rate Factor(CRF)를 23으로 설정하여 인코딩 품질을 조절한다.

#### 멀티미디어 파일 구조

멀티미디어 파일은 크게 **컨테이너**와 **코덱**으로 나눌 수 있다.

* **컨테이너**: 비디오, 오디오, 자막 등의 데이터를 하나의 파일에 담는 역할을 한다. 대표적인 컨테이너 포맷으로는 `.mp4`, `.mkv`, `.avi`, `.mov` 등이 있다.
* **코덱**: 비디오와 오디오 데이터를 인코딩하거나 디코딩하는 방법을 정의하는 알고리즘이다. 대표적인 비디오 코덱으로는 **H.264**, **VP9**, **AV1** 등이 있으며, 오디오 코덱으로는 **AAC**, **MP3**, **Opus** 등이 있다.

FFMPEG은 다양한 코덱과 컨테이너 포맷을 지원하므로, 사용자는 파일을 변환하거나 재생할 때 자유롭게 선택할 수 있다.

**FFMPEG의 아키텍처**

FFMPEG은 모듈식 아키텍처를 채택하고 있다. 이를 통해 각 기능이 독립적으로 작동하며, 사용자는 필요에 따라 각 모듈을 선택적으로 사용할 수 있다. 주요 모듈은 다음과 같다.

* **ffmpeg**: 멀티미디어 파일을 변환하거나 인코딩하는 데 사용되는 명령어 기반의 도구.
* **ffplay**: FFMPEG 라이브러리를 사용하여 멀티미디어 파일을 재생할 수 있는 간단한 플레이어.
* **ffprobe**: 멀티미디어 파일의 정보(비트레이트, 코덱, 해상도 등)를 확인하는 도구.

#### FFMPEG의 장점

FFMPEG은 다양한 멀티미디어 작업을 수행하는 데 있어 다음과 같은 장점을 가지고 있다.

**다양한 포맷 지원**

FFMPEG은 대부분의 비디오 및 오디오 포맷을 지원한다. FFMPEG이 지원하는 대표적인 비디오 포맷은 다음과 같다.

* **MP4** (`.mp4`)
* **Matroska** (`.mkv`)
* **AVI** (`.avi`)
* **MOV** (`.mov`)
* **FLV** (`.flv`)

오디오 포맷도 마찬가지로 폭넓게 지원하며, **MP3**, **AAC**, **WAV**, **FLAC** 등이 포함된다. 이러한 폭넓은 포맷 지원 덕분에 FFMPEG은 다양한 멀티미디어 작업 환경에서 사용될 수 있다.

**하드웨어 가속**

FFMPEG은 CPU뿐만 아니라 GPU를 활용한 하드웨어 가속을 지원한다. 이를 통해 대용량 비디오 파일을 인코딩하거나 디코딩할 때 처리 속도를 크게 향상시킬 수 있다. FFMPEG은 NVIDIA의 **NVENC**, **CUDA**, **AMD**의 **VCE**, **Intel**의 **Quick Sync Video** 등의 하드웨어 가속 기능을 지원하며, 이를 활용한 비디오 인코딩은 더욱 효율적이다.

```bash
ffmpeg -i input.mp4 -c:v h264_nvenc output.mp4
```

위 명령어는 **NVENC**를 사용하여 **H.264** 코덱으로 비디오를 인코딩한다. 하드웨어 가속을 이용하면 CPU 부하를 줄이면서 빠른 처리가 가능하다.

#### FFMPEG의 기본적인 동작 원리

FFMPEG은 기본적으로 **데이터 스트림**을 처리한다. 비디오, 오디오, 자막 파일은 모두 특정한 **스트림**으로 간주되며, 각 스트림은 독립적으로 인코딩되거나 디코딩될 수 있다.

**스트림의 구성**

* **비디오 스트림**: 비디오 데이터를 담고 있는 스트림으로, 프레임(frame) 단위로 데이터를 처리한다.
* **오디오 스트림**: 오디오 데이터를 담고 있는 스트림으로, 샘플(sample) 단위로 데이터를 처리한다.
* **자막 스트림**: 자막 정보를 담고 있는 스트림으로, 자막 파일의 경우 텍스트와 시간 정보를 포함한다.

FFMPEG은 이러한 스트림을 처리하여 입력 파일에서 데이터를 읽고, 변환한 후 출력 파일로 저장하는 과정을 수행한다.

```bash
ffmpeg -i input.mkv -c:v libx264 -c:a aac output.mp4
```

이 명령어는 **Matroska** 포맷(`.mkv`) 파일을 입력으로 받아 비디오 스트림을 **H.264** 코덱으로 인코딩하고, 오디오 스트림을 **AAC** 코덱으로 변환한 후 **MP4** 포맷으로 저장하는 과정을 보여준다.

#### FFMPEG의 확장성

FFMPEG은 **필터**를 이용하여 비디오 및 오디오 데이터를 쉽게 변환할 수 있다. 필터는 데이터에 다양한 효과를 적용할 수 있도록 하며, 사용자가 명령어를 통해 직접 설정할 수 있다. 대표적인 비디오 필터와 오디오 필터는 다음과 같다.

* **비디오 필터**: 밝기 조절, 대비 조절, 회전, 잘라내기, 확대/축소 등
* **오디오 필터**: 볼륨 조절, EQ(Equalizer) 적용, 노이즈 제거 등

```bash
ffmpeg -i input.mp4 -vf "scale=1280:720,eq=brightness=0.06" output.mp4
```

위 명령어는 **비디오 필터**를 사용하여 비디오 파일의 해상도를 **1280x720**으로 조정하고, 밝기를 약간 높이는 필터를 적용한 후 출력 파일로 저장하는 예제이다.

#### FFMPEG의 모듈 구성

FFMPEG은 여러 모듈로 구성되어 있으며, 각각의 모듈은 특정 기능을 수행한다. 이러한 모듈은 사용자가 필요에 따라 선택적으로 사용 가능하며, 이를 통해 다양한 작업을 수행할 수 있다.

**libavcodec**

**libavcodec**은 FFMPEG에서 가장 중요한 라이브러리 중 하나로, 다양한 비디오와 오디오 코덱을 처리하는 기능을 제공한다. 이 라이브러리는 인코딩 및 디코딩 과정에서 코덱을 사용하여 데이터를 변환한다.

* **비디오 코덱**: H.264, VP9, AV1, MPEG-2 등
* **오디오 코덱**: AAC, MP3, FLAC, Opus 등

libavcodec은 이러한 다양한 코덱을 지원하며, 사용자는 특정 코덱을 선택하여 데이터를 변환할 수 있다.

```bash
ffmpeg -i input.mp4 -c:v libx265 output.mkv
```

위 명령어는 **H.265** 코덱을 사용하여 비디오 데이터를 인코딩하는 예제이다. H.265 코덱은 **HEVC**(High-Efficiency Video Coding)으로도 알려져 있으며, H.264에 비해 더 높은 압축률을 제공한다.

**libavformat**

**libavformat**은 다양한 멀티미디어 컨테이너 포맷을 처리하는 라이브러리로, 파일 간의 포맷 변환을 가능하게 한다. 이 모듈은 입력 파일에서 데이터를 읽고, 출력 파일로 데이터를 쓰는 역할을 담당한다.

```bash
ffmpeg -i input.mp4 -f avi output.avi
```

위 명령어는 **MP4** 포맷의 파일을 **AVI** 포맷으로 변환하는 예제이다. 여기서 `-f avi`는 출력 포맷을 **AVI**로 지정하는 옵션이다.

**libavfilter**

**libavfilter**는 비디오 및 오디오 데이터를 필터링하는 라이브러리로, 다양한 필터를 통해 데이터를 처리할 수 있다. 예를 들어, 비디오 데이터를 잘라내거나 회전하는 등의 작업을 수행할 수 있으며, 오디오 데이터를 노멀라이즈하거나 볼륨을 조절하는 필터도 적용할 수 있다.

* **비디오 필터**: `crop`, `scale`, `rotate`, `fps`
* **오디오 필터**: `volume`, `aecho`, `highpass`, `lowpass`

```bash
ffmpeg -i input.mp4 -vf "crop=640:480:0:0" output.mp4
```

위 명령어는 비디오 파일에서 좌측 상단부터 **640x480** 크기의 영역만을 잘라내는 예제이다.

#### FFMPEG의 커맨드 라인 구조

FFMPEG은 커맨드 라인에서 실행되는 도구로, 다양한 옵션을 제공하여 파일을 변환하거나 편집할 수 있다. FFMPEG의 기본적인 명령어 구조는 다음과 같다.

```bash
ffmpeg [옵션] -i [입력 파일] [출력 파일]
```

여기서 `-i` 옵션은 입력 파일을 지정하며, 사용자는 다양한 옵션을 추가하여 출력 파일의 형식을 지정할 수 있다.

**주요 옵션 설명**

* **-i**: 입력 파일을 지정하는 옵션.
* **-c:v**: 비디오 코덱을 지정하는 옵션. 예: `libx264`, `libx265`.
* **-c:a**: 오디오 코덱을 지정하는 옵션. 예: `aac`, `mp3`.
* **-b:v**: 비디오 비트레이트를 설정하는 옵션. 예: `2M`(2Mbps).
* **-b:a**: 오디오 비트레이트를 설정하는 옵션. 예: `128k`(128kbps).
* **-r**: 비디오 프레임 레이트를 설정하는 옵션. 예: `30`, `60`.
* **-s**: 비디오 해상도를 설정하는 옵션. 예: `1280x720`, `1920x1080`.

```bash
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -c:a aac -b:a 128k -r 30 -s 1280x720 output.mp4
```

위 명령어는 입력 파일을 **H.264** 코덱으로 인코딩하고, 비트레이트는 2Mbps, 오디오는 **AAC** 코덱으로 인코딩하며, 해상도는 **1280x720**, 프레임 레이트는 **30fps**로 설정하는 예제이다.
