유튜브라는 사이트는 단순히 동영상을 올리고 동영상을 보여주는 게시판 아니겠습니까.
그걸 만들고 싶으면
1. 동영상 업로드 & 저장 기능
2. 유저들이 그 동영상을 요청하면 html 파일에 동영상을 넣어서 보여주기
이 정도만 만들면 구현 끝입니다.

사이트에 유저가 별로 없으면 그렇게 해도 전혀 상관이 없는데
유튜브는 27억명의 유저가 하루에 평균 30분씩 영상을 재생하기 때문에
그렇게 대충하면 트래픽비용으로 엄청난 적자가 발생합니다.
그래서 좀 다른 방법이 필요합니다.
인코딩
일단 유튜브에는 화질설정 부분이 있습니다.
720으로 설정하면 720 사이즈의 영상이 전송이되는 기능입니다.

근데 유튜버가 1080 사이즈의 영상을 업로드했는데
720 사이즈의 영상을 보내려면 어떻게하게요?
실시간으로 변환하고 그런게 아니라
미리 720 사이즈로 영상을 축소해둬야합니다.

그래서 일단 영상을 업로드받으면 CPU나 GPU를 갈궈서 영상을 여러 화질로 리사이즈를 해둬야하고요.
그런건 어도비 미디어 인코더를 쓰는게 아니라
개발할 때는 ffmpeg같은 프로그램을 이용하거나 돈내고 클라우드 서비스를 이용하면 되겠습니다.
참고로 ffmpeg 없어지면 인터넷 세상은 멸망합니다.

아무튼 그렇게 해두면 모바일 유저에게는
작은 사이즈의 영상을 보내줄 수 있기 때문에 상당한 트래픽을 절약할 수 있습니다.
압축형식
하지만 여기서 끝이 아닙니다.
요즘은 대부분 고화질 영상을 원하기 때문에 영상을 리사이즈해뒀다고 트래픽이 절약되진 않습니다.
그래서 동영상 용량을 압축하는 방법도 있습니다.
유튜브에선 주로 VP9 아니면 AV1같은 코덱을 사용해서 동영상을 압축합니다.

특히 AV1은 마법같은 알고리즘을 사용해서 압축을 해주기 때문에
역사와 전통의 h.264형식에 비해서 30% 더 적은 용량으로 영상을 압축할 수 있습니다.

하지만 AV1 형식으로 압축을 해놨으면 영상을 보는 유저 입장에서도
AV1형식을 디코딩할 수 있는 소프트웨어나 하드웨어를 가지고 있어야 영상 재생이 가능하기 때문에
그게 없으면 역사와 전통의 h.264같은 형식으로 보내줘야 합니다.

그래서 미리 여러 가지 버전으로 영상들을 인코딩 해두어야 합니다.
그래서 유튜브에 영상을 업로드하면 영상 처리하는데 몇분이나 걸리는 이유가 있습니다.
요즘은 심지어 AI로 더빙해준다고 처리시간이 몇십분이나 더 걸림
HLS, DASH
하지만 여기서 끝이 아닙니다.
유저들은 영상을 처음부터 끝까지 얌전하게 보지 않습니다.
누구는 영상을 초반에만 잠깐 보고 꺼버리고
누구는 갑자기 중간부터 영상을 재생해 버립니다.
그래서 영상 전체를 보내 버리면 트래픽 낭비가 굉장해질 수 밖에 없기 때문에

그걸 막고 싶으면 영상을 잘게 쪼개놓고
필요한 부분만 그때그때 보내는 방식을 사용합니다.
어떤 방법을 사용하냐면 HLS 아니면 DASH같은 기술이 있습니다.
두 개는 비슷한데 가장 많이 쓰는 HLS기준으로 설명을 드리자면

일단 동영상 시청하는 페이지에 들어오면 영상이 가장 먼저 다운되는게 아니라
.m3u8 문서가 하나 도착합니다.
지금 동영상이 어떤 화질과 코덱 버전이 있는지 전부 적어놓은 master playlist라는 문서입니다.
아까 다양한 화질과 코덱 인코딩해놓은 정보들 그대로 기록해놓은 파일입니다.
(그래서 인코딩할 때 함께 보통 생성합니다)

우선 자바스크립트로 그 파일을 읽어보고 어떤 사이즈와 어떤 포맷의 영상을 재생하는게 좋을지 선택을 하면 되겠습니다.
자바스크립트로 현재 화면 사이즈같은걸 검사해보고 최적의 영상을 선택하는 로직을 짜면 되겠죠?
그래서 1080사이즈의 AV1 영상이 좋을 것 같다고 판단했으면
그걸 달라고 서버에 요청하면 됩니다.

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

거기엔 몇초단위로 잘게 쪼갠 동영상들이
어떤 경로에 있는지 주소가 쭉 적혀있습니다.
그래서 그걸 차례로 가져오라고 자바스크립트로 코드 짜면 되는 것입니다.
사진에서는 실제로 .ts로 되어있는 비디오 조각들을 가져와서 재생해주는 걸 볼 수 있습니다.

