Skip to content

feat: 영상 다운로드 플로우 개편#1

Merged
cometj03 merged 3 commits into
cometj03:mainfrom
ItzTree:feat/download-video
May 23, 2026
Merged

feat: 영상 다운로드 플로우 개편#1
cometj03 merged 3 commits into
cometj03:mainfrom
ItzTree:feat/download-video

Conversation

@ItzTree
Copy link
Copy Markdown
Contributor

@ItzTree ItzTree commented May 20, 2026

배경 / 문제

기존 다운로드 흐름은 다음 한계를 가지고 있었음.

  1. 영상 URL을 video element src에서 읽음

    • 파일명을 screen.mp4로 가정 → 실제로는 main_(uuid).mp4 등 다양
    • CDN 호스트도 ssuin-object.commonscdn.com만 가정 → 실제로는 ssu-toast.commonscdn.com 등 다양
    • HLS/blob URL (MediaSource 사용) 케이스 미지원
    • 학습기간이 마감되었거나 100% 시청된 영상은 player가 video element를 안 만들어서 못 잡음
  2. chrome.downloads.download 사용

    • Chrome 다운로드 매니저 + SafeBrowsing을 거치면서 mp4가 멀웨어로 오탐될 가능성
    • 파일명이 URL 기반 UUID로 저장되는 케이스 발생
  3. commons CDN이 Referer 검증 → extension에서 직접 fetch 시 403

변경

1. 영상 URL 캡처: video element src → background chrome.webRequest

  • background.js*://*.commonscdn.com/* mp4 요청을 가로채 tabId → URL로 캐싱
  • 인트로(/uniplayer/intro.mp4)와 본 컨텐츠(/media_files/*.mp4) URL 패턴으로 필터링
  • popup이 background에 get-captured-mp4 메시지로 조회
  • 캐시 비어있으면 content script에 trigger-autoplay 보내고 8초간 폴링

파일명/호스트/플레이어 마크업에 무관하게 동작.

2. 다운로드: chrome.downloadsshowSaveFilePicker + fetch 스트리밍

  • popup에서 사용자 user-gesture로 showSaveFilePicker 호출 (Chrome 다운로드 매니저 + SafeBrowsing 우회)
  • fetch 응답을 FileSystemWritableFileStream으로 스트리밍하여 디스크에 직접 기록 (메모리 효율 + 정확한 파일명)
  • 진행률 실시간 표시

3. Referer 우회

  • declarativeNetRequest로 commonscdn.com 요청에 Referer: https://commons.ssu.ac.kr/ 강제 set

4. 기타

  • popup 반복 호출 시 인트로 재시작 방지를 위한 autoPlayAttempted 가드
  • 다운로드 중 popup 닫으면 스트리밍 끊김 → 경고 텍스트 UI 추가 (popup auto-close는 프로그래밍적으로 방지 불가)
  • host_permissions*://canvas.ssu.ac.kr/*://canvas.ssu.ac.kr/* 보정 (webRequest 매칭용)

알려진 한계

  • popup이 file picker로 인해 자동 닫히면 다운로드 중단 — 경고 UI로 사용자에게 안내. 근본 해결은 별도 window 또는 side panel API 사용 필요
  • 같은 탭에서 module 페이지 SPA navigation 시 캐시 stale 가능성 — 현재는 canvas main_frame 로드 시점에만 클리어. 빈번한 케이스 아니면 영향 미미

Test plan

  • 서로 다른 영상 3개 이상에서 다운로드 → 받은 파일 정상 재생 (content_type / 파일명 / CDN 호스트 다양성 한 번에 검증)
  • popup 여러 번 열어도 인트로 재시작 안 됨 (autoPlayAttempted 가드)

@ItzTree ItzTree changed the title feat: 영상 다운로드 흐름 개편 feat: 영상 다운로드 플로우 개편 May 20, 2026
@cometj03 cometj03 self-assigned this May 20, 2026
@cometj03 cometj03 self-requested a review May 20, 2026 23:21
@cometj03 cometj03 removed their assignment May 20, 2026
Copy link
Copy Markdown
Owner

@cometj03 cometj03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기여 감사합니다 🙌👍

정규식 부분만 고친다면 정상적으로 동작하는 것도 확인했습니다!

Comment thread background.js Outdated
Comment thread video-iframe-listener.js Outdated
Comment thread popup/index.js
@cometj03
Copy link
Copy Markdown
Owner

cometj03 commented May 21, 2026

@ItzTree

학습기간이 마감되었거나 100% 시청된 영상은 player가 video element를 안 만들어서 못 잡음

이 경우는 제가 아직 확인을 못했는데 따로 이슈로 올려주실 수 있을까요?

Comment thread popup/index.js
await chrome.tabs.sendMessage(tab.id, { target: 'video-iframe', type: 'trigger-autoplay' });
} catch (e) { /* iframe missing — handled below */ }
const start = Date.now();
while (Date.now() - start < 8000) {
Copy link
Copy Markdown
Owner

@cometj03 cometj03 May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8초로 설정하신 특별한 이유가 있을까요?

Copy link
Copy Markdown
Contributor Author

@ItzTree ItzTree May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

첫 로딩 시 videoPlayer 초기화 + 첫 mp4 요청 발생까지의 시간과 네트워크 지연을 여유롭게 고려해서 8초로 잡았습니다.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 알겠습니다.

그런데 해당 while 문이 끝날 때까지 아래 코드가 블록되어 있어서 그동안(약 8초 동안) 학습 진도 상황이 확인중...으로 뜨는 사소한 문제가 있네요.
병렬적으로 처리하는 등의 방법으로 해결할 수 있을 것 같은데, 이 PR에서는 넘어가고 다음에 고쳐도 될 것 같습니다.

Co-authored-by: Jung Haesung <harryjung1001@gmail.com>
@ItzTree
Copy link
Copy Markdown
Contributor Author

ItzTree commented May 22, 2026

@ItzTree

학습기간이 마감되었거나 100% 시청된 영상은 player가 video element를 안 만들어서 못 잡음

이 경우는 제가 아직 확인을 못했는데 따로 이슈로 올려주실 수 있을까요?

@cometj03

  1. 100% 시청 완료 영상은 정상 동작합니다. 제가 잘못봤어요
  2. 학습기간 마감이 '열람 종료'된 영상을 의미한 것이었는데, 마감 시 LMS가 player iframe 자체를 띄우지 않고, 다른 페이지로 대체합니다. commonscdn 쪽 mp4 요청도 없어서 현재 webRequest 캡처 방식으로는 해결이 어렵습니다.

이슈 올려서 해결할 수 있는 부분은 아니라고 판단됩니다.

@cometj03 cometj03 merged commit bdc3ed8 into cometj03:main May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants