<chan9yu />
홈포스트시리즈태그About


@chan9yu's dev blog

프론트엔드 개발의 아이디어와 경험을 기록하는 개발 블로그
코드와 디자인, 사용자 경험을 아우르는 인사이트를 담습니다.

RSSGitHubEmail
© 2026 chan9yu. All rights reserved.

미디어 코덱 뜯어보기 (VP8부터 차세대 AV2까지)

WebRTC에서 사용되는 비디오 코덱(VP8, VP9, H.264)과 오디오 코덱(Opus, G.711)을 실무 관점에서 비교하고, 크롬 내부 페이지로 실제 코덱을 확인하는 방법까지 다룹니다. AV1, AV2 등 차세대 코덱도 함께 살펴봅니다.

2026년 1월 18일
 
WebRTC코덱VP8VP9H.264Opus

미디어 코덱 뜯어보기 (VP8부터 차세대 AV2까지)
이전 글

2025년, 번아웃과 성장 사이에서

다음 글

Claude Code Agent Teams로 AI 뉴스봇 만들기

이런 글도 읽어보세요

[WebRTC 박살내기 #1] WebRTC 개념과 연결 구조 완전 정리

[WebRTC 박살내기 #1] WebRTC 개념과 연결 구조 완전 정리

2025년 10월 11일

WebRTC 박살내기 첫번째 시리즈 입니다. WebRTC 기본 개념부터 시그널링, Offer/Answer(SDP), Trickle ICE, STUN/TURN, NAT, 그리고 Mesh·SFU·MCU 아키텍처까지 한 번에 정리합니다.

WebRTC실시간통신+5
1분
[WebRTC 박살내기 #2] 미디어 스트림과 트랙 완벽 이해

[WebRTC 박살내기 #2] 미디어 스트림과 트랙 완벽 이해

2025년 10월 13일

WebRTC 박살내기 두번째 시리즈 입니다. WebRTC의 MediaStream과 MediaStreamTrack을 깊이 이해하고, getUserMedia부터 트랙 제어, 품질 관리까지 실전 예제와 함께 알아봅니다.

WebRTCMediaStream+2
1분
[WebRTC 박살내기 #3] PeerConnection API와 이벤트 흐름

[WebRTC 박살내기 #3] PeerConnection API와 이벤트 흐름

2025년 10월 20일

WebRTC 박살내기 세번째 시리즈 입니다. WebRTC의 핵심 RTCPeerConnection을 완벽하게 이해하고, 연결 생성부터 이벤트 처리, 품질 관리, 연결 복구까지 실전 예제와 함께 알아봅니다.

WebRTCRTCPeerConnection+4
1분

댓글

목차

  • 프롤로그
  • 코덱이 필요한 이유
  • 압축 없이는 불가능합니다
  • 코덱의 압축 효과
  • 코덱 기초 개념
  • 비트레이트(Bitrate)
  • 해상도(Resolution)
  • 프레임레이트(Frame Rate)
  • 인코딩과 디코딩
  • 비디오 코덱 비교
  • VP8
  • 사용 시나리오
  • 대략적 범위
  • VP9
  • 사용 시나리오
  • VP8 vs VP9 비교
  • 브라우저/환경 메모
  • H.264
  • 사용 시나리오
  • 대략적 범위
  • H.264 프로파일
  • 비디오 코덱 선택 가이드
  • 오디오 코덱 비교
  • Opus
  • 비트레이트별 품질 비교
  • 용도별 권장 범위
  • G.711
  • 사용 시나리오
  • G.711 vs Opus 비교
  • 크롬에서 실제 코덱 확인하기
  • webrtc-internals 활용
  • 1. 접속 방법
  • 2. 연결 정보 확인(영상)
  • 3. 운영에서 같이 보면 좋은 지표 5개
  • 4. 코덱 정보 찾기
  • SDP 확인
  • 실무 설정 예시
  • 1. 연결 설정(ICE 서버)
  • 2. 저대역폭 모드(캡처 제약 + 오디오 전처리)
  • 3. 코덱 선호 설정
  • 화면공유와 다자간 통화에서 달라지는 포인트
  • 화면공유는 카메라 영상과 다릅니다
  • 다자간(SFU) 통화는 전송 전략이 더 중요해집니다
  • 차세대 코덱
  • AV1
  • AV2
  • 마무리
  • 핵심 정리
미디어
영상통화
AV1
AV2

프롤로그

WebRTC로 실시간 영상 상담 서비스를 개발하면서 항상 궁금했던 질문이 있었습니다.

"왜 같은 네트워크 환경인데, 어떤 통화는 선명하고 어떤 통화는 화질이 떨어질까?"

답은 코덱(Codec)에 있었습니다.
같은 화상 통화라도 어떤 코덱을 사용하느냐에 따라 화질, 데이터 사용량, 기기 부하(발열/배터리)가 크게 달라질 수 있습니다.

이번 글에서는 WebRTC에서 사용되는 미디어 코덱을 실무 관점에서 정리했습니다.
복잡한 압축 알고리즘 이론은 제외하고, 실무에 바로 도움이 되는 핵심 포인트만 담았습니다.


코덱이 필요한 이유

압축 없이는 불가능합니다

HD 영상(1920×1080) 1초 분량을 단순 계산해보겠습니다.
(대략치이며, 단순화를 위해 RGBA 4바이트, 30프레임, 10진 단위 표기를 사용합니다.)

1920 × 1080 픽셀 × 4바이트 × 30프레임  
= 약 249MB/초  

30분 화상 통화라면 약 450GB의 데이터가 필요합니다.
이를 실시간으로 전송하려면 약 2Gbps 수준의 대역폭이 필요한데, 일반 가정용 인터넷(예: 100Mbps)으로는 어렵습니다.

💡 코덱(Codec)이란?
Coder + Decoder의 합성어입니다.
영상과 음성을 압축(인코딩)하고 다시 푸는(디코딩) 기술을 의미합니다.

코덱의 압축 효과

같은 HD 영상을 코덱으로 압축하면 대략 이런 수준으로 내려갈 수 있습니다.
(콘텐츠/장면 복잡도/인코더 설정/목표 지연/손실률에 따라 편차가 매우 큽니다.)

상황필요 대역폭압축률
압축 없음2,000Mbps-
H.264 압축2~4Mbps약 1/500~1/1,000
VP9 압축1~3Mbps약 1/700~1/1,500

코덱 압축 비교

💡 손실 압축 vs 무손실 압축
손실 압축: 원본과 완전히 동일하진 않지만, 사람이 인지하기 어려운 수준으로 압축 (H.264, VP9 등)
무손실 압축: 원본과 100% 동일하게 복원 가능 (예: FLAC)

WebRTC는 실시간성이 중요하기 때문에 손실 압축을 주로 사용합니다.


코덱 기초 개념

비트레이트(Bitrate)

1초에 전송되는 데이터의 양을 의미합니다.

화질비트레이트특징
360p300~800Kbps저화질
480p600Kbps~1.5Mbps일반
720p1.5~3MbpsHD
1080p3~6MbpsFull HD

비트레이트가 높을수록 화질은 좋아질 가능성이 크지만, 네트워크 부담과 데이터 사용량, 기기 부하가 함께 증가합니다.

해상도(Resolution)

영상의 가로×세로 픽셀 수를 나타냅니다.

이름해상도주 사용처
HD1280×720일반 화상 통화
Full HD1920×1080고화질 통화/상담
QHD2560×1440고급 모니터

WebRTC 실무에서는 대개 720p를 기본 목표로 두는 경우가 많습니다.
1080p는 네트워크/발열/배터리 부담이 커서, 서비스 성격에 따라 720p로도 충분한 경우가 많습니다.

프레임레이트(Frame Rate)

1초에 표시되는 프레임(장) 수를 의미합니다.

FPS체감주 사용처
15약간 끊김저속 네트워크
24영화 같은 느낌일반 영상
30자연스러움일반 화상 통화
60매우 부드러움게임/고프레임

WebRTC는 프레임레이트를 "표준값"으로 고정하지 않습니다.
실무에서는 24~30fps를 목표로 두는 경우가 많지만, 실제 값은 네트워크/기기 성능에 따라 내려가거나 적응적으로 변합니다.

인코딩과 디코딩

인코딩(Encoding): 원본 영상을 압축하는 과정
디코딩(Decoding): 압축된 영상을 재생 가능한 형태로 복원하는 과정

인코딩 디코딩 과정

발신자(SENDER): 미디어 -> 인코딩(Encoding) -> 전송
수신자(RECEIVER): 수신 -> 디코딩(Decoding) -> 화면 표시

양쪽 모두 같은 코덱을 지원해야 통신이 가능합니다.

💡 여기서 "지원"은
단순히 목록에 있다는 뜻뿐 아니라, 정책/가속 여부/협상 결과까지 포함해 실무에서는 더 넓게 봐야 합니다.


비디오 코덱 비교

VP8

2010년 Google이 On2 Technologies를 인수하면서 공개한 코덱입니다.

특징
  • WebRTC 호환 구현에서 필수 구현(MTI) 비디오 코덱으로 요구됩니다.
  • 로열티 부담을 피하려는 선택지로 자주 언급됩니다(서비스/배포 형태에 따라 고려 포인트는 달라질 수 있습니다)
  • 인코딩/디코딩 부담이 비교적 낮은 편
  • 압축 효율은 VP9/AV1 계열 대비 낮은 편

사용 시나리오

대략적 범위

항목범위
720p1.5~3Mbps
1080p3~6Mbps

💡 코덱 지연 팁
지연은 코덱만으로 결정되지 않고, 지터 버퍼/패킷 손실/재전송/인코딩 설정의 영향을 크게 받습니다.

장점: 호환성/안정성, 기기 부하가 비교적 낮은 편
단점: 같은 체감 화질 대비 데이터 사용량이 더 많아질 수 있음

VP9

2013년 공개된 VP8의 후속입니다.
같은 체감 화질을 더 적은 데이터로 만들려는 목표를 가집니다(효과는 장면/설정 의존)

특징
  • VP8 대비 압축 효율 개선(편차 큼)
  • 인코딩 비용(연산량)이 더 큼
  • 오래된 기기/환경에서는 부담이 될 수 있음

사용 시나리오

VP8 vs VP9 비교

항목VP8VP9비고
비트레이트더 높음더 낮아질 수 있음장면/설정 의존
CPU 사용률중간높아질 수 있음기기 의존
인코딩 속도빠름느려질 수 있음설정 의존

장점: 데이터 사용량 감소(조건이 맞으면 효과 큼)
단점: 인코딩 부담 증가, 오래된 기기에서 성능 저하 가능

브라우저/환경 메모

  • Chrome/Firefox/Chromium 계열에서는 VP9 사용이 비교적 수월한 편입니다.
  • Safari는 버전/기기/가속 여부/정책에 따라 결과가 달라질 수 있어, 실무에서는 VP9를 "가능하면 사용" 정도로 두고 H.264/VP8 폴백을 함께 설계하는 편이 안정적입니다.

H.264

2003년 표준화된, 매우 널리 쓰이는 비디오 코덱입니다.

특징
  • WebRTC 호환 구현에서 VP8과 함께 필수 구현(MTI)으로 요구되며, 보통 Constrained Baseline 프로파일 기준으로 논의됩니다.
  • 하드웨어 가속이 잘 되는 환경이 많아(특히 모바일) 전력/발열/부하 측면에서 유리한 경우가 많음
  • 매우 안정적이고 검증된 생태계
  • 압축 효율은 VP9/AV1 계열 대비 낮을 수 있음
  • 특허/라이선스 체계 존재(사용/배포 형태에 따라 이슈가 달라짐)

사용 시나리오

대략적 범위

항목범위
720p1.5~3.5Mbps
1080p3~6Mbps
하드웨어 가속환경에 따라 매우 유리
CPU 사용률하드웨어 사용 시 낮아질 수 있음

💡 라이선스 관련
H.264는 특허 라이선스 체계가 있어, 인코더/디코더의 배포 방식과 서비스 형태에 따라 비용/조건이 달라질 수 있습니다.

H.264 프로파일

프로파일특징용도
Baseline단순, 낮은 복잡도오래된 모바일
Main중간 복잡도일반 방송/저장
High높은 효율/화질고화질 저장/스트리밍
Constrained Baseline실시간 호환 고려실시간 통신에서 자주 언급

비디오 코덱 선택 가이드

  • 기기 부하/배터리(특히 모바일)가 중요하면 H.264를 우선 고려(하드웨어 가속 기대)
  • 대역폭 절약이 중요하면 VP9을 고려하되, 기기 부하와 Safari 변수를 감안해 폴백 포함
  • 무난한 기본값이 필요하면 VP8이 안전한 출발점

비디오 코덱 선택 가이드


오디오 코덱 비교

Opus

2012년 표준화된 오디오 코덱으로, WebRTC에서 핵심 오디오 코덱으로 필수 구현(MTI)에 포함됩니다.

특징
  • 낮은 비트레이트에서도 품질이 좋음
  • 매우 넓은 비트레이트 범위를 지원하며(상황에 따라 적응적으로 운용) 통화 품질을 유지하기 좋음
  • 음성과 음악 모두 준수

비트레이트별 품질 비교

비트레이트OpusG.711
6~8 Kbps통화 가능 수준어려움
16 Kbps음성에 충분어려움
32 Kbps음성 깔끔어려움
64 Kbps고품질전화 수준

용도별 권장 범위

용도비트레이트샘플레이트
음성 통화16~24 Kbps16 kHz
고품질 음성32~40 Kbps24 kHz
음악(모노)48~64 Kbps48 kHz
음악(스테레오)96~128 Kbps48 kHz

G.711

1972년 표준화된 오래된 오디오 코덱으로, 전통 전화망과 호환성이 큽니다.
WebRTC 호환 구현에서는 Opus와 함께 G.711(PCMU/PCMA)도 필수 구현(MTI)으로 요구됩니다.

특징
  • 코덱 처리 자체는 매우 단순한 편
  • 64 Kbps 고정
  • 전화 음질 수준

사용 시나리오

G.711 vs Opus 비교

항목G.711Opus
비트레이트64 Kbps 고정낮은 값부터 가변 운용
샘플레이트8 kHz16~48 kHz(구성 가능)
음질전화 수준더 높은 품질 가능

💡 체감 지연 메모
코덱 처리 지연이 낮아도, 실제 통화 지연은 지터 버퍼/패킷 손실/라우팅 영향이 훨씬 큽니다.


크롬에서 실제 코덱 확인하기

webrtc-internals 활용

1. 접속 방법

WebRTC 연결 중에 새 탭에서 아래 주소로 접속합니다.

chrome://webrtc-internals 화면

2. 연결 정보 확인(영상)

3. 운영에서 같이 보면 좋은 지표 5개

화질이 떨어질 때 "코덱 탓"으로 결론 내리기 전에, 아래를 같이 보면 원인 추적이 빨라집니다.

  • packetsLost / packetsReceived: 손실이 실제로 늘었는지
  • jitter: 수신 간격이 흔들리는지
  • roundTripTime(또는 currentRoundTripTime): 왕복 지연이 튀는지
  • framesDropped / framesDecoded: 디코딩이 밀리고 있는지(기기 부하 신호)
  • nackCount / pliCount / firCount: 재전송/키프레임 요청이 늘었는지(손실/불안정 신호)

4. 코덱 정보 찾기

검색창에 "codec" 입력

코덱 정보 찾기

codec 통계 항목에서 mimeType 확인

예시

코덱 정보 확인

SDP 확인

💡 해석
96, 97, 98은 코덱 "우선순위 번호"가 아니라 페이로드 타입(payload type) 입니다.
일반적으로 앞에 둔 코덱을 선호하도록 "제안"하는 경우가 많지만, 최종 선택은 양쪽 지원 교집합 + 응답(answer) + 브라우저 정책/가속 가능 여부에 의해 바뀔 수 있습니다.


실무 설정 예시

1. 연결 설정(ICE 서버)

아래는 "코덱 설정"이 아니라 연결(ICE) 설정 예시입니다.

2. 저대역폭 모드(캡처 제약 + 오디오 전처리)

아래는 "코덱 변경"이 아니라 입력 해상도/FPS 제한으로 트래픽과 부하를 줄이는 방식입니다.

3. 코덱 선호 설정

브라우저가 지원하는 경우, 트랜시버에서 선호 코덱을 정렬/필터링할 수 있습니다.
(협상에 영향을 주지만 "강제 확정"은 아닙니다.)

💡 참고
이 방식은 "브라우저가 제공하는 협상 로직" 위에서 동작합니다.
SDP를 직접 편집하는 방식도 존재하지만, 유지보수 리스크가 커서 팀/프로덕트 성격에 따라 신중하게 선택하는 편이 좋습니다.


화면공유와 다자간 통화에서 달라지는 포인트

화면공유는 카메라 영상과 다릅니다

화면공유는 카메라 영상과 품질이 저하되는 양상이 다릅니다.

  • 카메라 영상: 얼굴/배경처럼 색이 부드럽게 변하는 영역이 많아, 해상도가 조금 내려가도 체감 품질이 비교적 유지되는 편입니다.
  • 화면공유: 텍스트/선/정적인 UI가 많아, 해상도가 내려가거나 블록 노이즈가 생기면 글자가 먼저 뭉개져 체감 품질이 급격히 떨어집니다.

그래서 화면공유는 고프레임보다 가독성이 더 중요한 경우가 많습니다.
즉, 네트워크가 불안정하면 해상도를 깎기보다 프레임을 낮추는 방향이 결과가 좋은 경우가 많습니다.

💡 contentHint 활용 팁
contentHint는 "보장"이 아니라 "힌트"입니다.
contentHint는 브라우저/인코더가 트랙의 성격을 추정하는 데 참고하는 값입니다.
환경에 따라 효과가 달라질 수 있습니다.

화면공유에서 텍스트/도형 가독성을 우선하고 싶다면 "text" 또는 "detail"을 고려할 수 있습니다.

다자간(SFU) 통화는 전송 전략이 더 중요해집니다

SFU 방식의 다자간 통화에서는 코덱 선택만큼이나 누구에게 어떤 품질을 보낼지가 핵심입니다.

1:1에서 좋았던 고화질 단일 스트림 설정이 다자간에서 흔들리는 이유는 간단합니다.

  • SFU 구조에서는 보통 각 참가자가 SFU로 한 번 업로드하고, SFU가 다른 참가자에게 선별적으로 전달합니다.
  • 문제는 수신자마다 네트워크/기기 성능이 제각각이라는 점입니다.
    누군가는 와이파이, 누군가는 이동통신, 누군가는 저사양 기기일 수 있습니다.

이때 고화질 하나만 보내면, 느린 수신자는 끊김/프레임 드랍/강제 해상도 저하를 겪기 쉽습니다.
그래서 다자간에서는 다음 전략이 자주 쓰입니다.

  • 시뮬캐스트(Simulcast): 같은 영상을 여러 품질(예: 저/중/고)로 동시에 보내고, SFU가 수신자 상황에 맞는 레이어를 선택해 전달합니다.
    (WebRTC 표준에서도 다중 인코딩 제공을 다룹니다.)
  • SVC: 하나의 스트림을 계층적으로 쪼개(공간/시간 레이어 등), 필요 레이어만 받아 품질을 조절할 수 있게 합니다.

정리하면, 다자간 품질은 "코덱"만으로 결정되지 않고 레이어링(시뮬캐스트/SVC) + SFU의 선택/구독 정책(큰 화면/작은 화면, 발표자 우선 등)에 의해 체감이 크게 갈립니다.


차세대 코덱

AV1

2018년 Alliance for Open Media가 발표한 차세대 코덱입니다.

특징
  • VP9 대비 더 높은 압축 효율을 목표로 설계
  • 인코딩 비용이 크고, 실시간 적용은 환경(기기 성능/가속/정책) 영향이 큼
  • WebRTC에서는 "가능하면 사용" 정도로 두고 폴백을 함께 설계하는 방식이 안전합니다.

AV2

AV2는 AV1의 후속으로 개발 중인 차세대 코덱입니다.

특징
  • AV1 대비 추가 압축 효율 개선을 목표로 개발
  • AOMedia는 2025년 연말 공개(최종화) 목표를 언급해 왔고, 실제 적용 속도는 브라우저/구현체/하드웨어 생태계 진행 상황에 따라 달라질 수 있습니다.
  • 화면 콘텐츠 처리(문서/화면공유) 등 특정 시나리오 개선이 함께 언급되기도 합니다.

마무리

프롤로그에서 던졌던 질문, "왜 같은 네트워크인데 화질이 다를까?"의 답을 함께 찾아보았습니다.

코덱은 WebRTC 품질을 결정짓는 여러 변수 중 하나입니다.
같은 코덱이라도 네트워크 상태, 기기 성능, 설정 방식에 따라 결과가 달라질 수 있습니다.

실무에서는 "완벽한 코덱"을 찾기보다, 상황에 맞는 선택과 폴백 전략이 더 중요한 경우가 많습니다.
이 글이 필요하신 분들에게 도움이 되었으면 합니다.

핵심 정리

  1. chrome://webrtc-internals로 실제 동작 확인
    • 추측보다 측정이 정확합니다
    • Stats를 보면 코덱 외 병목을 빠르게 찾을 수 있습니다
  2. 환경에 따라 다른 전략
    • 모바일: H.264 (하드웨어 가속)
    • 최신 브라우저: VP9 고려 (대역폭 절약)
    • 안정성 우선: VP8 + 폴백
  3. 화면공유와 다자간은 별도 고려
    • 화면공유: 프레임보다 해상도 우선
    • 다자간: 시뮬캐스트/SVC + SFU 정책이 핵심

끝까지 읽어주셔서 감사합니다.

호환성이 최우선인 경우  
안정적인 기본 코덱이 필요한 경우  
대역폭 절약이 중요한 경우  
최신 환경(브라우저/기기) 중심인 경우  
모바일 배터리/발열이 중요한 경우  
하드웨어 가속에 기대고 싶은 경우  
레거시 호환이 중요한 경우  
전화 시스템 연동이 중요한 경우  
레거시 호환이 필요한 경우  
chrome://webrtc-internals  
inbound-rtp (video)  
├─ codecId: 사용 중인 코덱 참조(id)  
├─ frameWidth / frameHeight: 해상도  
├─ framesPerSecond: 초당 프레임 수  
└─ bytesReceived: 수신 데이터량  
{  
	"type": "codec",  
	"mimeType": "video/VP8",  
	"clockRate": 90000,  
	"payloadType": 96  
}  
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98  
a=rtpmap:96 VP8/90000  
a=rtpmap:97 VP9/90000  
a=rtpmap:98 H264/90000  
const configuration = {  
	iceServers: [{ urls: "stun:stun.l.google.com:19302" }]  
};  
const constraints = {  
	video: {  
		width: { ideal: 640 },  
		height: { ideal: 480 },  
		frameRate: { ideal: 15 }  
	},  
	audio: {  
		echoCancellation: true,  
		noiseSuppression: true  
	}  
};  
const pc = new RTCPeerConnection(configuration);

// 예: 비디오 트랜시버를 만든 뒤 선호 코덱을 정렬  
const transceiver = pc.addTransceiver("video");

const caps = RTCRtpReceiver.getCapabilities("video");  
const codecs = caps.codecs;

// VP9 → H.264 → VP8 순으로 선호  
const preferred = ["video/VP9", "video/H264", "video/VP8"];  
const sorted = codecs  
	.filter((c) => preferred.includes(c.mimeType))  
	.sort((a, b) => preferred.indexOf(a.mimeType) - preferred.indexOf(b.mimeType));

transceiver.setCodecPreferences(sorted);  
// screenTrack: getDisplayMedia()로 얻은 비디오 트랙이라고 가정  
screenTrack.contentHint = "text"; // 또는 "detail"