근데 유저가 갑자기 중간 부분에서 재생을 원하면 어떻게 하게요?
그 부분은 어떤 주소에 있는지 media playlist에서 찾아본 다음에
그 영상을 가져오면 되는 것 입니다.
직접 코드 짜기 귀찮으면 자동으로 구현해 주는 hls.js dash.js, 동영상플레이어 라이브러리도 있습니다.

ffmpeg 사용하면 영상을 쪼개주고 playlist까지 알아서 생성해줍니다.
CDN 캐싱
하지만 여기서 끝이 아닙니다.
영상을 한국에만 보관하면
다른 나라 사람이 그걸 조회했을 때 지연 시간이 너무 많이 발생할 수 있기 때문에
보통 영상들을 전세계 데이터센터에 복제해 둡니다.

예를 들어 미국에 있는 사람이 한국에 저장된 영상을 조회하면
한국에서 영상을 다운로드 해 올 겁니다.

근데 그걸 미국 데이터센터에 캐싱 해두면
이제 다른 미국사람이 이걸 요청할 때는
한국이 아니라 미국에서 영상을 전송 받을 수 있으니까 매우 빠르게 동작할 겁니다.
이런건 CDN 서비스를 쓰면 자동으로 해주니까 궁금하면 한번 찾아보십시오.
가격도 요즘은 경쟁 덕분인가 굉장히 저렴한데
예를 들어 겨우 5달러에 동영상 1TB 전송량을 제공하는 곳들도 있습니다.
그럼 대충 라프텔같은 사이트를 만든다고 했을 때
애니 1편을 1GB라고 넉넉하게 잡으면 유저가 1천편을 봐야 5달러 요금이 발생합니다.
그럼 월 회원권을 5달러에 팔아도 이론상 유지가 되지않을까 싶습니다.
실제 유튜브는 어떤 기술을 쓰나

하지만 여기서 끝이 아닙니다.
유튜브 사이트를 약간 분석해보면 뭔가 이상한걸 볼 수 있습니다.
영상에 있는 플레이 헤드를 여기저기 옮겨보면
용량이 상당한 동영상 데이터를 그때그때 받아 오는걸 확인할 수는 있는데
근데 동영상을 가져오기 위한 URL같은게 바뀌는게 없어요.
그리고 .m3u8 manifest파일이나 xml 같은 것도 받아오지 않습니다.

하지만 비디오 조각들을 결국 받아오는걸 보아하니
메모리 상에서 HLS 아니면 DASH와 비슷하게 동작하도록 기술을 직접 구현해서 사용하는 것으로 보입니다.
사람들이 잘 알고 있는 .m3u8 파일을 노출시키면 오프라인 비디오 무단수집도 쉬워져서 그럴 것 같기도 합니다.

동영상을 가져오기 위해 수상한 정보들을 서버로 전송하는 부분도 있습니다.
아마 이 안에 무슨 사이즈의 무슨 코덱의 몇번째 영상을 가져오는지 기록이 되어있는 것 같습니다.
근데 뭔가 안 보이게 암호화해놓은 거 같지만 이건 쉽게 디코딩해볼 수 있는데
왜냐면 구글이 내부적으로 사용하는 protobuf라는 자료형식이 있습니다.
데이터를 많이 압축하려고, 일반 문자나 JSON 형식대신 사용하는 경우들이 있는데 그걸 사용했군요.
그래서 이걸 har파일 같은걸로 다운로드하고 protobuf 변환 툴을 써보면 디코딩해볼 수 있습니다.

이런걸로 분석을 해보면 영상을 보낼 때마다 이런 숫자 데이터가 구글 서버로 전송되는걸 알 수 있고요.
다만 protobuf를 쓰면 이게 무슨 자료인지 이름이 생략되어있습니다.
그래서 값만 가지고 추론해야되는데 잘 보면 1080 같은 현재 사이즈 설정같은 부분도 있고요.

그리고 재생 위치를 옮길 때 마다 이런 값이 계속 변동하고 있습니다.
이건 몇번째 동영상 세그먼트를 가져올지 결정하는 부분 같습니다.
아무튼 크롬 개발자도구 볼 줄 알면 이런 형태로 비디오 스트리밍 기술을 구현해놓은걸 약간 배워볼 수 있습니다.
결론
실제 유튜브 사이트는 수많은 기능들이 더 필요하겠지만
핵심적인 백엔드 시스템 디자인은 이렇게 된다고 보시면 됩니다.

여러분만의 비밀 동영상 사이트가 필요하면 이걸로 직접 만들 수도 있고
아니면 회사에서 갑자기 스트리밍 서비스를 만들라고 하면 약간의 팁이 될 수도 있지 않을까요.