보트 위에서: MoQ를 이용한 대역폭 제약 환경의 라이브 스트리밍

On a Boat

요약

MoQ(미디어 오버 QUIC) 프로토콜이 위성통신 환경의 보트 같은 대역폭 제약 상황에서 9개 카메라의 라이브 스트리밍을 효율적으로 처리하는 방식을 설명한다. Pull 기반 구독 모델, 우선순위 큐잉, 멀티패스 QUIC 지원 등으로 대역폭을 최적화한다.

핵심 포인트

  • Pull 기반 구독 모델로 필요한 트랙만 전송하여 대역폭 절약 (WebRTC 등 push 기반 프로토콜과 차이)
  • 우선순위 기반 패킷 전송과 백필 지원으로 실시간 스트림과 VOD를 동시에 최적화
  • QUIC 멀티패스로 위성, 셀룰러, WiFi 등 다중 경로 동시 사용 가능

왜 중요한가

대역폭 제약이 있는 엣지 환경에서 안정적인 라이브 스트리밍 솔루션이 필요한 개발자에게 중요하다.

📄 전문 번역

보트에서의 라이브 스트리밍: MoQ가 답일까?

2026년 2월 26일, 한 척의 보트에서

Saronic이 MoQ를 써온 경험에 대해 블로그를 썼다. 꼭 읽어보길 바란다.

나도 이제 해상 통신에 대해 얘기할 수 있어서 신난다.

대역폭의 제약

상황을 한번 생각해보자.

보트에 타고 있다. 시속 엄청 빠르게 나간다. 카메라가 9개나 달려있는데, Starlink 비용이 비싸다. 아, 진짜.

9개 카메라에서 Full HD 스트림을 계속 보내는 건 현실적이지 않다. 비용을 감당할 수 있다고 해도, 보트라는 환경이 문제다. 대역폭은 들쑥날쑥하고, 카메라 피드도 자주 끊어진다.

기존 스트리밍 프로토콜들(WebRTC, SRT, RTSP, RTMP)은 모두 푸시(Push) 방식이다. 보안 카메라 같은 발행자가 서버로 모든 데이터를 계속 쏟아낸다. 보트 같은 환경에선 정말 안 좋다.

그런데 MoQ는 풀(Pull) 방식이다.* 우리는 미디어 퍼블리싱 세계의 못난 오리 같은 존재다.

*엄밀히 말하면, IETF 표준에서 선택적인 PUBLISH 메시지를 추가해서 양쪽 다 가능하게 만들긴 했다. 하지만 나는 그걸 쓰지 말 것을 강력히 권한다. 이유는 아래에 있다.

기본부터 시작하자

MoQ 방송은 "트랙(track)"이라는 라이브 스트림으로 나뉜다. 어떻게 나눌지는 전적으로 애플리케이션 몫이다.

예를 들어 hang.live는 이렇게 나눴다:

  • 1080p
  • 360p
  • 오디오
  • 자막
  • 채팅
  • 기타 등등

MoQ 뷰어는 각 트랙을 명시적으로 구독(SUBSCRIBE)해야만 전송된다. 그 외엔 아무것도 안 간다.

이게 정말 좋은 점이다. 이제 트랙은 선택 사항이 된다. 창을 최소화했다? 지원 안 하는 코덱? 화면이 작다? 그럼 1080p를 구독하지 마. 끝.

단일 뷰어의 경우

100명이 1080p를 구독하면?

이때 moq-relay가 영웅처럼 등장한다. 100개의 요청을 하나로 통합해서 상위 서버에 1080p 한 번만 구독한다. 보트의 대역폭은 안전해진다. 각 트랙은 최대 한 번만 전송된다.

대규모 시청자의 경우

100,000명이 1080p를 구독하면?

relay 클러스터를 구성하면 된다. 전 세계에 배치하면 갑자기 글로벌 CDN이 된다. 이건 HTTP CDN과 정확히 같은 개념인데, 라이브 스트림 버전일 뿐이다.

