# 라이브 스트리밍 변환

#### 라이브 스트리밍 개요

라이브 스트리밍은 실시간으로 미디어 콘텐츠를 전송하는 방식으로, 방송, 회의, 이벤트 등을 실시간으로 시청자에게 제공하는 데 사용된다. FFmpeg는 다양한 프로토콜과 포맷을 지원하여 라이브 스트리밍 변환을 수행할 수 있으며, RTMP, HLS, DASH 등 다양한 스트리밍 프로토콜을 활용할 수 있다.

#### RTMP 기반 라이브 스트리밍 설정

RTMP(Real-Time Messaging Protocol)는 주로 실시간 미디어 스트리밍에 사용되는 프로토콜이다. FFmpeg를 이용해 RTMP 서버로 라이브 스트리밍을 송출하는 방법은 다음과 같다.

```bash
ffmpeg -re -i input.mp4 -c:v libx264 -preset fast -maxrate 3000k -bufsize 6000k -vf "scale=1280:720" -g 50 -c:a aac -b:a 128k -f flv rtmp://server/live/streamkey
```

이 명령어는 비디오 코덱으로 `libx264`를 사용하고, 오디오 코덱으로 `aac`를 사용하여 RTMP 서버로 스트리밍을 송출한다. 비디오 해상도는 1280x720으로 설정하고, 비트레이트 및 버퍼 크기 등의 설정도 포함되어 있다.

#### HLS 기반 라이브 스트리밍 설정

HLS(HTTP Live Streaming)는 Apple이 개발한 HTTP 기반 스트리밍 프로토콜이다. 이 프로토콜은 미디어를 작은 조각으로 나누어 전송하며, 다양한 네트워크 환경에서 안정적인 스트리밍을 제공할 수 있다.

HLS 스트리밍을 위해서는 FFmpeg를 사용하여 입력 파일을 여러 개의 작은 `.ts` 파일로 나누고, 이를 관리하는 `.m3u8` 플레이리스트 파일을 생성한다.

```bash
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f hls -hls_time 10 -hls_list_size 0 -hls_segment_filename "segment_%03d.ts" playlist.m3u8
```

위 명령어는 입력 파일을 HLS 형식으로 변환하여 출력한다. `-hls_time`은 각 세그먼트의 길이를 초 단위로 지정하며, `-hls_list_size 0`은 모든 세그먼트를 리스트에 포함시킨다.

#### DASH 기반 라이브 스트리밍 설정

DASH(Dynamic Adaptive Streaming over HTTP)는 MPEG에 의해 표준화된 스트리밍 프로토콜로, 네트워크 상태에 따라 적응적으로 비트레이트를 변경할 수 있는 특성이 있다. DASH 스트리밍을 설정하기 위해서는 FFmpeg로 미디어 파일을 MP4 세그먼트로 변환하고, 이를 DASH 매니페스트 파일로 관리한다.

```bash
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f dash -min_seg_duration 4000000 -use_timeline 1 -use_template 1 -init_seg_name "init-stream$RepresentationID$.mp4" -media_seg_name "chunk-stream$RepresentationID$-$Number$.m4s" manifest.mpd
```

이 명령어는 `manifest.mpd` 파일을 생성하고, 미디어를 DASH 스트리밍을 위해 MP4 세그먼트 파일로 분할한다.

#### 스트리밍 품질 설정

라이브 스트리밍에서 품질을 최적화하는 것은 매우 중요하다. 스트리밍 품질을 결정하는 주요 요소는 비트레이트, 해상도, 프레임 레이트이다.

**비트레이트와 품질의 관계**

비트레이트는 스트리밍의 품질과 네트워크 대역폭에 큰 영향을 미친다. FFmpeg에서는 비트레이트를 수동으로 설정하거나, 고정 비트레이트(CBR) 또는 가변 비트레이트(VBR)를 선택할 수 있다. 비트레이트 설정의 예는 다음과 같다.

```bash
-c:v libx264 -b:v 3000k
```

이 명령어는 비디오의 비트레이트를 3000 kbps로 고정한다. 고정 비트레이트는 일정한 품질을 제공하지만, 네트워크 상태에 적응하지 못할 수 있다. 반면, 가변 비트레이트는 네트워크 대역폭에 따라 품질을 조정한다.

**해상도와 품질의 관계**

해상도는 비디오 품질에 영향을 주는 또 다른 중요한 요소이다. 해상도를 조정하는 방법은 FFmpeg에서 `-vf scale` 필터를 사용하여 비디오 해상도를 변경할 수 있다.

```bash
-vf "scale=1280:720"
```

이 필터는 비디오의 해상도를 1280x720으로 설정한다.

#### 프레임 레이트와 품질의 관계

프레임 레이트는 초당 비디오의 프레임 수를 나타내며, 영상의 부드러움에 영향을 미친다. FFmpeg에서 프레임 레이트를 설정하는 방법은 다음과 같다.

