최근 유튜브 채널에 올릴 영상을 제작하면서 이상한 현상을 발견했습니다. 제 PC에서는 분명히 적당한 밝기로 보였던 영상이, 유튜브에만 업로드하면 전체적으로 톤이 다운되고 어두워지는 문제였습니다.
특히 제가 사용하는 Pexels의 자연 영상 위에 반투명 오버레이까지 적용한 상태라, 이 현상은 더욱 두드러졌습니다. 처음에는 비트레이트나 압축률 문제라고 생각했지만, 수많은 테스트 끝에 진짜 원인이 바로 '색 공간(Color Space)'의 불일치에 있다는 것을 알게 되었습니다.
오늘은 저와 같은 문제를 겪는 영상 제작자분들을 위해, 이 문제를 완벽하게 해결해 준 FFmpeg 색 공간 보정 방법을 공유합니다.
1. 문제의 원인: "PC 모니터와 유튜브가 세상을 다르게 본다"
우리가 겪는 이 문제의 핵심은, PC 환경과 방송/스트리밍 환경이 사용하는 '색상 표현 범위'가 다르기 때문입니다.
- PC 환경 (Full Range, 0-255):
- 우리가 쓰는 대부분의 모니터와 동영상 플레이어는 0(완벽한 검정)부터 255(완벽한 흰색)까지 256단계의 색을 모두 표현합니다.
- 유튜브/방송 환경 (Limited Range, 16-235):
- 반면, 유튜브를 포함한 대부분의 방송 플랫폼은 16(방송용 검정)부터 235(방송용 흰색)까지의 범위만 표준으로 사용합니다.
무슨 일이 벌어질까요?
PC(Full Range)에서 만든 영상을 아무런 정보 없이 유튜브(Limited Range)에 던져주면, 유튜브는 이 영상을 자기 표준에 맞춰 강제로 압축(Squeeze)해버립니다.
PC에서의 색상: [0...16......235...255]
유튜브의 압축: [ (0 - 16은 모두 16으로) ... (235- 255는 모두 235로) ]
이 과정에서 우리가 세심하게 조절했던 어두운 영역(Shadow)의 디테일은 모두 뭉개져 버리고(Crushed Blacks), 전체적으로 콘트라스트가 강해지며 어둡게 보이게 됩니다.
2. 해결책: FFmpeg로 "이 영상은 유튜브용입니다" 꼬리표 달기
해결책은 간단합니다. 영상을 만들 때부터 FFmpeg에게 "이 영상은 유튜브 표준(Limited Range)에 맞춰서 만들어 줘"라고 명확하게 알려주는 것입니다.
이는 두 단계로 이루어집니다.
- 필터 적용: 영상의 모든 픽셀을 방송 표준(BT.709, Limited Range) 색 공간으로 변환합니다.
- 메타데이터 삽입: 출력 파일에 "이 영상은 Limited Range입니다"라는 꼬리표(Flag)를 달아 유튜브가 오해하지 않도록 합니다.
3. FFmpeg 파이썬 코드 예제 (해결편)
저는 subprocess를 이용해 FFmpeg를 실행하는데, 아래와 같이 필터와 출력 옵션을 추가하여 문제를 해결했습니다.
① filter_complex: colorspace 필터 추가하기
먼저, filter_complex 문자열의 비디오 필터 체인 가장 마지막에 아래 필터를 추가해 줍니다.
# 기존 필터 체인 마지막에 이 필터를 쉼표(,)로 연결해 줍니다.
colorspace_filter = "colorspace=all=bt709:trc=bt709:primaries=bt709:range=tv"
# 예시
filter_complex = f"[0:v]...[v_some_filter];[v_some_filter]{colorspace_filter}[v_final]"
range=tv: 이 부분이 바로 "Limited Range로 만들어 줘"라는 핵심 명령입니다.
② 출력 옵션: 색상 메타데이터 명시하기
다음으로, 최종 출력 명령어에 아래 옵션들을 추가합니다. 이 옵션들이 바로 '꼬리표' 역할을 합니다.
[libx264 (소프트웨어 인코딩) 예제]
command_sw = [
'ffmpeg', '-y', *input_args,
'-filter_complex', filter_complex,
'-map', '[v_final]', '-map', '[a_final]',
'-c:v', 'libx264', '-preset', 'fast', '-crf', '21',
# --- ✨ 색 공간 보정 옵션 (핵심) ✨ ---
'-pix_fmt', 'yuv420p', # 웹 스트리밍 표준 픽셀 포맷
'-colorspace', 'bt709', # HD 표준 색 공간
'-color_trc', 'bt709', # 감마 값
'-color_primaries', 'bt709', # 색상 원본
'-color_range', 'tv', # 'Limited Range' 명시
# ------------------------------------
'-c:a', 'aac', '-b:a', '192k',
output_path
]
subprocess.run(command_sw, check=True)
[h264_amf (하드웨어 인코딩) 예제]
하드웨어 인코더도 동일한 옵션을 추가해 주면 됩니다.
command_hw = [
'ffmpeg', '-y', *input_args,
'-filter_complex', filter_complex,
'-map', '[v_final]', '-map', '[a_final]',
'-c:v', 'h264_amf', '-b:v', '4000k',
# --- ✨ 동일한 색 공간 보정 옵션 추가 ✨ ---
'-pix_fmt', 'yuv420p',
'-colorspace', 'bt709',
'-color_trc', 'bt709',
'-color_primaries', 'bt709',
'-color_range', 'tv',
# ------------------------------------
'-c:a', 'aac', '-b:a', '192k',
output_path
]
subprocess.run(command_hw, check=True)
🚀 결론: "출신 성분을 밝혀라"
유튜브 업로드 후 색감이 변하는 문제는 대부분 영상 파일에 '색 공간 정보'가 없거나 잘못되어 유튜브가 임의로 처리하기 때문에 발생합니다.
위와 같이 FFmpeg를 사용하여 영상의 출신 성분(색 공간, 범위 등)을 명확히 밝혀주면, 유튜브는 더 이상 불필요한 변환을 하지 않고 우리가 의도한 색감 그대로를 시청자에게 보여줍니다.
단순히 밝기를 조절하는 것보다 훨씬 더 근본적이고 정확한 해결책이니, 영상 제작자라면 이 옵션들을 꼭 기본값으로 사용해 보시길 바랍니다.
'디자인 인사이트 > 동영상 만들기' 카테고리의 다른 글
| [유튜브 꿀팁] 조회수, 제목이 90%를 결정한다? 클릭을 부르는 제목 작성 공식 총정리 (0) | 2026.01.21 |
|---|---|
| 파이썬과 FFmpeg로 만드는 프리미엄 오디오북: 남성 성우 & 피아노 BGM 최적화 가이드 (0) | 2026.01.19 |
| [Python] 오디오북을 위한 '물 흐르는' 동기화 스크롤 자막 만들기 (ASS 자막 마스터하기) (0) | 2026.01.16 |
| 자막에 생명을! Python과 ASS로 '말씀'만 색상 바꾸는 자동화 비법 (0) | 2026.01.15 |
| [완벽 가이드] Python과 FFmpeg로 전문가급 오디오북 영상 자동 제작하기 (0) | 2026.01.14 |
댓글