MoQ가 표준화되는 이유가 바로 이거다. Cloudflare 같은 CDN으로 세계 규모로 확장하려고. 아니면 Saronic처럼 moq-relay를 직접 호스팅해서 네트워크 내에만 두는 선택도 있다.

변환 버전(Renditions)

회의적인 사람이 이렇게 물을 수 있다.

"나는 뷰어가 하나뿐인데, 대규모 팬아웃이 왜 필요해?"

좋은 질문이다. 렌디션을 얘기해보자.

새로운 시대에는 사람이 아니라 AI 모델을 던진다. AI는 모든 카메라의 360p 스트림을 구독해서 이상을 감지한다. 크래켄 공격이라든지 뭐 그런 거. 난 항해를 안 해서 정확히는 모르겠지만.

기본적으로 각 카메라의 360p 스트림만 전송된다. AI가 우측현에서 크래켄을 감지하면, 그 카메라의 1080p 스트림을 구독한다.

대역폭 부족 시 우선순위

대역폭이 부족해서 모든 걸 다 보낼 수 없다면?

그건 너의 선택이다. 모든 MoQ 구독은 우선순위를 갖고 있어서, 하나의 연결을 공유하면서도 서로 협력할 수 있다.

크래켄 영상이 필요한가? 우선순위를 10으로 설정하자. 보트 침몰은 피하고 싶은가? 정면 카메라를 5로. 오디오가 필요한가? 글쎄, 항해를 안 해서 모르겠지만, 15로 설정해 봐.

QUIC 라이브러리가 지정된 우선순위에 따라 패킷을 전송한다. 이 예시에선 오디오 → 크래켄 → 정면 카메라 → 기타 순서로.

이건 모두 최선의 노력(best-effort) 방식이라서, 대역폭이 너무 낮으면 우선순위가 낮은 패킷은 큐에 들거나 버려질 수 있다. 뭔가는 버려져야 하지만, 우리는 중요한 것부터 보내려고 최선을 다한다. 제발 크래켄이기를.

프레임 백필(Backfill)

MoQ의 또 다른 특징은 프레임을 버리지 않는다는 거다. 우선순위를 매길 뿐이다.

다시 회의적인 사람이 물었다.

"뭐라는 거야?"

자, 크래켄이 승무원과 대역폭을 다 집어삼키고 있다고 하자. 공격 경보가 울린다. 한 사람이 실시간으로 보고 싶어서 최대 지연시간을 100ms로 설정했다. 프레임이 그보다 오래 걸리면 넘어간다. 빙글빙글 도는 로딩 표시는 보기 싫으니까.

하지만 동시에 사후 분석용으로 영상을 녹화하는 VOD 워커도 있다. 얘는 30초 정도의 지연을 감당할 수 있다.

보통 WebRTC라면 100ms 후에 프레임을 버렸을 것이다. 그런데 MoQ는 안 버린다. 대신 우선순위를 낮춰서 새로운 프레임부터 보내되, 버려진 프레임을 RAM에 계속 둔다.

크래켄이 결국 배를 터고 떠날 거라고 본다. 상황이 정상화되면 30초 마감 전에 여유 대역폭으로 VOD를 백필할 수 있을지도 모른다.

결과? 실시간 라이브는 손실이 있고, VOD는 완벽하다. 한 명의 뷰어가 실시간 지연을 원한다고 해서 나머지 모두가 고통받을 필요는 없다. 진짜 대단한 기능이다.

다중 경로 연결(Bonded Pairs)

해안 근처에 있으면?

위성 연결에 더해 셀룰러 네트워크도 쓸 수 있을까?

당연하지, 이건 수사 질문이 아니라 당연한 거다.

QUIC는 경로 마이그레이션을 지원한다. 여러 경로 사이를 매끄럽게 전환할 수 있다(능동-대기 모드). Wifi에서 셀룰러로, 셀룰러에서 위성으로 전환해도 QUIC 연결은 끊어지지 않는다. TCP와 달리.

또한 다중 경로 확장도 있어서 여러 경로를 동시에 사용할 수도 있다(능동-능동 모드). 시도해보고 싶다면, iroh 팀이 방금 출시했다...