프로젝트 소개

M3U Playlist Editor는 Vue 3, Express, PostgreSQL(Node.js 22+, PostgreSQL 13+, Docker 및 CI에서 PostgreSQL 16)로 구축된 셀프 호스팅 IPTV 플레이리스트 관리자로, MIT 라이선스 하에 배포됩니다. 반응형 웹 인터페이스를 통해 M3U 및 Xtream 플레이리스트를 가져오고, 편집하고, 구성하고, 내보내고, 공유하며, 다중 사용자 격리와 프로덕션 Docker 스택을 지원합니다. 핵심 기능: Live TV, VOD, Series를 위한 Xtream Codes 가져오기; 로컬 또는 원격 M3U 가져오기 및 이스케이프된 M3U 내보내기; 소스별 채널 매칭 및 시간대 인식 가이드 보기 기능을 갖춘 XMLTV 가이드 소스; 카테고리 및 채널 정렬, 일괄 작업, 로고 업로드, 검색 및 메타데이터 편집; 스트림 유형 사이드바, 카테고리 목록, 채널 테이블, 채널별 편집 패널로 구성된 3개 창 채널 편집기; tvg-id 자동 매칭을 지원하는 다중 일 EPG 편집기 그리드; 즉시 순서가 유지되는 드래그 앤 드롭 정렬; 터키어 및 영어 인터페이스, 밝음/어두움/시스템 테마, 키보드 탐색, 모바일 레이아웃. 계정 및 보안: 회전하는 HttpOnly 새로 고침 세션과 함께 단기 액세스 토큰을 사용합니다. ALLOW_REGISTRATION=false로 등록을 비활성화할 수 있지만, users 테이블이 비어 있는 동안 첫 번째 사용자는 여전히 등록할 수 있어 신규 설치가 잠기지 않습니다. npm 스크립트는 등록된 이메일에 대해 관리자 권한을 부여하거나 취소하고, 사용자 비밀번호를 재설정하여 모든 활성 세션을 취소합니다. JWT_SECRET 및 CREDENTIAL_ENCRYPTION_KEY는 최소 32자 이상의 독립적으로 생성된 값이어야 하며, 프로덕션 시작 시 배송된 자리 표시자, 짧거나 엔트로피가 낮은 값, 두 값의 재사용을 거부합니다. 배포: Compose 스택은 순수 HTTP만 제공하며, TLS 리스너, 인증서, HTTP-to-HTTPS 리디렉션이 없습니다. 따라서 TLS는 프론트에서 종료되어야 하며(Caddy, Traefik, nginx 또는 클라우드 로드 밸런서), 게시된 포트는 비공개로 유지되거나 루프백에 바인딩되어야 합니다. 새로 고침 쿠키는 프로덕션에서 Secure로 표시됩니다. API 컨테이너는 시작 전에 보류 중인 마이그레이션을 적용하고, PostgreSQL은 호스트에 노출되지 않으며, 업로드된 로고와 데이터베이스 파일은 명명된 볼륨을 사용하고, API는 읽기 전용 루트 파일 시스템을 가진 비루트 사용자로 실행되며, 프론트엔드는 보안 및 캐시 헤더를 갖춘 nginx로 제공됩니다. 신뢰할 수 있는 로컬 서비스를 위한 문서화된 옵트인인 ALLOW_PRIVATE_NETWORK_URLS를 통해 비공개 네트워크 원격 URL은 기본적으로 SSRF 보호를 위해 차단됩니다. Xtream 가져오기 기본값(바이트 제한, 카테고리 및 유형 동시성, Node 힙 크기)은 약 150,000개의 Live/VOD/Series 항목이 있는 플레이리스트에 맞게 조정되었습니다. Xtream Codes 출력: 플레이리스트는 POST /api/playlists/:id/xtream-output을 통해 노출될 수 있으며, 서버 주소와 무작위 사용자 이름 및 비밀번호를 반환합니다. 비밀번호는 AES-256-GCM으로 암호화되어 저장되며, 소유자에게는 항상 일반 텍스트로 표시되고, 재생성 가능하며, 플레이어 액세스를 끄기 위해 제거할 수 있습니다. 지원되는 루트 경로는 /player_api.php, /xmltv.php, /get.php, /m3u.php입니다. 더 짧은 /m3u.php?id=...&secret=... 주소는 자체 자격 증명 쌍을 가지고 있어 Xtream 사용자 이름과 비밀번호를 노출하지 않고도 배포할 수 있으며, 출력이 재생성될 때 회전합니다. 서버는 스트림 주소가 아닙니다. get.php는 제공자의 채널 URL을 게시하고, player_api.php는 direct_source를 채우므로 재생은 애플리케이션을 건드리지 않으며, 이전 프록시 모드는 열과 함께 제거되었습니다. README는 게시된 URL이 상류 제공자의 자격 증명을 포함할 수 있으므로 출력 자격 증명을 공유하면 제공자 계정을 공유하는 것과 같다고 경고합니다. direct_source를 존중하는 클라이언트를 사용하세요. 로고 라이브러리: 채널 패널에는 48개국 및 16개 기타 그룹의 tv-logo/tv-logos에서 10,700개 이상의 로고를 검색하는 Find logo 버튼이 있습니다. 인덱스는 하루에 한 번 GitHub의 tree 엔드포인트에서 가져와 캐시되며, 이미지는 jsDelivr에서 제공되고, 매칭은 품질 및 국가 태그를 제거하고 터키어 문자를 접습니다(TRT 1 FHD는 trt-1-tr.png를 찾습니다). 어시스턴트는 동일한 기능을 호출하여 로고가 없는 채널에 로고를 적용할 수 있습니다. AI 어시스턴트: 모든 인증된 페이지에서 선택적 채팅 런처가 플레이리스트, 카테고리, 채널, EPG, 가져오기 및 동기화, 내보내기 및 공유, 첨부 파일 및 출력 파일, 예약된 작업, 계정/시스템 정보를 다루는 175개 서버 측 도구를 통해 애플리케이션을 작동합니다. OpenAI 호환 제공자(기본 URL, 암호화된 API 키, 모델 목록 가져오기)와 함께 작동하며, Server-Sent Events를 통해 답변을 스트리밍하고, 파괴적인 작업 전에 승인 게이트를 지원하며, 파일 첨부를 수락하고, 음성 명령을 최소 15분 간격의 반복 서버 측 작업으로 변환할 수 있으며, 실행은 기록되고, 실행 전에 백업되며, 한 번의 클릭으로 되돌릴 수 있습니다. 웹 검색은 사용자 구성 없이 배송됩니다. 내부 SearXNG 인스턴스(searxng:8080으로만 접근 가능, 공개적으로 노출되지 않음)가 web_search 및 open_web_page를 지원하며, JSON 출력이 포함된 설정에서 활성화되어 있습니다. SEARXNG_URL이 비어 있으면 두 도구 모두 등록되지 않습니다. 첨부 파일: .m3u, .m3u8, .txt, .xml, .xmltv, .json, .csv 파일은 확장자가 아닌 콘텐츠로 감지되며, 각 20 MB, 계정당 200 MB까지 디스크에 저장되고, 모델에 전체로 전달되지 않고 어시스턴트에 의해 페이지 처리되거나 검색됩니다. 12,000자를 초과하는 메시지는 자동으로 첨부 파일로 변환됩니다. 죽은 채널 복구: repair_dead_channels는 허용 오차 내의 이름 감소를 통해 깨진 채널을 Xtream 카탈로그와 매칭하고, 스트림 URL만 다시 작성하며, 각 후보를 쓰기 전에 테스트하고, 검사되지 않은 채널을 제외하며, 드라이 런을 지원합니다. 예약된 작업과 함께 사용하면 무인으로 실행할 수 있습니다.