UI 복잡 버전 234 RED→GREEN 완료(docs/UI_USECASES.md §A~§J): 라이브 테마 전환(DynamicResource 전환+ThemeResolver+HighContrast 테마, 재시작 없음), 디자인 토큰 체계·WCAG 대비 결함 5건 수정, 설정창 카테고리 내비/검색 재구성+AppConfig 40여 속성, 다운로드 관리자(속도/ETA/세그먼트맵/전체 일시정지-이어받기/CSV 내보내기/예약 게이트/중복 확인), 라이브러리·아카이브·작업공간·재생목록·즐겨찾기 편집 뷰, 접근성(자동화 속성 30여 개·커스텀 피어·docs/ACCESSIBILITY.md), 인터랙션(휠 클릭 새 탭·XButton 탐색·F12·영역 캡처·프로필 전환), 상태/알림(토스트·알림센터·온보딩·CrashReportDialog). 보강 테스트 35건+실창 E2E 4건(StaDispatcher 기반 — 프록시 설정이 기시작 핸들러를 건드리는 크래시 실결함 수정 포함) — 453/453 GREEN. 이전 미커밋 작업(CI 워크플로·Mdns·QueueHub·UpdateChecker·AGENTS/CLAUDE·빌드 스크립트) 일괄 포함
This commit is contained in:
parent
5a0ce730b2
commit
17f2f91152
88 changed files with 9463 additions and 1127 deletions
141
README.md
141
README.md
|
|
@ -1,71 +1,92 @@
|
|||
# 비디오 다운로더 (HLS / MP4)
|
||||
# VideoDownloader
|
||||
|
||||
maccms 계열 스트리밍 사이트(tvchak208 등)의 영상을 다운로드하는 도구입니다.
|
||||
HLS(`.m3u8`) 분할 재생과 직접 MP4 모두 지원합니다.
|
||||
브라우저를 내장한 데스크톱 영상 다운로더와, 같은 엔진을 공유하는 모바일 컴패니언 앱.
|
||||
|
||||
## 기능
|
||||
- **페이지 URL 자동 분석**: 재생페이지 URL만 넣으면 `player_aaaa` 설정 / 정규식 / iframe 플레이어에서 m3u8·mp4 주소를 자동 추출
|
||||
- **HLS 완전 지원**: 마스터 재생목록(최고 화질 자동 선택), **AES-128 복호화**, **fMP4(`#EXT-X-MAP`)** 초기화 세그먼트
|
||||
- **병렬 다운로드 + 이어받기**: 도중에 끊겨도 재실행 시 받은 분할은 건너뜀
|
||||
- **ffmpeg 자동 리먹스**: TS / fMP4 → MP4 (`-c copy`, 무손실·빠름)
|
||||
- **커스텀 헤더**: `--referer` 등으로 CDN 토큰 인증 대응
|
||||
앱 안의 브라우저로 사이트를 열면 재생되는 미디어(HLS `.m3u8` / DASH `.mpd` / MP4 직링크)를
|
||||
자동으로 감지해 목록에 띄우고, 쿠키·Referer 를 그대로 물려 받아 내려받는다.
|
||||
받은 영상은 내장 서버를 통해 같은 네트워크의 휴대폰에서 바로 재생하거나 저장할 수 있다.
|
||||
|
||||
## 준비
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
# ffmpeg 권장 (https://ffmpeg.org). PATH에 있으면 자동 인식됨.
|
||||
## 저장소 구조
|
||||
|
||||
| 프로젝트 | TFM | 역할 |
|
||||
|---|---|---|
|
||||
| `VideoDownloader.Core` | net8.0 | **다운로드 엔진.** HLS/DASH 파싱, AES-128 복호화, 병렬·이어받기, 미디어 감지, ffmpeg 리먹스, 플랫폼 추상화 |
|
||||
| `VideoDownloader.Browser` | net8.0-windows | WebView2 탭 컴포넌트 (응답 가로채기·쿠키 공급) |
|
||||
| `VideoDownloader.App` | net8.0-windows | **메인 WPF 앱.** 브라우저 셸 + 다운로드 UI + 서버 호스팅 |
|
||||
| `VideoDownloader.Server` | net8.0 | ASP.NET 라이브러리. App 안에서 기동되어 모바일/웹 컴패니언에 라이브러리·스트리밍 API 제공 |
|
||||
| `VideoDownloader.Mobile` | net10.0-android (+ios on macOS) | MAUI 컴패니언 앱 |
|
||||
| `VideoDownloader.Mobile.Core` | net8.0 | 모바일 공용 로직. UI 없이 테스트 가능하도록 분리 |
|
||||
| `VideoDownloader.Avalonia` | net8.0 | macOS/Linux 크로스플랫폼 셸 (진행 중 — `docs/DEPLOYMENT_PLAN.md` Gate #1' 참고) |
|
||||
| `VideoDownloader.Cli` | net8.0 | 엔진 검증용 개발 도구 (`--dashparse` 등) |
|
||||
| `VideoDownloader.Tests` | net8.0-windows | xUnit 전체 테스트 (Core/App/Server/Mobile.Core + E2E) |
|
||||
|
||||
그 밖에:
|
||||
|
||||
- `build/` — 배포 스크립트. `publish.ps1`(Windows 설치자), `installer.iss`(Inno Setup), `remote/`(맥·리눅스 원격 빌드)
|
||||
- `docs/` — 기획·감사 문서
|
||||
- `.env.example` — 배포/원격빌드 자격 증명 템플릿. `.env` 로 복사해 채운다 (`.env` 는 커밋되지 않음)
|
||||
|
||||
## 개발 환경
|
||||
|
||||
- **.NET 8 SDK** + **.NET 10 SDK** (모바일 및 Avalonia 12 가 10 을 요구)
|
||||
- Windows 11 (데스크톱 앱은 WPF + WebView2 기반이라 Windows 전용)
|
||||
- **ffmpeg** — PATH 에 있으면 자동 인식. 없으면 리먹스 단계에서 실패
|
||||
- 모바일 빌드 시: `dotnet workload install maui-android` (iOS 는 macOS 빌드머신에서만)
|
||||
|
||||
## 자주 쓰는 명령
|
||||
|
||||
```powershell
|
||||
# 테스트 — 가장 먼저 이걸로 상태 확인 (Mobile 제외 전 영역 커버)
|
||||
dotnet test VideoDownloader.Tests
|
||||
|
||||
# 데스크톱 앱 빌드 / 실행
|
||||
dotnet build VideoDownloader.App
|
||||
dotnet run --project VideoDownloader.App
|
||||
|
||||
# 엔진 단독 검증
|
||||
dotnet run --project VideoDownloader.Cli -- --dashparse "https://.../manifest.mpd"
|
||||
|
||||
# 모바일 (Android 워크로드 필요)
|
||||
dotnet build VideoDownloader.Mobile -f net10.0-android
|
||||
```
|
||||
|
||||
## 사용법
|
||||
> 솔루션 전체 빌드(`dotnet build VideoDownloader.slnx`)는 MAUI 워크로드가 설치돼 있어야 통과한다.
|
||||
> 워크로드 없이 작업할 때는 프로젝트를 개별 지정한다.
|
||||
|
||||
### 1) 가장 간단 — 페이지 URL만
|
||||
```bash
|
||||
python downloader.py "https://tvchak208.com/index.php/vod/play/id/123367/sid/1/nid/1.html" -o 영상제목
|
||||
## 배포
|
||||
|
||||
```powershell
|
||||
# Windows 설치자 (x64 + arm64) → out/VideoDownloader-Setup-{arch}.exe
|
||||
./build/publish.ps1 -Config Release -Version 1.0.0
|
||||
|
||||
# macOS / Linux 원격 빌드 (.env 의 빌드머신 자격 증명 사용) → out/remote/<rid>/
|
||||
bash build/remote/build-remote.sh all
|
||||
```
|
||||
|
||||
### 2) m3u8 주소를 직접 넘기기 (가장 확실, 아래 참고)
|
||||
```bash
|
||||
python downloader.py "https://cdn.example.com/.../index.m3u8" -o 영상제목 --referer "https://tvchak208.com/"
|
||||
```
|
||||
`out/`, `publish/` 는 산출물 디렉터리라 커밋되지 않는다.
|
||||
|
||||
### 3) 추가 헤더가 필요한 경우
|
||||
```bash
|
||||
python downloader.py "https://.../index.m3u8" -o 영상제목 \
|
||||
--referer "https://tvchak208.com/" \
|
||||
-H "Origin: https://tvchak208.com"
|
||||
```
|
||||
### CI (GitHub 공개 후)
|
||||
|
||||
옵션 요약
|
||||
| 옵션 | 설명 |
|
||||
`.github/workflows/release.yml` — 태그(`v*`) 푸시 시 테스트 관문 통과 후
|
||||
Windows 설치자(x64/arm64)·Linux/macOS tar.gz·Android APK 를 빌드해 **Draft Release** 로 올린다
|
||||
(QA 후 수동 Publish). macOS 서명·공증(D4)과 iOS TestFlight(D5)는 Apple Developer Program
|
||||
가입 + 시크릿 등록 후 활성화한다 — 상세는 `docs/DEPLOYMENT_PLAN.md` §5·§7.
|
||||
|
||||
Android 자동 업데이트는 [Obtainium](https://github.com/ImranR98/Obtainium) 을 지원한다:
|
||||
저장소 공개 후 `build/obtainium.json` 의 `<owner>/<repo>` 를 치환하고, 폰에서
|
||||
`obtainium://add/https://github.com/<owner>/<repo>` 링크 한 번으로 등록된다.
|
||||
|
||||
앱 내 업데이트 확인(데스크톱)은 설정 → "앱 업데이트"에 GitHub 저장소(`owner/repo`)를
|
||||
넣으면 GitHub Releases 최신 태그와 비교해 릴리스 페이지를 열어 준다.
|
||||
|
||||
## 문서
|
||||
|
||||
| 문서 | 내용 |
|
||||
|---|---|
|
||||
| `-o, --output` | 출력 파일명 (확장자 생략 가능, 기본 `video`) |
|
||||
| `--referer` | Referer 헤더. 403/401 날 때 페이지 주소를 지정 |
|
||||
| `-H "K: V"` | 추가 헤더 (여러 개 가능) |
|
||||
| `-c, --concurrency` | 동시 연결 수 (기본 8) |
|
||||
| `--user-agent` | User-Agent 재정의 |
|
||||
| `--keep-parts` | 병합 후 분할 임시파일 유지(디버그) |
|
||||
|
||||
---
|
||||
|
||||
## 이 사이트에서 m3u8 주소 직접 구하기 (추천)
|
||||
|
||||
페이지 자동 추출이 안 될 때(사이트마다 난독화가 다름) 가장 확실한 방법:
|
||||
|
||||
1. Chrome/Edge로 재생페이지 열기
|
||||
2. `F12` → **Network(네트워크)** 탭
|
||||
3. 필터에 **`m3u8`** 입력
|
||||
4. 영상 **재생** 버튼 클릭
|
||||
5. 목록에 뜬 `.m3u8` 요청 위에서 **우클릭 → Copy → Copy link address**
|
||||
6. 그 주소를 다운로더에 넘김:
|
||||
```bash
|
||||
python downloader.py "복사한_m3u8_주소" -o 영상제목 --referer "https://tvchak208.com/"
|
||||
```
|
||||
|
||||
> 팁: `index.m3u8`(마스터)과 `*.m3u8`(미디어)이 모두 뜰 수 있는데, 마스터를 넘겨도 **최고 화질을 자동 선택**합니다. 가장 위쪽 m3u8을 고르면 됩니다.
|
||||
> 403/401 에러가 나면 반드시 `--referer`로 재생페이지 주소를 지정하세요.
|
||||
|
||||
## 문제 해결
|
||||
- **`페이지에서 영상 주소를 찾지 못했습니다`** → 위 "m3u8 주소 직접 구하기" 방법 사용
|
||||
- **403/401** → `--referer "페이지 주소"` 추가 (필요시 `-H "Origin: ..."` 도 함께)
|
||||
- **`암호화 영상입니다. pycryptodome 필요`** → `pip install pycryptodome`
|
||||
- **MP4로 안 변환됨** → ffmpeg 설치 확인 (`ffmpeg -version`)
|
||||
| [AGENTS.md](AGENTS.md) | AI 코딩 에이전트 작업 계약 — 명령·규약·완료 기준 (사람이 읽어도 온보딩 문서) |
|
||||
| [docs/HARNESS.md](docs/HARNESS.md) | 개발 하네스 운영법 — 자동 검증 게이트, 규칙/스킬 구조 |
|
||||
| [docs/BROWSER_FEATURES_PLAN.md](docs/BROWSER_FEATURES_PLAN.md) | 데스크톱 브라우저 기능 계획 (v2) |
|
||||
| [docs/MOBILE_PLAN.md](docs/MOBILE_PLAN.md) | 모바일 앱 + PC↔모바일 연동 계획 (v1) |
|
||||
| [docs/DEPLOYMENT_PLAN.md](docs/DEPLOYMENT_PLAN.md) | Win/macOS/Linux/모바일 배포 체계 |
|
||||
| [docs/IMPLEMENTATION_AUDIT.md](docs/IMPLEMENTATION_AUDIT.md) | 계획 대비 구현 감사 |
|
||||
| [docs/BACKLOG.md](docs/BACKLOG.md) | 작업 이력 및 백로그 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue