• 로그인
  • 장바구니에 상품이 없습니다.

유튜브의 스트리밍 최적화 기술




유튜브라는 사이트는  

단순히 동영상을 올리고 동영상을 보여주는 게시판 아니겠습니까?

그게 다예요.

그래서 동영상 업로드 페이지 하나 만드시고 

거기에 누가 동영상을 올리면 그걸 어딘가 저장해뒀다가

유저들이 그 동영상을 요청하면 html video 태그 만들고

거기에 mp4 동영상을 넣어서 보여주면 됩니다.

그게 구현 끝이에요. 

사이트에 유저가 별로 없으면 그렇게 해도 전혀 상관이 없는데 

유튜브는 27억명의 유저가 하루에 평균 30분씩 영상을 재생하기 때문에

그렇게 대충하면 트래픽비용으로 엄청난 적자가 발생합니다.

그래서 좀 다른 방법이 필요합니다. 


다양한 화질로 인코딩

일단 유튜브에는 화질설정 부분이 있습니다.

720으로 설정하면 720사이즈의 영상이 전송이되는 기능입니다.

근데 유저가 1080 사이즈의 영상을 업로드했는데

720사이즈의 영상을 보내려면 어떻게하게요? 

실시간으로 변환하고 그런게 아니라 미리 720사이즈로 영상을 축소해둬야합니다.

그래서 일단 영상을 업로드받으면

CPU나 GPU를 갈궈서 영상을 여러 화질로 리사이즈를 해둬야하고요. 

그런건 어도비 미디어 인코더를 쓰는게 아니라

개발할 때는 ffmpeg 이용하거나 돈내고 클라우드 서비스를 이용하면 되겠습니다. 

참고로 ffmpeg이라는 오픈소스 소프트웨어가 없어지면 인터넷 세상은 멸망함

아무튼 그렇게 해두면 모바일 유저에게는

작은 사이즈의 영상을 보내줄 수 있기 때문에 상당한 트래픽을 절약할 수 있습니다. 



압축형식

하지만 여기서 끝이 아닙니다. 

요즘은 대부분 고화질 영상을 원하기 때문에 영상을 리사이즈해뒀다고 트래픽이 절약되진 않습니다. 

그래서 동영상 용량을 압축하는 방법도 있습니다.

유튜브에선 주로 VP9 아니면 AV1같은 코덱을 사용해서 동영상을 압축합니다. 

특히 av1, 얘네들은 마법같은 알고리즘을 사용해서 압축을 해주기 때문에 

역사와 전통의 h264형식에 비해서

30% 더 적은 용량으로 영상을 압축할 수 있습니다.

하지만 av1 형식으로 압축을 해놨으면 영상을 보는 유저 입장에서도

av1형식을 디코딩할 수 있는 소프트웨어나 하드웨어를 가지고 있어야 영상 재생이 가능하기 때문에

그게 없으면 역사와 전통의 h264같은 형식으로 보내줘야 합니다. 

그래서 미리 여러 가지 버전으로 영상들을 인코딩 해두고요.

그래서 유튜브에 업로드하시면 영상을 최소 이 정도로 인코딩을 미리 해놔야하기 때문에

영상 처리하는데 몇분이나 걸리게 됩니다.

요즘은 자동으로 외국어 더빙 해준다고 몇분이 더 소요됩니다.



manifest

하지만 여기서 끝이 아닙니다.

유저들은 영상을 처음부터 끝까지 얌전하게 보지 않습니다.

누구는 영상을 초반에만 잠깐 보고 꺼버리고

누구는 갑자기 중간부터 영상을 재생해 버립니다.

그래서 영상 전체를 보내 버리면 트래픽 낭비가 굉장해질 수 밖에 없기 때문에 

그걸 막고 싶으면 영상을 잘게 쪼개놓고

필요한 부분만 그때그때  보내는 방식을 사용합니다.

어떤 방법을 사용하냐면 HLS나 DASH같은 기술이 있습니다.

두 개는 비슷한데 가장 많이 쓰는 HLS기준으로 설명을 드리자면 

일단 동영상 시청하는 페이지에 들어오면 영상이 가장 먼저 다운되는게 아니라 

문서가 하나 도착합니다.

지금 동영상에 어떤 사이즈와 어떤 포맷들이 있는지 전부 적어놓은 master playlist라는 문서입니다.

거기서 어떤 사이즈와 어떤 포맷의 영상이 좋을지 선택을 해요.

자바스크립트로 현재 화면 사이즈같은걸 검사해보고

최적의 영상을 선택하는 로직을 짜면 되겠죠?

그래서 1080사이즈의 av1 영상이 좋을 것 같으면 그걸 달라고 서버에 요청하면 됩니다. 

근데 그러면 또 영상이 전송되는게 아니라 문서가 하나 더 전송 됩니다. 

media playlist라는 문서인데

거기엔 몇초단위로 잘게 쪼갠 동영상들이

어떤 경로에 있는지 주소가 쭉 적혀있습니다.

그래서 그걸 차례로 가져오라고 자바스크립트로 코드 짜면 되는 거예요.

근데 유저가 갑자기 중간 부분에서 재생을 원하면 어떻게 하게요? 

그 부분은 어떤 주소에 있는지 media playlist에서 찾아본 다음에

그 영상을 가져오면 되는 거예요.

직접 코드 짜기 귀찮으면 자동으로 구현해 주는

hls.js dash.js 라이브러리도 있습니다. 

동영상 플레이어 라이브러리도 그런 역할을 해줄 수 있고요. 

영상을 잘게 쪼개려면 ffmpeg 사용하면 쉽게 가능합니다.

playlist 생성도 해줌


CDN 캐싱

하지만 여기서 끝이 아닙니다.

영상을 한국에만 보관하면 

다른 나라 사람이 그걸 조회했을 때 지연 시간이 너무 많이 발생할 수 있기 때문에 

보통 영상들을 전세계 데이터센터에 복제해 둡니다.

예를 들어 미국에 있는 사람이 한국에 저장된 영상을 조회하면

한국에서부터 영상을 다운로드 해 올 겁니다.

근데 그걸 미국 데이터센터에 캐싱 해두면

이제 다른 미국사람이 이걸 요청할 때는

한국이 아니라 미국에서 영상을 전송 받을 수 있으니까 매우 빠르게 동작할 겁니다. 

이런건 CDN 서비스를 쓰면 자동으로 해주니까 궁금하면 한번 찾아보십시오.


실제 유튜브 연구결과

하지만 여기서 끝이 아니구요 

유튜브 사이트를 약간 분석해보면 뭔가 이상한걸 볼 수 있습니다. 

영상에 있는 플레이 헤드를 여기저기 옮겨보면

용량이 상당한 동영상 데이터를 그때그때 받아 오는걸 확인할 수는 있는데 

근데 동영상을 가져오기 위한 URL같은게 바뀌는게 없어요. 

그리고 manifest파일이나 xml 같은 것도 받아오지 않습니다.

아마 hls 아니면 dash와 비슷하게 동작하도록

기술을 직접 구현해서 사용하는 것으로 보입니다.

얘네는 동영상을 가져오기 위해 수상한 정보들을 서버로 전송하고 있습니다. 

아마 이 안에 무슨 사이즈의 무슨 코덱의 몇번째 영상을 가져오는지 기록이 되어있는 것 같습니다.

근데 뭔가 안 보이게 암호화해놓은 거 같고요.

이건 쉽게 디코딩해볼 수 있는데 

왜냐면 구글이 내부적으로 사용하는 자료형식이 있습니다.

protobuf 라고 부르는건데 

데이터를 많이 압축하려고, 일반 문자나 JSON 형식대신 사용하는 경우들이 있습니다.

그래서 protobuf 로 압축을 해놓은거같습니다. 

그래서 이걸 har파일 같은걸로 다운로드하고 protobuf 변환 툴같은게 있습니다.

이런 걸로 분석을 해보면 어떤 데이터가 전송되는지 훔쳐볼 수 있습니다.

영상을 보낼 때마다 위 사진과 같은 이상한 데이터가 구글 서버로 전송되는걸 알 수 있는데

protobuf를 쓰면 이게 무슨자료인지 이름이 생략되어있습니다.

그래서 값만 가지고 추론해야되는데 잘 보면 1080같은 현재 사이즈 설정같은 부분도 있고요.

그럼 그 사이즈 영상만 다운로드 해오겠죠?

그리고 재생 위치를 옮길 때 마다 이런 값이 계속 변동하고 있습니다.

이건 몇번째 동영상 세그먼트를 가져올지 결정하는 부분 같습니다.

아무튼 이런 형태로 비디오 스트리밍 기술을 구현해놓은걸 약간의 리버스엔지니어링 비슷한 것으로 훔쳐볼 수 있습니다.



결론

실제 유튜브 사이트는 수많은 기능들이 더 필요하겠지만 

핵심적인 시스템 디자인은 이렇게 된다고 보시면 됩니다.

여러분만의 비밀 동영상 사이트가 필요하면 이걸로 직접 만들 수도 있고

아니면 회사에서 갑자기 스트리밍 서비스를 만들라고 하면 도움이 될 수도 있을 것 같네요.




2025년 11월 13일

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