```bash
-r 30
```

이 명령어는 비디오의 프레임 레이트를 30fps로 설정한다. 일반적으로 24fps는 영화와 같은 콘텐츠에 적합하며, 30fps는 표준 TV 방송에, 60fps는 고속 액션이나 게임 방송에 적합한다.

#### 네트워크 환경에 따른 비트레이트 적응

네트워크 상황에 따라 비트레이트를 실시간으로 조정하는 방법은 매우 유용하다. 이를 위해 가변 비트레이트(VBR) 방식을 사용하며, 이는 네트워크 상태에 맞게 비트레이트를 조정하여 스트리밍 품질을 유지할 수 있다. 가변 비트레이트 설정의 예시는 다음과 같다.

```bash
-c:v libx264 -b:v 3000k -maxrate 3500k -bufsize 6000k
```

이 명령어는 기본 비트레이트를 3000kbps로 설정하고, 최대 비트레이트를 3500kbps로 제한한다. `bufsize`는 비트레이트 조정 시 사용할 버퍼의 크기를 설정하며, 네트워크 환경에 따라 적절한 값을 선택해야 한다.

#### 오디오 품질 설정

라이브 스트리밍에서 오디오 품질도 중요한 요소이다. FFmpeg에서는 다양한 오디오 코덱을 지원하며, `aac`는 일반적으로 많이 사용된다. 오디오 비트레이트를 설정하는 방법은 다음과 같다.

```bash
-c:a aac -b:a 128k
```

이 명령어는 오디오 코덱으로 `aac`를 사용하며, 비트레이트를 128kbps로 설정한다. 오디오 비트레이트는 주로 네트워크 대역폭에 따라 조정하며, 보통 96kbps에서 192kbps 사이가 적당한다.

#### 다중 비트레이트 스트리밍

다양한 네트워크 환경에서 스트리밍 품질을 최적화하기 위해 다중 비트레이트 스트리밍을 설정할 수 있다. 이는 사용자가 자신의 네트워크 상태에 맞는 품질을 선택할 수 있게 해 준다.

**HLS에서 다중 비트레이트 스트리밍 설정**

FFmpeg를 사용해 HLS 스트리밍에서 여러 해상도와 비트레이트를 제공하는 방법은 다음과 같다.

```bash
ffmpeg -i input.mp4 \
    -map 0:v -s:v:0 1280x720 -b:v:0 3000k \
    -map 0:v -s:v:1 640x360 -b:v:1 1000k \
    -map 0:a -b:a 128k \
    -f hls -hls_time 10 -hls_list_size 0 \
    -var_stream_map "v:0,a:0 v:1,a:0" \
    -master_pl_name master.m3u8 \
    -hls_segment_filename "v%v/fileSequence%d.ts" v%v/prog_index.m3u8
```

위 명령어는 두 가지 해상도와 비트레이트로 HLS 스트리밍을 설정한다. `1280x720` 해상도에서는 3000kbps 비트레이트를, `640x360` 해상도에서는 1000kbps 비트레이트를 사용하며, 사용자는 두 가지 옵션 중 하나를 선택할 수 있다.

#### RTMP에서 다중 비트레이트 스트리밍 설정

RTMP 스트리밍에서도 다중 비트레이트를 설정할 수 있으며, 이 경우 여러 개의 스트림을 동시에 생성한다.

```bash
ffmpeg -re -i input.mp4 \
    -map 0:v -s:v:0 1280x720 -b:v:0 3000k \
    -map 0:v -s:v:1 640x360 -b:v:1 1000k \
    -map 0:a -b:a 128k \
    -f flv rtmp://server/live/streamkey_720p \
    -f flv rtmp://server/live/streamkey_360p
```

이 명령어는 1280x720 해상도와 640x360 해상도로 각각 다른 RTMP 스트림을 전송한다. 각 해상도에 맞는 비트레이트를 설정하여 네트워크 상태에 맞는 선택을 할 수 있다.

#### FFmpeg와 하드웨어 가속을 이용한 스트리밍

하드웨어 가속은 스트리밍 성능을 높이는 데 유용하며, GPU를 사용하여 비디오 인코딩 및 디코딩 속도를 크게 향상시킬 수 있다. FFmpeg에서 하드웨어 가속을 사용하려면 `h264_nvenc` 또는 `hevc_nvenc`와 같은 GPU 인코더를 사용할 수 있다.

```bash
ffmpeg -hwaccel nvdec -i input.mp4 -c:v h264_nvenc -b:v 3000k -c:a aac -b:a 128k -f flv rtmp://server/live/streamkey
```

이 명령어는 `nvdec` 하드웨어 가속 디코더를 사용하고, `h264_nvenc` 인코더를 사용하여 RTMP 서버로 스트리밍을 송출한다. GPU를 사용하여 CPU 부하를 줄이고, 인코딩 성능을 최적화할 수 있다.
