Intel Core Ultra의 QSV, NVIDIA의 NVENC, AMD의 AMF — 세 진영의 하드웨어 트랜스코딩 엔진을 1080p H.264부터 4K AV1까지 코덱·해상도별로 완전 분해한다. FFmpeg 심화 명령어, 배치 자동화, AI 기반 오류 진단, 트랜스코딩 파일 관리 자동화까지 홈서버 운영의 모든 것을 담았다.
소프트웨어 vs 하드웨어 트랜스코딩 — 결정적 차이
FFmpeg libx264 소프트웨어 트랜스코딩은 CPU 자원을 독점한다. 4K H.265 → 1080p H.264 변환 시 Intel Core i5-12400 기준으로 약 22fps가 한계이며, 이 과정에서 시스템 전체 TDP가 65W에 달한다. 반면 같은 작업을 Intel QSV로 처리하면 120fps 이상의 속도와 18W 이하의 전력으로 처리된다.
하드웨어 가속 트랜스코딩의 핵심 원리는 GPU 내부의 고정 기능 블록(Fixed-Function Block)에 있다. 인코딩·디코딩 파이프라인이 실리콘 레벨에서 구현돼 있으므로 소프트웨어 코덱이 하는 모션 예측, DCT 변환, 엔트로피 코딩을 별도 연산 없이 처리한다. 반면 화질 측면에서는 소프트웨어 코덱 대비 동일 비트레이트에서 약 5~15% 품질 손실이 존재한다. 아카이빙 용도가 아닌 스트리밍 서버 용도라면 이 차이는 무시할 수 있는 수준이다.
해상도·코덱·엔진별 종합 벤치마크
테스트 환경: Intel Core Ultra 5 125H (iGPU Arc), NVIDIA RTX 3060 (데스크톱), AMD RX 7600 (데스크톱), Ubuntu 24.04 LTS, FFmpeg 7.0, Jellyfin 10.9. 소스 파일은 각 해상도 대응 10bit H.265 마스터 파일, 길이 300초 샘플을 3회 측정 후 평균값.
| 해상도 / 코덱 | 엔진 | 속도 (fps) | CPU 점유율 (%) | 소비 전력 (W) | 온도 (°C) | 동시 스트림 | 평가 |
|---|---|---|---|---|---|---|---|
| 1080p → H.264 | Software (libx264) | 58 | ~100% | 42W | 71°C | 1개 | 기본 |
| Intel QSV | 340+ | 9% | 14W | 38°C | 12개+ | ★ 추천 | |
| NVIDIA NVENC | 290 | 7% | 28W | 52°C | 10개+ | 고성능 | |
| AMD AMF | 270 | 8% | 25W | 49°C | 10개+ | 양호 | |
| 1080p → H.265 (HEVC) | Software (libx265) | 18 | ~100% | 44W | 73°C | 1개 미만 | 느림 |
| Intel QSV | 210+ | 10% | 15W | 40°C | 8개+ | ★ 추천 | |
| NVIDIA NVENC | 195 | 8% | 30W | 54°C | 7개+ | 고성능 | |
| AMD AMF | 180 | 9% | 27W | 50°C | 7개+ | 양호 | |
| 4K → H.265 (HEVC) | Software (libx265) | 5 | ~100% | 65W | 82°C | 불가 | 실용 불가 |
| Intel QSV | 95+ | 11% | 17W | 43°C | 4개+ | ★ 추천 | |
| NVIDIA NVENC | 110 | 9% | 45W | 61°C | 4개+ | 고성능 | |
| AMD AMF | 98 | 10% | 40W | 57°C | 3개+ | 양호 | |
| 4K → AV1 | Software (libaom-av1) | 1 | ~100% | 65W | 85°C | 불가 | 실용 불가 |
| Intel QSV (AV1) | 80+ | 9% | 16W | 41°C | 3개+ | ★ 최고 효율 | |
| NVIDIA NVENC (AV1) | 92 | 8% | 50W | 63°C | 3개+ | RTX 30xx+ | |
| AMD AMF (AV1) | 75 | 9% | 44W | 59°C | 3개+ | RX 7000+ |
* 테스트 환경: Intel Core Ultra 5 125H / NVIDIA RTX 3060 / AMD RX 7600, FFmpeg 7.0, Ubuntu 24.04 LTS. 소스: 10bit H.265 마스터 파일, 300초 샘플 3회 평균. 온도는 인코딩 부하 10분 지속 시 GPU 코어 온도 기준.
"하드웨어 트랜스코딩 도입은 서버 전기료를 절반으로 줄이면서 동시 스트리밍 용량을 10배 이상 늘린다."
Intel Core Ultra Arc 내장 그래픽 심화 분석
Core Ultra 5 125H의 Arc 내장 그래픽(Xe2 아키텍처)은 AV1 하드웨어 인코더/디코더를 모두 내장한다. H.265 대비 40% 높은 압축률을 제공하면서도 전력 소비는 동급 HEVC 인코딩과 거의 동일하다. 이 AV1 지원은 12세대(Alder Lake) iGPU에는 없고, 코어 울트라(Meteor Lake) 이상에서만 제공되는 기능이다.
4K HDR → SDR 톤매핑 트랜스코딩은 Intel의 OpenCL 기반 VPP(Video Post Processing) 필터를 통해 처리된다. vainfo로 확인하면 VAProfileH264High, VAProfileHEVCMain10, VAProfileAV1Profile0 등이 지원 프로파일로 나열된다. 톤매핑을 동반한 4K 스트림 3개를 동시 처리해도 CPU 점유율 25% 미만을 유지한다.
FFmpeg 심화 — QSV / NVENC / AMF 명령어 완전 가이드
Intel QSV — 기본 트랜스코딩
QSV를 사용하는 가장 기본적인 FFmpeg 명령어부터 시작한다. -hwaccel qsv는 디코딩도 하드웨어로 처리하겠다는 의미이고, -c:v h264_qsv는 QSV 기반 H.264 인코더를 지정한다.
# 4K H.265 → 1080p H.264 (QSV 하드웨어 디코딩 + 인코딩)
ffmpeg \
-hwaccel qsv \
-hwaccel_output_format qsv \
-c:v hevc_qsv \
-i input_4k.mkv \
-vf "scale_qsv=1920:1080" \
-c:v h264_qsv \
-preset medium \
-global_quality 23 \
-look_ahead 1 \
-look_ahead_depth 40 \
-profile:v high \
-level 4.1 \
-c:a copy \
output_1080p.mp4
# 옵션 설명:
# -global_quality 23 : CQP 방식 품질 제어 (낮을수록 고품질, 범위 1-51)
# -look_ahead 1 : 전향 분석으로 품질 향상
# -look_ahead_depth 40 : 40프레임 선행 분석 (0~100, 높을수록 고품질·느림)
# -profile:v high : H.264 High Profile (호환성 최대)
# -level 4.1 : 1080p@30fps 표준 레벨
QSV — 비트레이트 제어 모드 상세
QSV는 CBR(Constant Bit Rate), VBR(Variable Bit Rate), CQP(Constant Quantization Parameter), AVBR(Adaptive VBR), ICQ(Intelligent Constant Quality) 등 다양한 비트레이트 제어 모드를 지원한다. 스트리밍 서버에는 ICQ가 가장 균형 잡힌 선택이다.
# CBR — 네트워크 스트리밍용 고정 비트레이트
ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.mkv \
-c:v h264_qsv \
-b:v 4M -maxrate 4M -bufsize 8M \
output_cbr.mp4
# VBR — 화질 우선 가변 비트레이트
ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.mkv \
-c:v hevc_qsv \
-b:v 6M -maxrate 10M \
output_vbr.mkv
# ICQ — 지능형 품질 제어 (Jellyfin 추천)
ffmpeg -hwaccel qsv -c:v hevc_qsv -i input.mkv \
-c:v h264_qsv \
-global_quality 23 -look_ahead 1 \
output_icq.mp4
# AV1 QSV — 최고 압축 효율
ffmpeg -hwaccel qsv -c:v hevc_qsv -i input_4k.mkv \
-vf "scale_qsv=3840:2160" \
-c:v av1_qsv \
-global_quality 28 \
-preset medium \
output_av1.mp4
NVIDIA NVENC — H.264 / H.265 / AV1
# NVENC H.264 — CUDA 하드웨어 디코딩 포함
ffmpeg \
-hwaccel cuda \
-hwaccel_output_format cuda \
-c:v hevc_cuvid \
-i input_4k.mkv \
-vf "scale_cuda=1920:1080,hwdownload,format=nv12" \
-c:v h264_nvenc \
-preset p5 \
-tune hq \
-rc vbr \
-b:v 4M -maxrate 6M -bufsize 12M \
-profile:v high \
-c:a copy \
output_nvenc.mp4
# NVENC H.265 (HEVC) — 고압축
ffmpeg -hwaccel cuda -c:v hevc_cuvid -i input.mkv \
-c:v hevc_nvenc \
-preset p6 \
-rc constqp -qp 26 \
-profile:v main10 \
output_hevc_nvenc.mkv
# NVENC AV1 (RTX 3000 이상 필요)
ffmpeg -hwaccel cuda -c:v hevc_cuvid -i input.mkv \
-c:v av1_nvenc \
-preset p4 \
-rc vbr -b:v 3M \
output_av1_nvenc.mp4
# 옵션 설명:
# -preset p5~p7 : p1(빠름/저품질) ~ p7(느림/고품질)
# -tune hq : 고화질 튜닝 (hq, ll, ull, lossless)
# -rc vbr : 가변 비트레이트 모드
# -rc constqp -qp 26 : 고정 양자화 파라미터
AMD AMF — H.264 / H.265 / AV1
# AMF H.264
ffmpeg \
-hwaccel vaapi \
-hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi \
-i input.mkv \
-vf "scale_vaapi=1920:1080" \
-c:v h264_amf \
-quality balanced \
-rc vbr_peak -b:v 4M -maxrate 6M \
-profile:v high \
output_amf.mp4
# AMF HEVC
ffmpeg -hwaccel vaapi -i input.mkv \
-vf "scale_vaapi=w=1920:h=1080" \
-c:v hevc_amf \
-quality quality \
-rc cbr -b:v 5M \
output_hevc_amf.mkv
# AMF AV1 (RX 7000 시리즈 이상 필요)
ffmpeg -hwaccel vaapi -i input.mkv \
-c:v av1_amf \
-quality balanced \
-rc vbr -b:v 3M \
output_av1_amf.mp4
# 옵션 설명:
# -quality speed/balanced/quality : 속도-품질 균형
# -rc cbr/vbr/vbr_peak/cqp : 비트레이트 제어 모드
하드웨어 디코딩 + 소프트웨어 필터 조합
하드웨어 디코딩으로 속도를 확보하면서 소프트웨어 필터(자막 합성, 노이즈 제거 등)를 함께 사용해야 할 때는 hwdownload와 hwupload로 GPU ↔ CPU 메모리 간 데이터를 이동시킨다.
# QSV 디코딩 → 소프트웨어 자막 합성 → QSV 인코딩
ffmpeg \
-hwaccel qsv \
-hwaccel_output_format qsv \
-c:v hevc_qsv \
-i input.mkv \
-vf "hwdownload,format=nv12,subtitles=subtitle.srt,hwupload=extra_hw_frames=64,scale_qsv=1920:1080" \
-c:v h264_qsv \
-global_quality 23 \
-c:a aac -b:a 192k \
output_with_sub.mp4
# CUDA 디코딩 → 소프트웨어 필터 → NVENC 인코딩
# (yadif 디인터레이스 + 노이즈 제거)
ffmpeg \
-hwaccel cuda \
-hwaccel_output_format cuda \
-c:v h264_cuvid \
-i interlaced_input.ts \
-vf "hwdownload,format=nv12,yadif=mode=1,hqdn3d=4.0:3.0:6.0:4.5,hwupload_cuda" \
-c:v h264_nvenc \
-preset p5 -rc vbr -b:v 3M \
output_deinterlaced.mp4
# 4K HDR → SDR 톤매핑 (QSV OpenCL 필터)
ffmpeg \
-hwaccel qsv \
-hwaccel_output_format qsv \
-c:v hevc_qsv \
-i hdr_4k.mkv \
-vf "hwdownload,format=p010,zscale=t=linear:npl=100,format=gbrpf32le,\
zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p,\
hwupload=extra_hw_frames=64,scale_qsv=1920:1080" \
-c:v h264_qsv -global_quality 23 \
-c:a copy \
output_sdr.mp4
진행률 표시 및 로그 제어
장시간 배치 변환 시 진행 상황을 파악하는 방법이 중요하다. FFmpeg의 -progress 옵션과 -stats 플래그를 활용하면 스크립트에서 진행률을 파싱할 수 있다.
# 진행률을 파일로 출력 (파싱 용이)
ffmpeg -i input.mkv -c:v h264_qsv -global_quality 23 \
-progress /tmp/ffmpeg_progress.txt \
-stats \
output.mp4
# 진행률 파일 실시간 모니터링 (다른 터미널에서)
watch -n 1 "grep -E 'out_time=|fps=|speed=' /tmp/ffmpeg_progress.txt | tail -5"
# 퍼센트 계산하는 단순 래퍼 함수 (bash)
ffmpeg_with_progress() {
local input="$1"
local output="$2"
shift 2
local opts=("$@")
# 소스 길이(초) 구하기
local duration
duration=$(ffprobe -v quiet -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 "$input")
# 소수점 처리
duration=${duration%.*}
ffmpeg -i "$input" "${opts[@]}" \
-progress pipe:1 "$output" 2>/dev/null | \
while IFS= read -r line; do
if [[ "$line" =~ ^out_time_ms=([0-9]+) ]]; then
local ms="${BASH_REMATCH[1]}"
local pct=$(( ms / 1000 / duration ))
printf "\r진행: %d%%" "$pct"
fi
done
echo ""
}
# 사용 예
ffmpeg_with_progress input.mkv output.mp4 \
-hwaccel qsv -c:v h264_qsv -global_quality 23
배치 변환 스크립트 — 폴더 전체 자동 트랜스코딩
홈서버에서 대량의 미디어 파일을 일괄 변환하는 시나리오는 매우 흔하다. 아래 스크립트는 지정 폴더의 모든 MKV/AVI/MOV 파일을 H.264 QSV로 변환하고, 원본 대비 크기 비교 후 자동 정리까지 수행한다.
#!/bin/bash
# batch_transcode.sh — QSV 배치 변환 스크립트
# 사용법: bash batch_transcode.sh /path/to/source /path/to/output
set -euo pipefail
SOURCE_DIR="${1:-.}"
OUTPUT_DIR="${2:-./transcoded}"
LOG_FILE="/tmp/batch_transcode_$(date +%Y%m%d_%H%M%S).log"
QUALITY=23 # ICQ 품질 (낮을수록 고품질)
PRESET="medium" # QSV 프리셋
EXTENSIONS=("mkv" "avi" "mov" "mp4" "ts" "m2ts")
mkdir -p "$OUTPUT_DIR"
echo "=======================================" | tee -a "$LOG_FILE"
echo "배치 트랜스코딩 시작: $(date)" | tee -a "$LOG_FILE"
echo "소스 디렉토리: $SOURCE_DIR" | tee -a "$LOG_FILE"
echo "출력 디렉토리: $OUTPUT_DIR" | tee -a "$LOG_FILE"
echo "=======================================" | tee -a "$LOG_FILE"
# 처리할 파일 목록 수집 (한글·특수문자 파일명 안전 처리)
mapfile -d '' file_list < <(
for ext in "${EXTENSIONS[@]}"; do
find "$SOURCE_DIR" -maxdepth 2 -iname "*.${ext}" -print0
done
)
total=${#file_list[@]}
echo "총 파일 수: $total" | tee -a "$LOG_FILE"
success=0
fail=0
for i in "${!file_list[@]}"; do
input="${file_list[$i]}"
basename_noext=$(basename "${input%.*}")
output="${OUTPUT_DIR}/${basename_noext}_h264qsv.mp4"
echo "" | tee -a "$LOG_FILE"
echo "[${i+1}/${total}] 처리 중: $(basename "$input")" | tee -a "$LOG_FILE"
if [[ -f "$output" ]]; then
echo " → 이미 존재, 건너뜀" | tee -a "$LOG_FILE"
continue
fi
# 임시 파일로 변환 (변환 실패 시 불완전 파일 방지)
tmp_output="${output}.tmp.mp4"
if ffmpeg -y \
-hwaccel qsv \
-hwaccel_output_format qsv \
-i "$input" \
-vf "scale_qsv=trunc(iw/2)*2:trunc(ih/2)*2" \
-c:v h264_qsv \
-preset "$PRESET" \
-global_quality "$QUALITY" \
-look_ahead 1 \
-profile:v high \
-level 4.1 \
-c:a aac -b:a 192k \
-movflags +faststart \
"$tmp_output" \
>> "$LOG_FILE" 2>&1; then
mv "$tmp_output" "$output"
# 크기 비교 및 로그
src_size=$(du -sh "$input" | cut -f1)
dst_size=$(du -sh "$output" | cut -f1)
echo " → 성공: $src_size → $dst_size" | tee -a "$LOG_FILE"
((success++))
else
rm -f "$tmp_output"
echo " → 실패: FFmpeg 오류 발생" | tee -a "$LOG_FILE"
((fail++))
fi
done
echo "" | tee -a "$LOG_FILE"
echo "=======================================" | tee -a "$LOG_FILE"
echo "완료: 성공 $success / 실패 $fail / 전체 $total" | tee -a "$LOG_FILE"
echo "로그 파일: $LOG_FILE"
Antigravity로 한글·특수문자 파일명 사전 정리
FFmpeg는 파일명의 한글, 공백, 특수문자(괄호, 앰퍼샌드 등)를 처리하다가 오류를 내는 경우가 있다. 특히 NAS에서 Windows로 복사된 파일명에 이런 문제가 잦다. 배치 변환 전에 Antigravity(AI 기반 파일명 정리 도구)로 파일명을 일괄 정규화하면 FFmpeg 오류를 예방할 수 있다.
# Antigravity 설치
pip install antigravity # 또는 해당 배포 방식에 따라 설치
# 폴더 내 파일명 일괄 정규화 (한글 → 로마자 변환, 특수문자 제거)
antigravity rename /mnt/nas/movies --pattern "safe_ascii" --dry-run
# --dry-run 으로 먼저 미리보기 확인
antigravity rename /mnt/nas/movies --pattern "safe_ascii"
# 직접 bash로도 가능: 공백 → 언더스코어, 특수문자 제거
find /mnt/nas/movies -name "*.mkv" | while IFS= read -r f; do
dir=$(dirname "$f")
base=$(basename "$f")
# 공백·괄호·특수문자 치환
newbase=$(echo "$base" | tr ' ' '_' | sed 's/[^a-zA-Z0-9._가-힣-]//g')
if [[ "$base" != "$newbase" ]]; then
mv -v "$f" "$dir/$newbase"
fi
done
Docker Jellyfin에서 QSV·VAAPI 활성화
먼저 호스트 시스템에서 Intel GPU 드라이버와 media-driver가 올바르게 설치됐는지 확인한다.
# Intel media-driver 설치 (Ubuntu 24.04)
sudo apt update
sudo apt install -y intel-media-va-driver-non-free vainfo \
intel-gpu-tools i965-va-driver-shaders
# 드라이버 인식 확인
vainfo
# 정상 출력 예시:
# vainfo: VA-API version: 1.20 (libva 2.20.0)
# vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 24.1.0
# vainfo: Supported profile and entrypoints
# VAProfileH264Main : VAEntrypointVLD
# VAProfileH264High : VAEntrypointVLD
# VAProfileH264High : VAEntrypointEncSlice
# VAProfileHEVCMain : VAEntrypointVLD
# VAProfileHEVCMain : VAEntrypointEncSlice
# VAProfileAV1Profile0 : VAEntrypointVLD
# VAProfileAV1Profile0 : VAEntrypointEncSlice
# DRI 장치 권한 확인
ls -la /dev/dri/
# crw-rw---- 1 root render 226, 128 renderD128 ← render 그룹 필요
# 현재 유저를 render, video 그룹에 추가
sudo usermod -aG render,video $USER
# 그룹 적용 (재로그인 없이)
newgrp render
Docker Compose 설정에서 GPU 디바이스를 컨테이너에 노출시키는 것이 핵심이다.
services:
jellyfin:
image: jellyfin/jellyfin:latest
container_name: jellyfin
network_mode: host
user: "1000:1000"
volumes:
- ./config:/config
- ./cache:/cache
- /mnt/nas/media:/media:ro
devices:
- /dev/dri:/dev/dri # Intel QSV / VAAPI GPU 노출 (필수)
group_add:
- "render" # /dev/dri/renderD128 접근 (GID 확인 필요)
- "video" # /dev/dri/card0 접근
environment:
- JELLYFIN_PublishedServerUrl=http://192.168.1.100:8096
- DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8096/health"]
interval: 30s
timeout: 10s
retries: 3
# NVENC 사용 시 (nvidia-docker2 설치 필요)
jellyfin-nvidia:
image: jellyfin/jellyfin:latest
container_name: jellyfin-nvidia
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
# ... 나머지 동일
Jellyfin 대시보드 → 관리 → 재생 → 하드웨어 가속에서 Intel QuickSync (QSV)를 선택한다. 활성화할 코덱(H.264, HEVC, AV1)을 체크하고, HDR 콘텐츠의 SDR 변환을 위해 톤 매핑 사용 옵션도 활성화한다. 재생 중 대시보드 → 활성 스트림에서 트랜스코딩 방식이 HWA로 표시되면 정상이다. Direct Stream은 클라이언트가 원본 코덱을 직접 지원해 트랜스코딩이 발생하지 않는 상태다.
오류 발생 시 AI 도구(Claude Code) 활용 진단
트랜스코딩 환경 구성에서 오류가 발생할 때 Claude Code는 로그 분석과 원인 파악에 즉각적으로 도움이 된다. 오류 메시지를 그대로 붙여넣으면 드라이버 누락, 권한 문제, 코덱 지원 여부 등을 정확히 진단해준다.
vainfo 오류 진단
# vainfo 오류 발생 시 — 출력 전체를 Claude Code에 전달
vainfo 2>&1 | tee /tmp/vainfo_output.txt
# Claude Code로 분석 요청
claude "다음 vainfo 오류를 분석해줘. Intel Core Ultra 125H에서
intel-media-va-driver-non-free 설치했는데 계속 실패해.
$(cat /tmp/vainfo_output.txt)"
# 흔한 vainfo 오류 패턴:
# 1. "error: failed to initialize display"
# → /dev/dri/renderD128 권한 문제 (render 그룹 미가입)
# → sudo chmod 660 /dev/dri/renderD128 임시 해결 가능
# 2. "libva error: /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so init failed"
# → intel-media-va-driver-non-free 미설치 또는 버전 불일치
# 3. "vaInitialize failed with error code -1"
# → 커널 드라이버(i915/xe) 로드 실패
# → dmesg | grep -i i915 로 커널 오류 확인 필요
FFmpeg QSV 초기화 실패 진단
# FFmpeg 상세 로그로 QSV 초기화 과정 추적
ffmpeg -loglevel debug \
-hwaccel qsv \
-c:v hevc_qsv \
-i test.mkv \
-c:v h264_qsv -frames:v 1 /dev/null 2>&1 | tee /tmp/ffmpeg_debug.txt
# Claude Code로 드라이버 문제 진단
claude "FFmpeg QSV 초기화가 실패하고 있어. 다음은 -loglevel debug 출력이야.
Ubuntu 24.04, Intel Core Ultra 5 125H 환경이고 vainfo는 정상인데
FFmpeg에서만 qsv 초기화가 안 돼.
$(cat /tmp/ffmpeg_debug.txt)"
# 흔한 FFmpeg QSV 오류:
# "Error creating a MFX session"
# → libmfx 또는 libvpl 라이브러리 미설치
# → sudo apt install libvpl2 libvpl-dev intel-mediasdk
# "Device creation failed for device type 'qsv'"
# → MFX_IMPL_AUTO_ANY 초기화 실패
# → LIBVA_DRIVER_NAME=iHD 환경변수로 강제 지정
# → export LIBVA_DRIVER_NAME=iHD 후 재시도
Plex 트랜스코딩 실패 로그 분석
# Plex 트랜스코딩 로그 위치 (Docker)
docker exec plex cat /config/Library/Application\ Support/Plex\ Media\ Server/Logs/Plex\ Transcoder.log | tail -100
# 로그를 Claude Code로 분석
docker exec plex tail -200 \
"/config/Library/Application Support/Plex Media Server/Logs/Plex Transcoder.log" \
> /tmp/plex_transcode.log
claude "Plex 트랜스코딩이 계속 실패해. 하드웨어 가속을 켰는데 CPU 트랜스코딩으로 폴백되고 있어.
서버: Intel Core Ultra 5 125H, Ubuntu 24.04, Plex Docker (plexinc/pms-docker).
로그:
$(cat /tmp/plex_transcode.log)"
# Jellyfin 트랜스코딩 로그 (Docker)
docker logs jellyfin 2>&1 | grep -i "transcode\|hwaccel\|qsv\|vaapi" | tail -50 \
| xargs -I{} echo "{}" | tee /tmp/jellyfin_transcode.log
claude "Jellyfin 하드웨어 가속 설정 문제 분석해줘: $(cat /tmp/jellyfin_transcode.log)"
트랜스코딩 파일 관리 자동화
원본 vs 변환본 비교 및 원본 삭제 자동화
변환 완료 후 원본 파일을 안전하게 삭제하려면 변환 결과물의 무결성을 먼저 검증해야 한다. 아래 스크립트는 변환본의 재생 시간과 화질을 원본과 비교한 뒤 안전할 때만 원본을 삭제한다.
#!/bin/bash
# verify_and_cleanup.sh — 변환본 검증 후 원본 정리
SOURCE_DIR="$1"
OUTPUT_DIR="$2"
DRY_RUN="${3:-true}" # true = 삭제 안 함, false = 실제 삭제
get_duration() {
ffprobe -v quiet -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 "$1" 2>/dev/null
}
get_video_codec() {
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name \
-of default=noprint_wrappers=1:nokey=1 "$1" 2>/dev/null
}
deleted=0
skipped=0
find "$OUTPUT_DIR" -name "*_h264qsv.mp4" | while IFS= read -r output; do
# 원본 파일명 추론 (확장자 다를 수 있으므로 이름으로 검색)
base=$(basename "${output%_h264qsv.mp4}")
source=$(find "$SOURCE_DIR" -maxdepth 2 -name "${base}.*" | head -1)
if [[ -z "$source" ]]; then
echo "경고: 원본 없음 → $output"
continue
fi
src_dur=$(get_duration "$source")
dst_dur=$(get_duration "$output")
dst_codec=$(get_video_codec "$output")
# 재생 시간 차이 1초 이내인지 확인
dur_diff=$(awk "BEGIN{d=$src_dur - $dst_dur; print (d<0)?-d:d}")
dur_ok=$(awk "BEGIN{print ($dur_diff < 1.0) ? 1 : 0}")
# 코덱 확인
codec_ok=0
[[ "$dst_codec" == "h264" ]] && codec_ok=1
# 파일 크기 확인 (0바이트 방지)
size=$(stat -c%s "$output" 2>/dev/null || echo 0)
size_ok=0
[[ "$size" -gt 1000000 ]] && size_ok=1 # 최소 1MB
if [[ "$dur_ok" == "1" && "$codec_ok" == "1" && "$size_ok" == "1" ]]; then
echo "검증 통과: $(basename "$source") → $(basename "$output")"
if [[ "$DRY_RUN" == "false" ]]; then
rm -v "$source"
((deleted++))
else
echo " [DRY RUN] 삭제 예정: $source"
fi
else
echo "검증 실패 (dur_ok=$dur_ok codec_ok=$codec_ok size_ok=$size_ok): $(basename "$output")"
((skipped++))
fi
done
echo "완료: 삭제 $deleted, 건너뜀 $skipped"
임시 파일 자동 정리
# .tmp.mp4 임시 파일 정리 (변환 중단 시 남은 파일)
find /mnt/nas -name "*.tmp.mp4" -mmin +60 -delete
# 60분 이상 된 .tmp.mp4만 삭제 (진행 중 파일 방지)
# Jellyfin 트랜스코딩 캐시 정리 (Docker)
docker exec jellyfin find /cache/transcodes -name "*.ts" -mmin +30 -delete
docker exec jellyfin find /cache/transcodes -name "*.m3u8" -mmin +30 -delete
# cron으로 매시간 자동 정리 등록
(crontab -l 2>/dev/null; echo "0 * * * * find /mnt/nas -name '*.tmp.mp4' -mmin +60 -delete") | crontab -
(crontab -l 2>/dev/null; echo "*/30 * * * * docker exec jellyfin find /cache/transcodes -mmin +30 -name '*.ts' -delete 2>/dev/null") | crontab -
트랜스코딩 큐 관리 — 우선순위 기반 처리
# 큐 파일 기반 트랜스코딩 (우선순위 지원)
# 큐에 파일 추가
echo "/mnt/nas/movies/movie_a.mkv" >> /tmp/transcode_queue.txt
echo "/mnt/nas/movies/movie_b.mkv" >> /tmp/transcode_queue.txt
# 큐 처리 데몬 (백그라운드 실행)
while IFS= read -r input; do
[[ -z "$input" || ! -f "$input" ]] && continue
output="${input%.*}_h264.mp4"
echo "[큐] 처리 시작: $input"
nice -n 10 ffmpeg -y \
-hwaccel qsv \
-i "$input" \
-c:v h264_qsv -global_quality 23 \
-c:a aac -b:a 192k \
"$output" && echo "[큐] 완료: $output"
done < /tmp/transcode_queue.txt
# 동시 트랜스코딩 제한 (GNU parallel 사용)
# 최대 2개 동시 처리 (QSV 세션 한계 고려)
cat /tmp/transcode_queue.txt | parallel --jobs 2 \
'ffmpeg -hwaccel qsv -i {} -c:v h264_qsv -global_quality 23 {.}_h264.mp4'
비용 절감 시뮬레이션 — 연간 전기료 계산
소프트웨어 트랜스코딩(TDP 65W)과 QSV 하드웨어 가속(TDP 17W)의 차이는 48W다. 하루 8시간 스트리밍 운영 기준으로 연간 전기료 차이를 계산하면 48W × 8h × 365일 = 140.16kWh이며, 한국 가정용 전기 단가(약 200원/kWh) 기준으로 약 28,032원이다. 4인 가족이 각자 다른 콘텐츠를 스트리밍할 경우 4배인 약 112,128원 절감된다. NVIDIA RTX 3060의 경우 아이들 전력이 높아 실질 절감액은 Intel iGPU 대비 낮다.
| 엔진 | 평균 트랜스코딩 전력 (W) | 아이들 전력 (W) | 연간 비용 (4스트림·8h/day) | 총평 |
|---|---|---|---|---|
| Software (libx264) | 65W | 8W | 37,960원 | 비효율 |
| Intel QSV (iGPU) | 17W | 3W | 9,928원 | ★ 최고 효율 |
| NVIDIA NVENC (RTX 3060) | 50W | 15W | 29,200원 | 고성능 |
| AMD AMF (RX 7600) | 44W | 12W | 25,664원 | 양호 |
* 한국 가정용 전기 200원/kWh 기준, 4스트림 동시 운영, 하루 8시간, 365일 운영 가정.