멀티뷰 크롬 확장 3편 — 화질의 벽, 싱크 맞추기, GitHub 배포 (2026)

멀티뷰 크롬 확장을 만들면서 1편에서는 유튜브를, 2편에서는 치지직·SOOP·트위치를 한 화면에 붙였다. 3편은 그 뒤에 남아 있던 문제 세 가지를 하나씩 정리한 기록이다. 어떤 문제가 있었고 어떻게 고쳤는지, 그리고 만든 걸 GitHub에 올려 다른 사람도 쓸 수 있게 공유하기까지의 과정을 남긴다.

목차

출발점: 남아 있던 문제 셋

2편까지 오니 경기와 편파중계를 한 화면에서 같이 보는 그림은 됐다(1편, 2편). 그런데 쓰다 보니 걸리는 게 세 개 있었다.

  • SOOP만 화질이 540p에서 멈춘다
  • 방송이 메인 창에만 쌓여서 모니터 두 개로 못 나눈다
  • 같은 경기인데 방송마다 장면이 몇 초씩 어긋난다

이번 편은 이 셋을 순서대로 건드린 기록이다.

문제 1 — SOOP 화질이 540p에서 안 올라간다

시도한 것들

먼저 SOOP이 주는 화질 목록을 찾았다. 방송 정보 응답에 VIEWPRESET이 있었고 sd(360)·hd(540)·hd4k(720)·original(1080)이 적혀 있었다. 그래서 가장 높은 original을 요청했는데, 실제 재생 해상도를 찍어보니 960×540이었다. 1080을 달라고 했는데 540이 온 것이다.

[MultiPiP] SOOP 시도: original (1080p 요청) → 실제 540p
[MultiPiP] SOOP 시도: hd4k (720p 요청) → 실제 540p

로그인 상태가 안 실려서인가 싶어 SOOP 로그인 쿠키를 읽어 요청에 직접 붙여봤다. 쿠키가 정상적으로 들어갔는데도 540p 그대로였다. 다음엔 SOOP 공식 플레이어를 그대로 끼워봤는데, 이번엔 “브라우저 권한 차단” 안내가 떴다. 확장 프로그램 안에서는 그 플레이어가 필요한 권한을 못 써서 화질 담당 부분이 아예 작동하지 않았다.

원인과 결론

원인은 우리 코드가 아니었다. 같은 증상이 외부 도구에서도 동일하게 보고되고 있었다. SOOP은 한국 IP에서 그리드 네트워크(고화질 스트리머 설치)를 거치지 않은 외부 재생을 540p로 제한한다. 1080p 라벨이 붙어 있어도 실제 데이터는 540p로 내려온다.

그래서 깔끔한 540p가 이 방식의 천장이라고 결론 내렸다. 대신 방송이 720p를 열어주면 자동으로 잡도록, 높은 화질부터 실제로 틀어보고 많이 깎이면 한 단계 낮추는 방식으로 고쳤다. 1080p는 정책이라 포기했다. 아쉽지만 못 뚫는 건 못 뚫는 거다.

문제 2 — 방송을 여러 창으로 나눌 수 없다

모니터가 두 대인데 방송이 한 창에만 쌓였다. 먼저 “새 창으로 열기”를 만들어 그리드 창을 여러 개 띄우게 했다. 그런데 확장 버튼으로 추가한 방송이 늘 메인 창에만 들어가서, 옮길 방법이 없다는 문제가 다시 생겼다.

창 간 이동으로 해결

