TRENDSHIFT · 2026.06.15

iptv-org/iptv 딥다이브
— 전 세계 1만 5천 개 방송 링크를 봇이 매일 점검·발행하는 거대 데이터 큐레이션 기계

iptv-org/iptv는 전 세계에 공개된 IPTV(인터넷 방송) 채널 링크를 한곳에 모아 국가·카테고리·언어·지역별로 정리한 m3u 재생목록 모음이다. 핵심은 "링크를 모았다"가 아니라, 사람이 GitHub 이슈로 제보한 링크를 봇이 매일 자동으로 수집·검증·포맷·발행하는 대규모 데이터 큐레이션 파이프라인에 있다. 영상 파일은 단 한 개도 저장하지 않고, 오직 "공개된 스트림 URL"만 큐레이션한다. (저장소: iptv-org/iptv · TypeScript + Node 22 · CC0(퍼블릭 도메인) 라이선스 · GitHub 스타 12만+ · 스트림 약 15,250개 · 국가별 m3u 324개)

이 문서는 코드 한 줄보다 "수만 개 데이터를 사람·봇·CI가 어떻게 협업해 관리하는가"라는 데이터 엔지니어링 관점에서 이 레포를 해부한다.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트
  7. 시스템 / 환경 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 레포가 무엇을 하는 물건인가.

핵심 메시지

"전 세계 흩어진 무료 방송 링크를,
사람이 제보하고 봇이 매일 검증·정리해 발행하는 공공 도서관."

당신이 VLC 같은 플레이어에 링크 하나(https://iptv-org.github.io/iptv/index.m3u)만 붙여넣으면, 전 세계 수천 개 무료 채널 목록이 펼쳐진다. iptv-org/iptv는 이 거대한 "방송 채널 주소록"을 만들고 유지하는 프로젝트다.

중요한 건 이게 단순한 텍스트 파일 묶음이 아니라는 점이다. 새 채널은 GitHub 이슈(제보) → 봇이 자동 수집 → 중복·DMCA·DB 검증 → 포맷 정리 → 공개 재생목록 생성 → GitHub Pages 발행이라는 컨베이어 벨트를 매일 자정 한 번씩 자동으로 돈다. 즉 "수만 개 데이터를 사람과 봇이 함께 굴리는 시스템"이 진짜 알맹이다.

iptv-org/iptvm3u 재생목록(playlist) 큐레이션 프로젝트다. 원천 데이터(채널 메타데이터)는 자매 레포 iptv-org/database에서, EPG(편성표)는 iptv-org/epg에서 가져온다. 이 레포가 책임지는 것은 "스트림 URL을 채널에 연결하고, 그 묶음을 국가·카테고리·언어·지역별 m3u로 발행하는 일"이다. 영상 자체는 저장하지 않으며, 라이선스도 데이터 공유에 어울리는 CC0(퍼블릭 도메인)다.

용어
m3u / m3u8 (재생목록 포맷)
#EXTM3U로 시작하는 단순 텍스트 포맷으로, "이 채널 이름 = 이 스트림 주소"를 줄줄이 나열한 목록이다. 미디어 플레이어가 이 파일을 읽어 채널 메뉴를 만든다. iptv-org가 발행하는 결과물이 바로 이 m3u 파일들이다. (.m3u8은 UTF-8 인코딩 버전으로, HLS 스트리밍에서 흔히 쓴다.)
용어
IPTV (Internet Protocol Television)
방송 전파나 케이블이 아니라 일반 인터넷망(HTTP/HLS)으로 실시간 TV를 전송하는 방식. 많은 방송사·공공기관이 자사 채널을 공개 스트림으로 인터넷에 올려두는데, iptv-org는 그 공개 링크들을 모아 정리한다.

2왜 주목받는가

트렌딩 이유 · 다른 IPTV 목록 대비 장점.

인터넷에는 "IPTV m3u 목록"이 수없이 떠돈다. 그런데 대부분은 관리되지 않는 죽은 링크 덩어리이거나, 출처가 불분명한 불법 스트림을 섞어둔 것이다. iptv-org/iptv가 12만 스타를 모은 이유는 단순 "링크가 많아서"가 아니라, 데이터를 유지·검증·발행하는 엔지니어링이 진짜 오픈소스 프로젝트처럼 돌아가기 때문이다.

비교 항목흔한 m3u 목록iptv-org/iptv
데이터 규모수백~수천, 들쭉날쭉약 15,250 스트림 · 국가별 324개 m3u
갱신 방식가끔 수동 커밋매일 자정 봇이 자동 수집·발행(cron)
품질 검증거의 없음중복·URL유효성·DB대조·DMCA/NSFW 차단목록 자동 검사
기여 절차제각각구조화된 이슈 템플릿 → 봇 자동 처리 → PR/CI 검증
분류대충 섞임국가·카테고리·언어·지역·도시 등 다축으로 자동 생성
법적 입장모호영상 미저장 · CC0 · 저작권 클레임 절차 명문화
생태계단독 파일database·epg·api·sdk·awesome-iptv 레포 군집
기존 방식의 한계
"수동으로 관리되는 링크 목록"은 반드시 썩는다

스트림 URL은 수명이 짧다. 방송사가 CDN을 바꾸거나 서비스를 닫으면 링크가 죽는다. 수동 목록은 곧 절반이 재생 불가가 되고, 중복 링크가 쌓이며, 누군가 슬쩍 불법/저작권 침해/성인 스트림을 끼워 넣어도 걸러지지 않는다. 결국 "규모가 커질수록 손으로 관리가 불가능해지는" 전형적 데이터 부패에 빠진다.

iptv-org의 해결
"사람은 제보만, 검증·정리·발행은 전부 코드로"

iptv-org는 큐레이션의 반복·기계적 부분을 전부 자동화했다. 사람은 GitHub 이슈로 "이 채널 추가/수정/문제"만 구조화된 양식으로 제보하고, 봇이 그걸 파싱해 스트림에 반영한다. 그다음 린트(m3u 형식)·검증(중복/URL/DB대조/차단목록)·포맷·생성·발행이 CI에서 자동으로 돈다. "사람의 판단이 필요한 곳에만 사람을, 나머지는 봇에게" — 대규모 데이터 큐레이션의 모범 답안이다.

3기술 스택 전체 지도

데이터 처리 엔진(스크립트)·발행(GitHub Pages)·자동화(CI) 각각.

① 데이터 처리 엔진 (백엔드 = TypeScript CLI)

이 레포에는 "서버"가 없다. 대신 한 번 실행하고 끝나는 CLI 스크립트 묶음이 데이터를 가공한다. 전부 TypeScript이고, tsx로 컴파일 없이 바로 실행한다. 명령은 commander로 정의되고 package.jsonplaylist:* 스크립트로 호출된다.

요소역할
Node.js 22 + TypeScript전체 스크립트 런타임/언어. CI도 node 22 고정.
tsxTS를 빌드 없이 즉시 실행(tsx scripts/commands/...).
commander각 명령의 인자·옵션 정의(예: 변경된 파일만 검증).
iptv-playlist-parserm3u 텍스트 → 스트림 객체로 파싱하는 핵심 라이브러리.
@iptv-org/sdk자매 데이터(channels·blocklist·guides 등) 모델·로더.
m3u-linterm3u 형식 규칙 검사(태그 순서·필드 등). 설정은 m3u-linter.json.
hls-parser / mpd-parser / mediainfo.js실제 스트림 재생 가능성·해상도 등 테스트(playlist:test).
@octokit/*GitHub API로 이슈·디스커션을 읽어 봇이 처리.
axios / socks-proxy-agent스트림 요청 · 프록시 경유 테스트.
@freearhey/core · es-toolkitCollection·Dictionary·Logger 등 유틸 · 함수형 헬퍼.

② 발행물 (프론트엔드 = 정적 m3u + README 표)

요소역할
공개 m3u 파일playlist:generate가 만드는 결과물. 국가/카테고리/언어/지역/도시별로 분리.
GitHub Pagesiptv-org.github.io/iptv/...로 m3u를 정적 호스팅(gh-pages 브랜치).
.api/streams.jsonplaylist:export 결과 → 자매 레포 iptv-org/api로 배포(JSON API).
PLAYLISTS.md각 m3u 링크와 채널 수를 담은 거대 표. readme:update가 자동 생성.
HTML 리포트report:create + core/htmlTable.ts — 테스트 결과 표.

③ 자동화 · 인프라 (GitHub Actions)

워크플로역할
update.yml★ 핵심. 매일 cron: 0 0 * * * + 수동. 이슈 반영→검증→생성→발행 전체를 돌리고 봇 계정으로 커밋·푸시·Pages 배포.
check.ymlPR이 올라오면 바뀐 streams 파일만 골라 lint+validate. 통과 못 하면 머지 불가.
format.yml내부 재생목록을 표준 형식으로 일괄 정리 후 커밋.
봇 토큰tibdex/github-app-token으로 GitHub App 토큰 발급 → iptv-bot[bot] 명의 커밋.
로컬 CI 재현gh act(act:update 등)로 Actions를 로컬에서 그대로 돌려봄.
용어
cron 스케줄 (0 0 * * *)
시간 기반 자동 실행 규칙. 0 0 * * *은 "매일 0시 0분"을 뜻한다. GitHub Actions의 schedule 트리거에 이걸 걸면, 사람이 버튼을 누르지 않아도 매일 자정에 update 파이프라인이 스스로 돈다. 이것이 "매일 갱신"의 정체다.

4아키텍처 심화 분석

제보(이슈) → 봇 수집 → 검증 → 생성 → 발행, 데이터 큐레이션 파이프라인.

전체 흐름 한눈에

이 레포의 본질은 "한 방향으로 흐르는 데이터 컨베이어 벨트"다. 입력은 두 가지: ① 사람이 올린 GitHub 이슈(채널 추가/수정/신고), ② 자매 레포의 원천 데이터(channels·blocklist). 이걸 봇이 매일 빨아들여 내부 streams/*.m3u를 갱신하고, 검증을 통과하면 공개용 m3u를 새로 찍어 GitHub Pages와 API로 발행한다.

[사람] GitHub 이슈 [원천 데이터 — 자매 레포] 채널 추가/수정/신고 (구조화 양식) iptv-org/database (채널·차단목록) │ │ @iptv-org/sdk 로 로드 │ @octokit 로 이슈 파싱 │ ▼ ▼ ┌──────────────────────────────────────────────────────────┐ │ 매일 자정 · update.yml (cron: 0 0 * * *) · iptv-bot[bot] │ └───────────────────────────┬──────────────────────────────┘ ▼ (1) playlist:update 이슈를 streams/*.m3u 에 반영(추가/수정/삭제 플래그) │ 처리한 이슈 번호 → temp/logs/playlist_update.log ▼ (2) playlist:lint m3u-linter 로 형식 규칙 검사 (태그·필드 순서) │ ▼ (3) playlist:validate ┌──── 검증 게이트 (실패 시 파이프라인 중단) ────┐ │ · 중복 URL → error │ │ · 잘못된 URL → error │ │ · DB에 없는 채널 id → warning │ │ · 차단목록(DMCA/NSFW) 매칭 → error │ └─────────────────────────────────────────────┘ │ ▼ (4) playlist:generate 국가·카테고리·언어·지역·도시·index 별 공개 m3u 생성 │ (14종 generator: country/category/language/...) ▼ (5) playlist:export .api/streams.json (기계 판독용 JSON) 생성 ▼ (6) readme:update PLAYLISTS.md 표(채널 수·링크) 자동 갱신 │ ┌────────────────┼─────────────────────┐ ▼ ▼ ▼ git commit GitHub Pages iptv-org/api (봇 명의 푸시) gh-pages 배포 streams.json 배포 streams/ 갱신 공개 m3u 호스팅 (JSON API)

검증 게이트 — 데이터 품질을 코드로 강제

이 파이프라인의 심장은 validate.ts다. 단순히 "파일이 m3u 형식인가"를 넘어, 데이터의 의미적 정합성을 검사한다. 핵심 통찰은 오류(error)와 경고(warning)를 구분한다는 점이다 — error는 파이프라인을 멈추지만, warning은 흐름은 보내되 사람에게 알린다.

검사판정의미
중복 URLerror같은 스트림이 다른 파일에 이미 있으면 거부(어느 파일에 있는지까지 표시).
URL 유효성errorisURI()로 형식 검사. 깨진 주소 차단.
DB 미등록 채널warning채널 id가 database에 없으면 경고(데이터 정렬 유도).
DMCA 차단목록error저작권자 클레임이 있는 채널은 발행 거부.
NSFW 차단목록error2024년부터 성인 채널 배포 중단 정책을 코드로 집행.
검증 로직 핵심 (validate.ts 요지)
// 1) 모든 스트림을 url 키로 버퍼에 모아 "중복"을 감지
const buffer = new Dictionary<Stream>()
streams.forEach(s => { if (!selectedFiles.includes(s.filepath)) buffer.set(s.url, s) })

// 2) 검증 대상 스트림을 하나씩 게이트에 통과
if (buffer.has(stream.url))            log.add({ type:'error', ... })  // 중복
if (!isURI(stream.url))                log.add({ type:'error', ... })  // 잘못된 URL
if (!data.channelsKeyById.get(id))     log.add({ type:'warning', ... })// DB에 없음

// 3) 차단목록(블록리스트) 대조 — DMCA / NSFW
blocklistRecords.forEach(r => {
  if (r.reason === 'dmca')  log.add({ type:'error', ... })
  if (r.reason === 'nsfw')  log.add({ type:'error', ... })
})

여기서 배울 점: "검증은 별도 데이터 소스(database·blocklist)와의 대조"라는 발상이다. m3u 파일 자체만 보지 않고, 외부 진실원과 교차 검증해 정합성을 지킨다.

핵심 설계 패턴

패턴iptv-org에서의 구현
단일 진실원 분리채널 메타데이터=database, 스트림 링크=이 레포, 편성표=epg. 책임이 레포별로 쪼개짐.
이슈 주도 워크플로구조화된 이슈 템플릿(1_streams_add.yml 등)이 곧 데이터 입력 폼. 봇이 파싱.
봇 자동화 (GitOps)모든 변경이 봇 명의 커밋으로 git에 남음 → 이력·되돌리기·감사 가능.
생성기(Generator) 패턴같은 스트림 데이터에서 14종 generator가 축(국가/언어/카테고리…)별 m3u를 찍어냄.
린트 + 검증 분리형식(lint)과 의미(validate)를 따로. CI는 둘 다 통과해야 머지.
증분 검증PR에서는 바뀐 파일만 검사(git diff --name-only)해 CI 속도 확보.
모델/표현 분리Stream/Playlist 모델 → m3u·JSON·HTML·README 표로 각각 직렬화.
비유 — 데이터 큐레이션 파이프라인

이 레포를 "전 세계에서 책을 기증받는 거대 공공 도서관"으로 생각하자. 시민(사람)은 정해진 기증 양식(이슈 템플릿)으로 책을 보낸다. 사서 로봇(봇)은 매일 밤 들어온 책을 받아 중복인지, 페이지가 멀쩡한지, 분실·금지 도서 목록(DMCA/NSFW)에 있는지 검사한다. 통과한 책만 서가에 꽂고(streams 갱신), 그걸 다시 주제·언어·국가별 추천 목록(공개 m3u)으로 묶어 출입구(GitHub Pages)에 비치한다. 사람은 "판단"만, 로봇은 "반복 검수·정리"를 맡는 분업이 핵심이다.

5디렉토리 구조 해부

데이터(streams)·엔진(scripts)·자동화(.github)의 3구역.

iptv/ ├── streams/ ★★ 데이터 본체 — 국가별 m3u 324개 │ ├── ad.m3u ae.m3u af.m3u ... (국가 코드별, 총 ≈15,250 스트림) │ ├── at_pluto.m3u au_samsung.m3u (사업자/플랫폼별 변형) │ └── ... ├── scripts/ ★ 데이터 처리 엔진 (TypeScript) │ ├── commands/ 실행 진입점 (npm run 으로 호출) │ │ ├── playlist/ │ │ │ ├── update.ts ★ 이슈→streams 반영 (봇 핵심) │ │ │ ├── validate.ts ★ 검증 게이트 (중복·URL·DB·차단목록) │ │ │ ├── generate.ts ★ 공개 m3u 14종 생성 │ │ │ ├── format.ts 내부 m3u 표준 포맷팅 │ │ │ ├── export.ts .api/streams.json 생성 │ │ │ ├── test.ts 실제 스트림 재생 가능성 테스트 │ │ │ └── edit.ts 대화형 편집(inquirer) │ │ ├── readme/update.ts PLAYLISTS.md 표 자동 생성 │ │ ├── report/create.ts HTML 테스트 리포트 │ │ └── api/load.ts 자매 데이터 다운로드(postinstall) │ ├── generators/ ★ 14종 생성기 (축별 m3u) │ │ ├── indexGenerator.ts 전체 통합 index.m3u │ │ ├── countriesGenerator.ts 국가별 │ │ ├── categoriesGenerator.ts 카테고리별 │ │ ├── languagesGenerator.ts 언어별 │ │ ├── regionsGenerator.ts 지역별 │ │ ├── citiesGenerator.ts 도시별 │ │ └── ... (subdivisions·sources·raw 등) │ ├── models/ Stream · Playlist · Issue · Discussion │ ├── core/ PlaylistParser · streamTester · htmlTable ... │ ├── tables/ README 표 빌더(국가·언어·카테고리·지역) │ ├── api.ts 자매 데이터 로드/다운로드 진입 │ ├── constants.ts 경로 상수(STREAMS_DIR·LOGS_DIR·ROOT_DIR) │ └── utils.ts getStreamInfo · loadIssues · createThread ├── .github/ │ ├── workflows/ ★ check.yml · update.yml · format.yml │ └── ISSUE_TEMPLATE/ ★ 데이터 입력 폼 (1_streams_add.yml 등 6종) ├── tests/ jest 테스트(@swc/jest 변환) ├── m3u-linter.json m3u 린트 규칙 ├── PLAYLISTS.md 자동 생성된 거대 재생목록 표(≈124KB) ├── package.json playlist:* 명령 모음 └── README.md / CONTRIBUTING.md / FAQ.md / LICENSE(CC0)
읽는 순서 추천

README.md + .github/ISSUE_TEMPLATE/로 "데이터가 어떻게 들어오나" → ② scripts/commands/playlist/update.ts로 "이슈→데이터 반영" → ③ validate.ts로 "어떻게 검증하나" → ④ generators/ 한두 개로 "어떻게 m3u를 찍나" → ⑤ .github/workflows/update.yml로 "전체를 어떻게 매일 자동으로 묶나". 이 다섯 곳에 큐레이션 파이프라인의 전부가 있다.

6학습 포인트

대규모 데이터 큐레이션 · CI 자동화에서 무엇을 배우나.

A. 사람-봇 분업 — "판단은 사람, 반복은 봇"

가장 큰 교훈은 기여의 진입장벽을 코드가 아니라 "양식"으로 낮춘 것이다. 기여자는 TypeScript를 몰라도 이슈 템플릿만 채우면 된다. 봇이 그걸 파싱해 데이터에 반영하고, 검증·정리·발행은 전부 자동이다. 커뮤니티 데이터 프로젝트를 키우는 핵심 설계다.

실습: 당신의 작은 데이터 프로젝트(예: 맛집 목록)에 GitHub 이슈 폼(.github/ISSUE_TEMPLATE/*.yml)을 하나 만들어, 비개발자도 구조화된 데이터를 제출하게 해 보라.

B. 검증을 CI 게이트로 강제하기

데이터가 깨지지 않게 지키는 비결은 "검증을 머지 조건으로 만드는 것"이다. check.yml은 PR에서 바뀐 파일만 골라 lint+validate를 돌리고, 실패하면 머지를 막는다. 사람의 선의에 기대지 않고 품질을 자동으로 집행한다. error/warning 구분, 외부 진실원(database·blocklist)과의 교차 검증도 그대로 배울 패턴이다.

실습: 임의의 CSV/JSON 데이터에 "필수 컬럼·중복 키·금지값" 검사를 하는 검증 스크립트를 쓰고, GitHub Actions에서 PR마다 돌게 걸어 보라. 통과 못 하면 빨간 X가 뜨도록.

C. cron + 봇 커밋으로 "살아 있는 데이터" 유지

update.ymlcron: 0 0 * * * + GitHub App 토큰 + 봇 명의 커밋 조합은 "사람이 손대지 않아도 매일 스스로 갱신·발행되는 저장소"를 만든다. 모든 변경이 git 이력에 남아 추적·되돌리기가 된다(GitOps). 이건 데이터뿐 아니라 가격·환율·통계 같은 어떤 주기적 데이터에도 그대로 적용된다.

실습: 매일 어떤 공개 API를 호출해 결과 JSON을 레포에 자동 커밋하는 scheduled workflow를 만들어 보라. 봇 명의 커밋·푸시까지.

D. 하나의 모델, 여러 표현 (Generator 패턴)

같은 Stream 데이터에서 14종 generator가 국가·언어·카테고리·지역·도시별 m3u를, 또 export가 JSON을, readme:update가 마크다운 표를 찍어낸다. "데이터 모델과 출력 형식의 분리"가 명확해서, 새 분류 축을 추가하려면 generator 하나만 더 만들면 된다.

실습: 항목 리스트(예: 도서 목록) 하나를 받아 "장르별 / 저자별 / 연도별"로 그룹핑해 각각 별도 파일로 내보내는 generator 3개를 같은 입력 모델만 받도록 설계하라.

7시스템 / 환경 요구사항

쓰는 사람 vs 개발/기여하는 사람으로 나뉜다.

대상요구사항
단순 시청자아무것도 설치 안 함. VLC 등 플레이어에 m3u 링크 붙여넣기가 전부.
로컬 개발/기여Node.js 22 + npm. npm install(postinstall이 자매 데이터 자동 다운로드).
주요 명령npm run playlist:validate / :generate / :format / :test.
CI 로컬 재현gh(GitHub CLI) + act. npm run act:update로 워크플로 로컬 실행.
봇 운영(메인테이너)GitHub App(APP_ID·PRIVATE_KEY 시크릿) — 봇 명의 커밋·Pages 배포용.
네트워크스트림 테스트(playlist:test) 시 외부 접속 + 선택적 프록시(socks).
법적 · 윤리적 주의 (반드시 읽을 것)
이 레포는 "공개 링크 모음"이지 영상 저장소가 아니다

README가 명시하듯 이 저장소에는 영상 파일이 전혀 없다. 사용자 제보로 모인, 저작권자가 의도적으로 공개한 것으로 보이는 공개 스트림 URL만 담는다. 그럼에도 특정 링크가 저작권을 침해한다면 전용 이슈 템플릿(6_copyright-claim.yml)으로 제거를 요청할 수 있다.

다만 링크를 목록에서 지운다고 그 콘텐츠가 웹에서 사라지지는 않는다(링크 제공은 복제가 아니므로 그 자체가 저작권 직접 침해는 아니라는 것이 프로젝트 입장). 실제 콘텐츠 제거는 GitHub이나 메인테이너가 아니라 실제 호스팅 업체에 요청해야 한다. 시청·재배포 시 본인 관할지의 방송·저작권 법규를 준수할 책임은 사용자에게 있다. 본 문서는 데이터 큐레이션 아키텍처 학습용이다.

8직접 해볼 수 있는 실습 과제

난이도별 5단계 — 데이터 큐레이션·CI 자동화 체득.

과제 1 난이도 ★☆☆☆☆

m3u 한 파일 뜯어보기

streams/에서 한 국가 파일(예: kr.m3u)을 열어 #EXTM3U·#EXTINF·tvg-id·스트림 URL의 구조를 직접 읽고, "한 채널 = 메타데이터 한 줄 + URL 한 줄"이 어떻게 표현되는지 도식으로 정리한다.

과제 2 난이도 ★★☆☆☆

로컬에서 검증 돌려보기

레포를 클론하고 npm installnpm run playlist:validate를 돌려, error/warning이 어떻게 출력되는지 본다. 일부러 m3u에 중복 URL이나 깨진 URL을 한 줄 넣어보고 검증이 그걸 잡아내는지 확인한다.

과제 3 난이도 ★★★☆☆

나만의 검증 게이트 만들기

임의의 데이터 파일(CSV/JSON)에 대해 "중복 키 검사 + 필수 필드 검사 + 금지값(블록리스트) 대조"를 하는 검증 스크립트를 쓴다. iptv처럼 error는 종료코드 1, warning은 출력만 하도록 구분해 본다.

과제 4 난이도 ★★★★☆

cron 자동 발행 파이프라인 구축

GitHub Actions에서 schedule: cron으로 매일 공개 데이터 API를 호출 → 가공 → 결과를 레포에 봇 명의로 커밋·푸시하는 워크플로를 만든다. iptv의 update.yml을 참고해 "변경이 있을 때만 커밋" 조건까지 넣어 본다.

과제 5 난이도 ★★★★★

Generator 패턴으로 다축 발행기 만들기

하나의 입력 데이터 모델에서 "분류 축별"로 여러 출력 파일을 찍어내는 generator 구조를 직접 설계한다. iptv의 generators/처럼 공통 베이스 클래스 + 축별 서브클래스로 짜고, 새 축을 추가할 때 기존 코드 수정 없이 generator만 더하면 되도록 확장성을 확보한다.

9관련 기술 심화 학습 로드맵

6주 코스 — 데이터 포맷부터 CI 자동 발행까지.

주차주제실습 · 참고
1주차미디어 재생목록 포맷 — m3u/m3u8·HLS 기본streams/*.m3u 분석 · iptv-playlist-parser 사용
2주차TypeScript CLI 만들기 — commander·tsxscripts/commands/ 정독 · 미니 CLI 작성
3주차데이터 검증 설계 — 정합성·중복·교차검증validate.ts · error/warning 분리 구현
4주차Generator/모델 분리 — 하나의 모델, 여러 표현generators/ · models/Stream·Playlist
5주차GitHub Actions — PR 게이트·증분 검사check.yml · git diff --name-only 활용
6주차봇 자동화·GitOps — cron·App 토큰·자동 커밋·Pages 배포update.yml 통째 분석 · 직접 scheduled workflow 구축

10핵심 키워드 사전

본문·소스에 나온 용어 빠른 참조.

용어의미
IPTV일반 인터넷망으로 실시간 TV를 전송하는 방식.
m3u / m3u8"채널명 = 스트림 주소"를 나열한 텍스트 재생목록 포맷. 이 레포의 발행물.
HLS / DASH(MPD)인터넷 실시간 스트리밍 방식. hls-parser/mpd-parser로 분석.
스트림(stream)한 채널의 실제 재생 URL + 메타데이터. 이 레포가 큐레이션하는 단위.
데이터 큐레이션흩어진 데이터를 수집·검증·정리·발행해 가치 있게 유지하는 일.
이슈 템플릿구조화된 GitHub 이슈 폼. 비개발자의 데이터 입력 창구.
validate(검증)중복·URL유효성·DB대조·차단목록 검사. 의미적 정합성 게이트.
lintm3u 형식 규칙 검사(m3u-linter). 의미가 아닌 형식 점검.
blocklist(차단목록)DMCA·NSFW 등 발행하면 안 되는 채널 목록. database에서 가져옴.
generator스트림 데이터에서 국가/언어/카테고리별 m3u를 찍어내는 생성기.
cron (0 0 * * *)"매일 자정 실행" 스케줄. update 파이프라인의 자동 트리거.
GitHub App 토큰봇(iptv-bot[bot]) 명의로 커밋·배포하기 위한 인증.
GitHub Pages공개 m3u를 정적 호스팅하는 곳(iptv-org.github.io/iptv).
GitOps모든 변경을 git 커밋으로 남겨 추적·되돌리기 가능하게 운영하는 방식.
CC0저작권을 포기한 퍼블릭 도메인 라이선스. 이 데이터의 라이선스.
EPG전자 편성표. 별도 레포 iptv-org/epg가 담당.

11참고 링크