그래서 각 방송에 이동 버튼을 달고, 누르면 어느 창으로 보낼지 목록이 뜨게 고쳤다. 창끼리 서로를 인식하고 방송을 주고받는 건 BroadcastChannel로 처리했다. 창마다 번호(#1, #2)가 붙어서 원래 창으로 되돌리거나 세 번째 창으로 넘기는 것까지 된다. 여기에 방송 구성과 배치를 이름 붙여 저장하고 그대로 불러오는 기능을 더했다. 한 번 세팅해두면 다음엔 불러오기 한 번으로 복원된다.

문제 3 — 방송끼리 싱크가 안 맞는다

같은 경기를 여러 곳에서 트니 장면이 몇 초씩 어긋났다. SOOP이 유독 빨랐다. 찾아보니 플랫폼마다 지연이 다르고 실시간으로 변한다. SOOP은 저지연이라 앞서고, 유튜브 라이브가 보통 가장 느리다. 게다가 소스마다 공통 시계가 없어서 프로그램이 “지금 같은 장면”이라고 판단할 기준 자체가 없다.

그래서 자동 싱크는 포기하고 수동으로 우회했다. 각 방송에 지연 조절(−/+)을 달아, 빠른 방송을 뒤로 밀어 느린 쪽에 눈으로 맞추게 했다. 여기서 하나 알게 된 건, 느린 방송을 앞으로 당길 수는 없다는 점이다. 아직 오지 않은 화면을 미리 볼 수는 없으니, 기준은 항상 제일 느린 방송이고 빠른 쪽을 늦추는 방향만 가능하다. 지연을 넣을 여유를 만들려고 지난 구간을 60초까지 들고 있도록 버퍼도 늘렸다.

완벽하진 않다. 초 단위 눈맞춤이라 프레임까지 맞지는 않고, 오래 보면 가끔 다시 조정해야 한다. 그래도 경기 장면이 대충 겹치니 볼 만해졌다.

어떻게 시켰나 — 프롬프트로 진행한 과정

이번에도 코드를 직접 친 게 아니라 코딩 에이전트(Claude)에게 말로 시켜서 진행했다. 특히 화질 문제는 “증상 → 조사 → 로그 확인”의 반복이었다.

  1. 증상 보고 — “SOOP 화질이 540p에서 안 올라가.” → 화질 목록부터 찾게 했다.
  2. 로그 공유 — 콘솔에 찍힌 실제 해상도 값을 그대로 붙여넣었다. 요청 화질과 실제 화질이 다르다는 걸 여기서 확인했다.
  3. 가설 검증 — “로그인 쿠키를 넣어보자”, “공식 플레이어를 임베드해보자”처럼 하나씩 시켜보고 각각 왜 안 되는지 확인했다.
  4. 원인 규명 — “안 되는 이유를 끝까지 파봐”라고 시켰더니 외부 자료에서 근본 원인을 찾아냈다.
  5. 기능 요청 — “창을 분리할 수 있을까”, “원래 창으로 되돌리는 방법은?”, “싱크가 안 맞는데 방법이 없을까”처럼 쓰면서 느낀 불편을 그때그때 요청했다.

코드를 몰라도 화면에 뜬 값과 콘솔 로그를 그대로 전달하는 게 가장 빨랐다.

배포와 공유 — GitHub에 올리고 설치하기

기능이 어느 정도 찼으니 다른 사람도 쓸 수 있게 정리했다. 디버그 로그를 걷어내고 아이콘과 설치 안내를 붙이고 버전을 올렸다. 이름·설정에 개인 정보가 없도록 일반화했다.

GitHub에 올린 과정

크롬 웹스토어도 생각했지만, 비공식 API와 보안 헤더 처리 방식 때문에 심사에서 막힐 가능성이 커서 이번엔 GitHub 공개로 갔다. 순서는 이랬다.

  1. GitHub에서 새 저장소를 만든다(Public, README·라이선스는 직접 넣을 거라 체크 해제).
  2. 저장소 첫 화면의 uploading an existing file로 들어가, 확장 폴더 안의 내용 전체를 드래그해서 올리고 커밋한다. 폴더째가 아니라 내용물을 올려야 파일이 최상단에 놓인다.
  3. Settings → Pages에서 Source를 Deploy from a branch, 브랜치 main, 폴더 /docs로 지정하고 저장한다.
  4. 1~2분 뒤 https://아이디.github.io/저장소명/ 주소로 설치 안내 페이지가 뜬다.

여기서 한 번 막혔다. 빈 저장소 상태에서 업로드 주소로 바로 들어가니 “브랜치를 먼저 선택하라”는 안내가 떴다. 첫 커밋이 없어 브랜치가 없어서였는데, 저장소 첫 화면의 업로드 링크로 들어가니 정상적으로 올라갔다.

설치·공유 방법

배포 결과는 아래 두 곳이다.

쓰는 방법은 간단하다. 설치 페이지에서 확장 다운로드(.zip)를 눌러 받고 압축을 푼다. 크롬 주소창에 chrome://extensions를 입력하고 우측 상단 개발자 모드를 켠 뒤, 압축해제된 확장 프로그램을 로드합니다를 눌러 압축 푼 폴더를 고르면 끝이다. 툴바의 확장 아이콘을 누르면 멀티뷰가 열린다. 다른 사람에게 공유할 때도 설치 페이지 주소만 보내면 된다.

마무리

화질은 정책 벽에 막혀 540p가 천장이고, 싱크도 수동으로 맞춰야 한다. 비공식 API라 플랫폼이 구조를 바꾸면 또 손봐야 한다. 그래도 필요해서 만든 도구가 배포까지 갔고, 이제 주소만 보내면 다른 사람도 쓸 수 있다.

다음엔 실제로 쓰는 모습을 데모 영상으로 정리해볼 생각이다. 창마다 레이아웃을 자동으로 복원하는 것도 욕심이 난다. 만들다 막히면 또 기록으로 남기겠다.


댓글 남기기