Định dạng TS IPTV Source
TS IPTV Source là một tệp JSON duy nhất mô tả trọn vẹn một bộ sưu tập mang dấu ấn riêng: ai tạo ra nó, màu sắc, bố cục trang chủ, kênh truyền hình và radio, phim lẻ, phim bộ với các mùa và tập, lịch phát sóng, cùng các liên kết tới danh sách phát, lịch phát sóng và addon khác. Định dạng này là định dạng mở, được mô tả đầy đủ trên trang này và được kiểm tra bằng một JSON Schema công khai.
TS IPTV không có sẵn kênh nào và cũng không có sẵn nguồn nào. Một TS IPTV Source chỉ chứa những đường dẫn do người tạo đưa vào; TS IPTV không liệt kê, lưu trữ hay giới thiệu nguồn nào. Mọi ví dụ trên trang này dùng tên miền giả example.com, một luồng thử nghiệm công khai, phim thuộc phạm vi công cộng trên archive.org, hoặc tệp ví dụ của chính TS IPTV trên tsiptv-8bdd6.web.app.
Tệp: JSON Schema (https://tsiptv-8bdd6.web.app/schema/tsiptv-source-v1.json, chuẩn 2020-12) · ví dụ minimal-live, vod-catalog, composed-includes · công cụ kiểm tra trên trình duyệt.
Định dạng này là gì
M3U mô tả một danh sách kênh. TS IPTV Source mô tả cả một bộ sưu tập và cách trang chủ của nó hiển thị. Hãy dùng định dạng này khi bạn muốn có phim lẻ và phim bộ kèm ảnh bìa và các tập, có các mục và màu sắc riêng, có nhiều luồng cho mỗi nội dung, hoặc khi bạn muốn gộp các danh sách M3U, lịch XMLTV, addon tương thích Stremio và các nguồn khác thành một.
Định dạng tuân theo năm nguyên tắc:
- Chỉ có dữ liệu, không có mã. Không có script, biểu thức, HTML hay Markdown. Mọi chữ đều là văn bản thuần; TS IPTV không bao giờ chạy thứ gì từ một nguồn.
- Chỉ có đường dẫn, không có nội dung. Tệp mang các đường dẫn do người tạo cung cấp. Bản thân định dạng, schema và ứng dụng không kèm nội dung nào.
- Dễ viết bằng tay. Tệp hợp lệ nhỏ nhất chỉ có mười dòng. Có cách viết tắt cho các trường hợp thường gặp (
urlthay chostreams, một chuỗi thường thay cho đối tượng dịch). - Tương thích về sau. Trường không biết sẽ bị bỏ qua và giá trị không biết được thay bằng giá trị dự phòng đã định, nên ứng dụng cũ vẫn đọc được tệp mới. Chỉ thay đổi làm hỏng tương thích mới tăng
version. - Cùng ý nghĩa với M3U. Header, DRM và xem lại có đúng ý nghĩa như trong M3U kiểu Kodi, nên một kênh phát giống nhau ở cả hai định dạng.
Trang này là tài liệu tham khảo công khai của phiên bản 1. JSON Schema khắt khe hơn ứng dụng, nên tệp qua được schema gần như luôn được chấp nhận. Ngoại lệ là những điều schema không thấy được: tệp lớn hơn 5 MiB; format nằm sau 64 KiB đầu tiên; ngày không có thật trên lịch như 2026-02-30 (TS IPTV cảnh báo và bỏ qua trường đó); id trùng và tham chiếu tới mục không tồn tại (ứng dụng và công cụ kiểm tra đều phát hiện); và include bị lỗi hoặc tạo vòng lặp (E_INCLUDE, E_INCLUDE_CYCLE, và E_EMPTY nếu không còn gì khác).
Bắt đầu nhanh
Tệp nhỏ nhất dùng được: một kênh phát thật (luồng thử nghiệm công khai của Mux, phim Big Buck Bunny © Blender Foundation, CC BY 3.0).
{
"$schema": "https://tsiptv-8bdd6.web.app/schema/tsiptv-source-v1.json",
"format": "tsiptv-source",
"version": 1,
"id": "com.example.my-channels",
"meta": { "name": "My Channels" },
"channels": [
{ "id": "test-hls", "name": "HLS Test Channel", "url": "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" }
]
}
Lưu thành my-channels.tsiptv.json (UTF-8), đưa lên một máy chủ HTTPS bất kỳ rồi thêm đường dẫn vào TS IPTV. Dòng $schema giúp các trình soạn thảo như VS Code kiểm tra tệp và gợi ý tên trường ngay khi bạn gõ.
Định dạng, từng phần một
Tệp
| Thuộc tính | Quy tắc |
|---|---|
| Mã hoá | UTF-8. BOM ở đầu tệp được chấp nhận nhưng không nên ghi. |
| Cú pháp | JSON: không chú thích, không dấu phẩy thừa. Gốc là một đối tượng. |
| Nhận dạng | Tệp là TS IPTV Source khi trường "format" ở cấp cao nhất là "tsiptv-source". Tên tệp và loại nội dung máy chủ gửi không quan trọng. TS IPTV tìm format trong 64 KiB đầu tiên của tệp, nên hãy đặt nó ở gần đầu (ngay sau $schema). |
| Đuôi tệp | Nên dùng .tsiptv.json (ví dụ my-channels.tsiptv.json). |
| Kích thước | Tối đa 5 MiB sau khi giải nén, áp dụng cho chính tệp và cho từng nguồn được include. |
| Nén | Chấp nhận cả Content-Encoding: gzip của HTTP lẫn tệp đã nén gzip. |
Cấp cao nhất
| Trường | Bắt buộc | Nghĩa |
|---|---|---|
$schema | không | Đường dẫn schema, dành cho trình soạn thảo. TS IPTV không bao giờ tải nó. |
format | có | Đúng "tsiptv-source". |
version | có | 1. Số lớn hơn nghĩa là “cần TS IPTV mới hơn”. |
id | có | Mã định danh cố định của nguồn, là một Id. Nên dùng tên miền đảo ngược (com.example.news). Cùng id từ cùng đường dẫn là một bản cập nhật. |
revision | không | Số nguyên ≥ 0 mà bạn tăng lên mỗi lần đăng thay đổi (mặc định 0). |
meta | có | Thông tin về nguồn. |
appearance | không | Màu sắc và kiểu thẻ. |
layout | không | Các mục của trang chủ. Không có thì dùng bố cục mặc định. |
channels | không | Kênh truyền hình và radio, tối đa 10.000. |
movies | không | Tối đa 5.000. |
series | không | Tối đa 1.000 (và tổng cộng 20.000 tập). |
epg | không | Đường dẫn lịch phát sóng XMLTV, tối đa 10. |
includes | không | Tài liệu từ xa, tối đa 20. |
Tệp phải có ít nhất một trong channels, movies, series hoặc includes không rỗng.
Quy tắc chung
- Trường
x-: mọi trường có tên bắt đầu bằngx-là của bạn (ghi chú, dữ liệu của công cụ). TS IPTV bỏ qua chúng và định dạng sẽ không bao giờ định nghĩa trường nào như vậy. Quy tắc này không áp dụng cho tên header, khoá ngôn ngữ hay mã khoá DRM, vì đó là dữ liệu. nulltương đương với bỏ trống trường đó.- Trường không biết bị ứng dụng bỏ qua, nhưng schema báo lại để bạn phát hiện lỗi gõ.
- Chữ được cắt khoảng trắng hai đầu; giá trị rỗng sau khi cắt là không hợp lệ. Độ dài tính theo ký tự (điểm mã Unicode).
- Ký tự điều khiển: schema không cho phép trong chữ, trừ xuống dòng trong chữ dài (phần mô tả). TS IPTV dễ dãi hơn: xuống dòng hay ký tự điều khiển trong chữ một dòng được thay bằng dấu cách và chỉ bị báo là cảnh báo, không phải lỗi. URL và nguồn xem lại hoàn toàn không được có; giá trị header chỉ cho phép tab.
meta
| Trường | Bắt buộc | Nghĩa |
|---|---|---|
name | có | Chữ: tên hiển thị của nguồn. |
description | không | Chữ dài. |
author | không | { "name" (bắt buộc, 1–100), "url"?, "email"? }. |
logo | không | URL ảnh vuông, từ 256×256 trở lên. |
homepage | không | Hiện trong “Giới thiệu nguồn”; TS IPTV hỏi trước khi mở. |
language | không | Ngôn ngữ của các chữ viết dạng chuỗi thường và ngôn ngữ dự phòng (mặc định en). |
languages | không | Ngôn ngữ của nội dung, để hiển thị (tối đa 20). |
updatedAt | không | Thời điểm dạng 2026-09-27T10:00:00Z. |
adult | không | true nếu nguồn có nội dung người lớn. Mọi giá trị không phải true hay false cũng được coi là người lớn. Khi đó TS IPTV cảnh báo và hỏi “Tôi đủ 18 tuổi trở lên” trước khi nhập. |
license | không | Giấy phép của danh sách (không phải của luồng), chữ tự do hoặc mã SPDX, tối đa 200 ký tự. |
Chữ và bản dịch
Mọi chữ hiển thị là một chuỗi thường, viết bằng ngôn ngữ của meta.language, hoặc một đối tượng ánh xạ mã ngôn ngữ tới chuỗi:
"name": "Movies"
"name": { "en": "Movies", "vi": "Phim lẻ", "zh-CN": "电影" }
- Chữ (tên, tiêu đề): 1–200 ký tự, một dòng. Chữ dài (mô tả): 1–5.000 ký tự; được xuống dòng (LF, CR hoặc CRLF).
- Mã ngôn ngữ:
en,vi,zh-CN,pt-BR(mẫu^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$); tối đa 30 mã mỗi đối tượng. - TS IPTV chọn theo thứ tự: đúng ngôn ngữ của ứng dụng (
zh-CN), rồi ngôn ngữ chính (zh, rồi bất kỳzh-…), rồimeta.language, rồien, rồi mục đầu tiên. - Chữ được hiện đúng như viết: không HTML, không Markdown.
Id, URL, header, màu
| Kiểu | Quy tắc |
|---|---|
| Id | ^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$: chữ cái, chữ số, ., _, -, phân biệt hoa thường, không có : (dấu hai chấm dành cho mục được include, includeId:itemId). Mọi id của kênh, phim lẻ, phim bộ, tập và include phải là duy nhất trong tệp. Id xuất hiện trước được giữ, theo thứ tự: kênh, phim lẻ, phim bộ (mỗi phim bộ kèm các tập của nó), include; mục bị bỏ thì không giữ id của nó. |
| URL | Tuyệt đối, http:// hoặc https://, tối đa 2.048 ký tự, không khoảng trắng hay ký tự điều khiển. Mọi URL trong tệp (luồng, ảnh, include, máy chủ giấy phép) đều theo quy tắc này; rtmp:, udp:, file:, data: và mọi giao thức khác đều không hợp lệ. Nên dùng https. |
| Header | Đối tượng tên header → giá trị, ví dụ { "User-Agent": "Mozilla/5.0", "Referer": "https://example.com/" }. Tối đa 20. Giá trị được gửi đúng như viết (không giải mã URL), tối đa 4.096 ký tự. Cấm Host, Content-Length, Connection và Transfer-Encoding. Header đi kèm mọi yêu cầu của luồng (manifest, đoạn video, khoá), không đi kèm yêu cầu giấy phép DRM và không đi kèm tệp phụ đề. |
| Màu | #RRGGBB. |
appearance
"appearance": {
"accent": "#FFB300",
"accentSecondary": "#FF7043",
"background": { "gradient": ["#101014", "#1C1C24"], "image": "https://example.com/bg.jpg", "imageDim": 0.7 },
"card": { "style": "poster", "corner": "medium", "showTitles": true }
}
| Trường | Mặc định | Nghĩa |
|---|---|---|
accent | màu nhấn của ứng dụng | Viền khi chọn, chip đang chọn, nút, thanh tiến độ. |
accentSecondary | màu nhấn phụ | Chuyển màu trên nút và huy hiệu. |
background.color | nền của ứng dụng | Nền một màu. |
background.gradient | không có | 2–3 màu, từ trên xuống; thay cho color. |
background.image | không có | Ảnh phía sau trang chủ, dưới một lớp phủ tối. |
background.imageDim | 0.6 | Độ đậm của lớp phủ, 0,3–1,0. |
card | { "style": "auto" } | Kiểu thẻ mặc định cho mọi mục. |
Kiểu thẻ: style là auto, poster (2:3), landscape (16:9), square, logo (ô logo kênh) hoặc list (một dòng: logo, tên, chương trình đang phát); auto nghĩa là poster cho phim lẻ và phim bộ, logo cho kênh truyền hình, square cho radio, landscape cho các tập, và posterShape riêng của mục với mục lấy từ danh mục của addon tương thích Stremio. corner là none, small, medium hoặc large. showTitles: false ẩn tên trên thẻ (kênh và dạng list luôn hiện tên).
Độ dễ đọc. TS IPTV giữ màu chữ sáng của mình. Nếu màu nền của bạn (hoặc một điểm của dải màu) có độ tương phản dưới 4,5:1 với màu chữ đó, TS IPTV dùng nền của mình (ảnh nền vẫn được giữ). Nếu màu nhấn có độ tương phản dưới 3:1 với nền, cả hai màu nhấn được thay bằng màu của ứng dụng. Giao diện chỉ áp dụng cho trang chủ và trang chi tiết của nguồn; trình phát, hộp thoại và phần cài đặt vẫn giữ giao diện của ứng dụng.
layout: trang chủ
layout.home là danh sách 1–30 mục, được vẽ từ trên xuống.
"layout": {
"home": [
{ "type": "hero", "query": { "from": "movies", "limit": 5 } },
{ "type": "row", "title": { "en": "Continue watching", "vi": "Xem tiếp" }, "query": { "from": "continueWatching" } },
{ "type": "row", "title": "News", "query": { "from": "channels", "groups": ["News"] }, "card": { "style": "logo" } },
{ "type": "grid", "title": "All channels", "query": { "from": "channels", "sort": "number" }, "groupChips": true }
]
}
| Trường của mục | Nghĩa |
|---|---|
type (bắt buộc) | hero (băng ảnh lớn trượt ngang, 1–10 mục), row (một hàng ngang, mặc định 20 mục, tối đa 100) hoặc grid (lưới mọi mục phù hợp, tải theo trang). |
id | Giúp TS IPTV nhớ vị trí cuộn và vị trí chọn của mục. |
title, subtitle | Tiêu đề và dòng phụ nhỏ hơn (hero không hiện tiêu đề). |
query | Mục hiển thị gì (bắt buộc, trừ hero có items). |
items | Chỉ cho hero: các banner làm tay { "image" (16:9, bắt buộc), "title", "subtitle", "target", "autoplay" }. Một hero có query hoặc items, không có cả hai. |
card | Kiểu thẻ cho riêng mục này (hero bỏ qua trường này). |
seeAll | Chỉ cho row (mặc định true): nút “Xem tất cả” mở toàn bộ truy vấn dạng lưới. |
groupChips | Chỉ cho grid của channels hoặc radio: các chip lọc theo nhóm phía trên lưới. |
Hero dùng truy vấn sẽ lấy backdrop của từng mục, nếu không có thì poster, rồi logo, và bỏ qua mục không có ảnh. target của banner là id của một kênh, phim lẻ, phim bộ hoặc tập phim (mục được include viết dạng includeId:itemId); không có target thì banner chỉ để trang trí. autoplay: true bắt đầu phát nội dung (chỉ với kênh, phim lẻ và tập phim): kênh phát ngay; phim lẻ mở trang chi tiết của nó, tập phim mở trang chi tiết của phim bộ chứa nó, rồi phát luôn, nên bấm Quay lại sẽ về trang chi tiết đó. Banner không thể mở trang web. Mục không tìm thấy nội dung nào sẽ không được vẽ.
Truy vấn
| Trường của truy vấn | Nghĩa |
|---|---|
from (bắt buộc) | channels, radio, movies, series, catalog (danh mục của một include addon tương thích Stremio), continueWatching, favorites. |
include | Chỉ lấy mục từ include có id này. Bắt buộc với catalog, khi đó nó là id của include stremio. |
catalog | Cho from: "catalog": { "type", "id", "genre"? } của một danh mục khai báo trong manifest của addon đó. |
ids | Chỉ những mục này, theo đúng thứ tự (1–500; mục được include viết dạng includeId:itemId). Id không tồn tại bị bỏ qua. |
groups, genres, tags | Mục có nhóm (kênh), thể loại (phim lẻ, phim bộ) hoặc thẻ chứa một trong các giá trị này; không phân biệt hoa thường. |
sort | source (thứ tự trong tệp; mục được include đứng sau mục của bạn), name, number, year, yearDesc, recent (Xem tiếp). |
limit | 1–500 mục. |
Các bộ lọc kết hợp bằng VÀ giữa các trường và HOẶC trong cùng một trường. Bộ lọc không áp dụng được (ví dụ genres với kênh) bị bỏ qua. Với catalog, chỉ catalog.genre dùng để lọc và thứ tự của addon được giữ nguyên. continueWatching (phim lẻ, tập phim xem dở và kênh vừa xem) và favorites (kênh yêu thích) lấy từ lịch sử của chính người xem, không bao giờ nằm trong tệp; chúng bị ẩn cho tới khi có nội dung.
Bố cục mặc định
Khi không có layout, TS IPTV hiển thị: Xem tiếp; hero từ phim lẻ (chỉ khi có phim có backdrop); Phim lẻ; Phim bộ; Radio; và lưới Kênh xếp theo số kênh, kèm chip nhóm. Mục rỗng được bỏ đi.
Kênh, phim lẻ và phim bộ
Các trường phát, dùng chung cho kênh, phim lẻ và tập phim. Mỗi mục có đúng một trong hai trường url và streams:
| Trường | Nghĩa |
|---|---|
url | Một luồng. Viết tắt của "streams": [{ "url": … }]. |
streams | 1–10 lựa chọn, tốt nhất xếp trước. Với kênh, TS IPTV phát luồng đầu tiên mà thiết bị hỗ trợ, và người xem có thể chọn luồng khác ở mục “Luồng” trong “Tuỳ chọn phát” của trình phát (điện thoại: nút cài đặt của trình phát; TV: ▶, hoặc phím MENU, phím phụ đề hay phím Settings). Với phim lẻ hoặc tập phim, trang chi tiết liệt kê các luồng và người xem chọn ở đó; “Tuỳ chọn phát” của chúng chỉ có phụ đề. Trên TV, phần tuỳ chọn chỉ mở khi có gì đó để chọn. |
headers | Header cho mọi luồng của mục; header riêng của luồng được ưu tiên theo từng tên. |
mimeType | Gợi ý loại luồng cho mọi luồng. |
drm | DRM cho mọi luồng; drm riêng của luồng thay thế nó. |
Kênh
{
"id": "example-news",
"name": { "en": "Example News", "vi": "Tin tức Ví dụ" },
"number": 101,
"logo": "https://example.com/logos/news.png",
"groups": ["News", "HD"],
"epgId": "ExampleNews.us",
"url": "https://cdn.example.com/news/index.m3u8",
"headers": { "Referer": "https://example.com/" },
"catchup": { "mode": "shift", "days": 3 }
}
| Trường | Nghĩa |
|---|---|
id, name (bắt buộc) | Id và Chữ. |
type | tv (mặc định) hoặc radio. |
number | 0–99.999, hiện trên thẻ và dùng cho sort: "number". |
logo | URL logo (nên dùng PNG nền trong suốt). |
groups | 0–10 tên nhóm (1–100 ký tự). So khớp không phân biệt hoa thường và hiện đúng như viết; tên nhóm không được dịch. |
epgId | <channel id> XMLTV của kênh. Không có thì lịch được khớp theo tên (không phân biệt hoa thường, dấu và khoảng trắng). |
epgShiftHours | −12 … +14 giờ cộng vào giờ trong lịch của kênh. |
description, tags | Chữ dài; 0–20 thẻ, mỗi thẻ 1–50 ký tự. |
catchup | Xem lại. |
Phim lẻ
Bắt buộc có id, name và các trường phát. Tuỳ chọn: originalName, poster (2:3), backdrop (16:9, dùng cho hero và trang chi tiết), logo (logo tên phim), description, year (1870–2100), releaseDate (YYYY-MM-DD), runtimeMinutes (1–1.440), genres (0–10), cast (0–50), directors (0–20), countries (mã ISO như US), languages, ageRating (như in trên phim, ví dụ T16), tags, subtitles (0–30).
Phim bộ, mùa, tập
{
"id": "fleischer-superman",
"name": "Fleischer Superman",
"year": 1941,
"endYear": 1943,
"seasons": [
{
"number": 1,
"episodes": [
{ "id": "fleischer-superman-s1e1", "number": 1, "name": "The Mechanical Monsters",
"url": "https://archive.org/download/superman_the_mechanical_monsters/superman_the_mechanical_monsters_512kb.mp4" }
]
}
]
}
- Phim bộ có
idvàname(bắt buộc),originalName,poster,backdrop,logo,description,year(năm đầu),endYear(năm cuối, không nhỏ hơnyear; không có nghĩa là đang chiếu),genres,cast,countries,languages,ageRating,tagsvàseasons(1–100). Phim bộ không có trường phát, và không códirectors,releaseDate,runtimeMinuteshaysubtitles. - Mỗi mùa có
number(0–999, không trùng trong phim bộ;0là Tập đặc biệt, xếp cuối), tuỳ chọnname,poster,description, vàepisodes(1–500). - Mỗi tập có
id(duy nhất trong cả tệp; dùng để lưu tiến độ xem),number(không trùng trong mùa),name, các trường phát, và tuỳ chọndescription,thumbnail(16:9),releaseDate(ngày trong tương lai nghĩa là “sắp ra mắt”, được liệt kê nhưng chưa phát được),runtimeMinutes,subtitles.
Luồng
| Trường | Nghĩa |
|---|---|
url (bắt buộc) | HLS .m3u8, DASH .mpd, MP4, WebM, MKV, MPEG-TS, hoặc âm thanh (AAC, MP3, Opus). |
name | Nhãn trong danh sách chọn luồng, như 1080p hoặc Dự phòng. |
headers, drm | Như trên; gộp lên trên, hoặc thay thế, giá trị của mục. |
mimeType | Khi đường dẫn không có đuôi rõ ràng: application/x-mpegURL hoặc application/vnd.apple.mpegurl (HLS), application/dash+xml, video/mp4, video/mp2t, video/webm, video/x-matroska, audio/aac, audio/mpeg, audio/ogg. |
quality, language | Huy hiệu: HD, 720p; mã ngôn ngữ âm thanh. |
DRM
"drm": { "system": "widevine", "licenseUrl": "https://license.example.com/widevine", "licenseHeaders": { "X-Example": "1" } }
"drm": { "system": "clearkey", "keys": { "000102030405060708090a0b0c0d0e0f": "00112233445566778899aabbccddeeff" } }
system:widevine,playready(bắt buộc có đường dẫn giấy phép) hoặcclearkey(một đường dẫn giấy phép, hoặckeys: 1–20 cặp mã khoá 32 ký tự hex → khoá 32 ký tự hex).- TS IPTV gửi yêu cầu thô tới
licenseUrlvà chờ giấy phép thô trả về;licenseHeaderschỉ đi kèm yêu cầu đó. Các giao thức giấy phép bọc hoặc dạng JSON không thuộc phiên bản 1. - Widevine phát trên Android; PlayReady phát trên thiết bị Android có hỗ trợ (có PlayReady CDM, chủ yếu là TV); ClearKey chỉ phát trên Android với luồng DASH. Trên iPhone, iPad và máy tính, kênh bỏ qua luồng có DRM và phát luồng tiếp theo không có DRM; nếu không có, TS IPTV báo “Kênh này được bảo vệ bằng DRM. Thiết bị này không hỗ trợ DRM.” Với phim lẻ hoặc tập phim, chọn một luồng có DRM ở trang chi tiết sẽ hiện đúng thông báo đó, nên hãy cho các mục này thêm một luồng không có DRM.
- Chỉ công bố khoá và máy chủ giấy phép mà bạn có quyền chia sẻ.
Xem lại (catch-up)
catchup dùng cùng các chế độ và chỗ trống như xem lại trong M3U kiểu Kodi: { "mode", "source"?, "days"? (1–60, mặc định 7), "correctionHours"? (−24 … +24) }. mode là default (source là mẫu URL đầy đủ, bắt đầu bằng http:// hoặc https://), append (source được nối vào sau đường dẫn phát trực tiếp, ví dụ ?utc={utc}&lutc={lutc}), shift, flussonic, flussonic-ts hoặc xc. Với default và append, source là bắt buộc và không bao giờ được cắt khoảng trắng: có dấu cách hay ký tự điều khiển là không hợp lệ (W_FIELD), phần xem lại bị bỏ và kênh chỉ phát trực tiếp. Các chế độ khác dựng URL từ đường dẫn phát trực tiếp và bỏ qua source. TS IPTV lưu thông tin xem lại; tính năng phát lại chương trình đã phát sẽ có sau.
Phụ đề
{ "url" (WebVTT hoặc SubRip), "language" (bắt buộc), "label"?, "format"? ("vtt" hoặc "srt") }. Phụ đề mặc định Tắt: người xem bật một phụ đề ở mục “Phụ đề” trong “Tuỳ chọn phát” của trình phát (xem luồng). Trên Android, phụ đề không có label hiện tên ngôn ngữ, và tệp phụ đề được tải không kèm header của luồng, nên hãy đặt chúng ở nơi không cần mã truy cập hay Referer. Trên máy tính, phụ đề vẫn tải được, nhưng cách đặt tên và việc có gửi header hay không chưa được kiểm chứng. iPhone và iPad chưa hiện phụ đề.
epg và includes
epg là danh sách đường dẫn lịch phát sóng XMLTV, mỗi mục là một chuỗi URL hoặc { "url", "refreshHours"? } (1–720, mặc định 24). Lịch có thể nén gzip. Chương trình được khớp với kênh theo epgId; kênh không có epgId được khớp theo tên (không phân biệt hoa thường, dấu và khoảng trắng).
"includes": [
{ "id": "news", "type": "m3u", "url": "https://example.com/playlists/news.m3u", "name": "Partner news" },
{ "id": "guide", "type": "xmltv", "url": "https://example.com/epg/guide.xml.gz", "refreshHours": 12 },
{ "id": "sampler", "type": "stremio", "url": "https://addon.example.com/manifest.json" },
{ "id": "archive", "type": "tsiptv-source", "url": "https://example.com/archive.tsiptv.json" }
]
| Trường của include | Nghĩa |
|---|---|
id (bắt buộc) | Id duy nhất; làm tiền tố cho các mục được include (news:ExampleTV.us). Không được bắt đầu bằng epg- (dành cho các đường dẫn epg). |
type (bắt buộc) | m3u, xmltv, stremio hoặc tsiptv-source. |
url (bắt buộc) | Với stremio, là đường dẫn manifest kết thúc bằng /manifest.json. |
name | Hiện trong “Giới thiệu nguồn” và trong thông báo lỗi. |
refreshHours | Số giờ tối thiểu giữa hai lần tự tải lại (1–720, mặc định 24). |
headers | Gửi kèm khi tải tài liệu m3u, xmltv hoặc tsiptv-source; không gửi tới addon hay luồng. |
| Loại | Đóng góp gì | Id của mục |
|---|---|---|
m3u | Kênh (mục radio vào nhóm radio), đọc bằng trình đọc M3U của TS IPTV, kể cả header và DRM; lịch trong x-tvg-url của nó được gộp vào bộ lịch. | includeId: + tvg-id của kênh (hoặc tên), ký tự ngoài tập ký tự Id được thay bằng _: ExampleTV.us@HD → live:ExampleTV.us_HD. |
xmltv | Chỉ dữ liệu lịch; không dùng được trong truy vấn. | — |
stremio | Không thêm gì vào các nhóm nội dung; danh mục của nó được hiện bằng from: "catalog". Chỉ luồng url phát được (xem addon tương thích Stremio). | Id riêng của addon. |
tsiptv-source | Kênh, radio, phim lẻ, phim bộ và đường dẫn lịch của nó. meta, appearance và layout của nó bị bỏ qua. | includeId: + id của mục (nối tiếp nhau: archive:partner:item). |
- Độ sâu và vòng lặp: tệp gốc ở độ sâu 1; nguồn được include có thể include tiếp tới độ sâu 3. Include thuộc bất kỳ loại nào sâu hơn 3, hoặc có URL đã nằm trên đường đi, sẽ bị từ chối (
E_INCLUDE_CYCLE). - Tổng mỗi lần làm mới: tối đa 20 include trong cả cây (không tính đường dẫn lịch), 50 MiB tải về (mọi tài liệu kể cả tệp gốc; câu trả lời
304tính là 0), và 20.000 kênh, 5.000 phim lẻ, 1.000 phim bộ sau khi gộp. Mỗi include M3U tối đa 20 MiB, XMLTV tối đa 100 MiB, TS IPTV Source tối đa 5 MiB. - Khi tải lỗi: include lỗi không bao giờ làm hỏng nguồn của bạn. TS IPTV giữ bản tải thành công gần nhất; nếu chưa có, các mục dùng include đó bị ẩn.
- Nội dung người lớn: nếu một nguồn được include có
meta.adult: true(hoặc bất kỳ giá trị nào không phải true/false), hoặc manifest của một addon khai báo nội dung người lớn, TS IPTV hỏi xác nhận 18+ cho cả nguồn trước khi lưu bất cứ thứ gì. Nếu một lần làm mới về sau khiến nguồn bạn chưa xác nhận trở thành nguồn người lớn, nội dung mới của include gây ra điều đó sẽ bị giữ lại (bản cũ vẫn được dùng) cho tới khi bạn xác nhận trong “Giới thiệu nguồn”.
Giới hạn
| Mục | Giới hạn |
|---|---|
| Kích thước tệp | 5 MiB mỗi tài liệu sau khi giải nén; 50 MiB mỗi lần làm mới cho cả cây |
| Số mục | 10.000 kênh, 5.000 phim lẻ, 1.000 phim bộ, 20.000 tập mỗi tài liệu; 20.000 / 5.000 / 1.000 sau khi gộp |
| Phim bộ | 100 mùa, 500 tập mỗi mùa |
| Luồng, phụ đề | 10 luồng mỗi mục; 30 phụ đề |
| Header | 20 mỗi bảng (kể cả sau khi gộp header của mục và của luồng); giá trị tối đa 4.096 ký tự |
| Bố cục | 30 mục; 10 banner hero; limit và ids của truy vấn tối đa 500; một hàng hiện tối đa 100 |
| Include | 20 mỗi tài liệu và trong cả cây; độ sâu 3; 10 đường dẫn epg mỗi tài liệu |
| Chữ | 200 ký tự (Chữ), 5.000 (chữ dài), 30 ngôn ngữ mỗi chữ; URL 2.048 |
Bảo mật và quyền riêng tư
- TS IPTV không bao giờ chạy, tính toán hay hiển thị như mã đánh dấu bất cứ thứ gì từ một nguồn.
- Chỉ đường dẫn
httpvàhttpsmới được mở. - Một nguồn không thể mở trang web, cài đặt hay tải tệp xuống máy. Khi nhập, ứng dụng chỉ tải tệp và các include của nó; ảnh được tải khi hiển thị; luồng chỉ được tải khi người xem bấm phát.
- URL và header có thể chứa mã truy cập. TS IPTV không gửi chúng tới dịch vụ phân tích, báo cáo lỗi hay máy chủ của mình, và không ghi chúng vào nhật ký ở bản phát hành.
- Máy chủ tại nhà trong mạng nội bộ vẫn dùng được.
- Nội dung người lớn luôn cần xác nhận 18+ (ở tệp gốc hay trong include).
Phiên bản và giá trị chưa biết
Trường tuỳ chọn và giá trị mới sẽ dần được thêm vào phiên bản 1, tại cùng đường dẫn schema. Khi gặp một giá trị chưa biết, TS IPTV dùng giá trị dự phòng thay vì báo lỗi:
| Giá trị chưa biết ở | Điều gì xảy ra |
|---|---|
type của mục, from của truy vấn | Mục bị bỏ qua. |
sort của truy vấn | Dùng thứ tự source. |
style / corner của thẻ | auto / medium. |
type của kênh | Coi như tv. |
type của include | Include bị bỏ qua (E_INCLUDE). |
mimeType của luồng | Bỏ qua gợi ý. |
drm.system | Luồng không bao giờ được phát khi thiếu DRM; nó không phát được trên thiết bị đó. |
catchup.mode | Không có xem lại; phát trực tiếp vẫn bình thường. |
Thay đổi làm đổi ý nghĩa của các tệp hiện có sẽ là phiên bản 2, với schema mới (tsiptv-source-v2.json); schema phiên bản 1 vẫn được giữ.
Kiểm tra: lỗi và cảnh báo
TS IPTV kiểm tra một nguồn ở ba mức. Lỗi tài liệu khiến tệp bị từ chối. Lỗi mục bỏ mục hoặc trường đó và nhập phần còn lại. Cảnh báo không thay đổi gì nhưng được liệt kê. Mỗi vấn đề được liệt kê dạng đường dẫn — MÃ: giải thích, ví dụ channels[3].url — E_URL: … (phần giải thích là một câu ngắn theo ngôn ngữ của ứng dụng).
| Mã | Mức | Khi nào | Người xem thấy gì |
|---|---|---|---|
E_NOT_JSON | tài liệu | Không phải JSON, hoặc gốc không phải đối tượng | “Tệp này không phải JSON hợp lệ.” |
E_NOT_SOURCE | tài liệu | Thiếu format hoặc sai giá trị | “Đây không phải tệp TS IPTV Source.” |
E_VERSION | tài liệu | Thiếu version, không phải số nguyên ≥ 1, hoặc mới hơn ứng dụng | “Nguồn này cần phiên bản TS IPTV mới hơn.” |
E_TOO_LARGE | tài liệu | Lớn hơn 5 MiB | “Nguồn này lớn hơn 5 MB.” |
E_ID, E_META | tài liệu | Thiếu hoặc sai id, meta hay meta.name | “Nguồn này thiếu id hoặc tên.” |
E_EMPTY | tài liệu | Không có mục và include nào (hoặc tất cả đều bị bỏ) | “Nguồn này không có nội dung nào TS IPTV hiển thị được.” |
E_ITEM_ID | mục | Thiếu hoặc sai id; số mùa hay số tập bị thiếu hoặc ngoài khoảng; một phần tử không phải đối tượng | Trước khi nhập: “N mục sẽ bị bỏ qua” kèm Chi tiết. Sau khi nhập: thông báo thành công, ví dụ “Đã thêm nguồn: 3 kênh, 1 phim lẻ, 0 phim bộ”, kèm “Đã bỏ qua N mục”. Khi làm mới: đếm trong “Giới thiệu nguồn” (“Số vấn đề ở lần làm mới gần nhất: N”) và liệt kê trong “Các vấn đề tìm thấy”. |
E_DUPLICATE_ID | mục | Id (hoặc số mùa, số tập) đã được dùng | |
E_ITEM_NAME | mục | Thiếu hoặc sai name | |
E_NO_STREAM | mục | Không có url/streams, có cả hai, hoặc không còn luồng hợp lệ; phim bộ hay mùa không còn gì hợp lệ bên trong | |
E_INCLUDE | include | Include không hợp lệ, nguồn được include bị từ chối, hoặc tải lỗi (bản tốt gần nhất được giữ) | |
E_INCLUDE_CYCLE | include | Vòng lặp, hoặc sâu hơn 3 | |
E_URL | trường / mục | URL không hợp lệ (luồng, ảnh hay banner bị bỏ) | Liệt kê trong Chi tiết; không tính vào “N mục sẽ bị bỏ qua”. Mục vẫn được giữ, trừ khi không còn gì phát được (khi đó là E_NO_STREAM). |
E_HEADER_FORBIDDEN | trường | Tên header bị cấm hoặc không hợp lệ; chỉ header đó bị bỏ | |
E_DRM | luồng | DRM không hợp lệ (thiếu đường dẫn giấy phép, khoá sai); luồng bị bỏ | |
W_UNKNOWN_TYPE | cảnh báo | Một giá trị chưa biết được thay bằng giá trị dự phòng | Liệt kê trong Chi tiết; không có gì bị bỏ, trừ khi ghi rõ. |
W_QUERY_REF | cảnh báo | Truy vấn trỏ tới include không tồn tại hoặc include xmltv, truy vấn catalog trỏ tới include không phải stremio, hoặc addon không khai báo danh mục đó; mục bị bỏ qua | |
W_LIMIT | cảnh báo | Chạm giới hạn số lượng; các mục thừa bị bỏ | |
W_CONTRAST | cảnh báo | Một màu được thay để dễ đọc | |
W_TEXT | cảnh báo | Chữ quá dài (bị cắt); xuống dòng hay ký tự điều khiển trong chữ một dòng được thay bằng dấu cách; khoá ngôn ngữ không hợp lệ, hoặc có hơn 30 ngôn ngữ (các mục đó bị bỏ qua) | |
W_FIELD | cảnh báo | Trường tuỳ chọn sai kiểu hay ngoài khoảng, giá trị header không hợp lệ, nguồn xem lại không hợp lệ, mục bố cục hỏng, hoặc một cách dùng sai được bỏ qua; trường đó bị bỏ |
Công cụ kiểm tra trên trình duyệt chạy JSON Schema và các bước kiểm tra tham chiếu trên tệp của bạn trước khi bạn đăng nó.
Ví dụ đầy đủ
Danh sách kênh tối giản
Một kênh phát thật, một kênh giả có header và mã lịch phát sóng, và một đài radio giả.
{
"$schema": "https://tsiptv-8bdd6.web.app/schema/tsiptv-source-v1.json",
"format": "tsiptv-source",
"version": 1,
"id": "app.tsiptv.examples.minimal-live",
"meta": {
"name": "Minimal live list",
"description": "The smallest useful TS IPTV Source: one public test stream that really plays, one placeholder channel that shows how to send HTTP headers, and one placeholder radio station. Replace the example.com links with your own streams.",
"language": "en",
"updatedAt": "2026-09-27T00:00:00Z"
},
"channels": [
{
"id": "hls-test",
"name": "HLS Test Channel",
"number": 1,
"groups": ["Test"],
"description": "Mux public HLS test stream. Video: Big Buck Bunny, (c) Blender Foundation, CC BY 3.0.",
"url": "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
},
{
"id": "example-news",
"name": "Example News (placeholder)",
"number": 2,
"groups": ["News"],
"logo": "https://example.com/logos/news.png",
"epgId": "ExampleNews.us",
"url": "https://cdn.example.com/news/index.m3u8",
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Referer": "https://example.com/"
}
},
{
"id": "example-radio",
"type": "radio",
"name": "Example Radio (placeholder)",
"groups": ["Radio"],
"url": "https://radio.example.com/stream.aac",
"mimeType": "audio/aac"
}
]
}
Không có layout, nên TS IPTV dùng bố cục mặc định: một hàng Radio và một lưới Kênh có chip nhóm.
Phim lẻ và phim bộ, có giao diện và bố cục riêng
{
"$schema": "https://tsiptv-8bdd6.web.app/schema/tsiptv-source-v1.json",
"format": "tsiptv-source",
"version": 1,
"id": "app.tsiptv.examples.vod-catalog",
"revision": 1,
"meta": {
"name": { "en": "Public Domain Cinema", "vi": "Rạp phim Phạm vi công cộng" },
"description": {
"en": "A small movie and series catalog built only from public-domain films on archive.org and a public test stream. It shows a custom appearance and home layout.",
"vi": "Danh mục phim và phim bộ nhỏ, chỉ gồm phim thuộc phạm vi công cộng trên archive.org và một luồng thử nghiệm công khai. Tệp này minh hoạ giao diện và bố cục trang chủ tuỳ chỉnh."
},
"author": { "name": "TS IPTV examples", "url": "https://tsiptv-8bdd6.web.app/guides/tsiptv-source/" },
"homepage": "https://tsiptv-8bdd6.web.app/guides/tsiptv-source/",
"language": "en",
"languages": ["en"],
"updatedAt": "2026-09-27T00:00:00Z",
"license": "Listing: CC0-1.0. Films: public domain (see each item)."
},
"appearance": {
"accent": "#FFB300",
"accentSecondary": "#FF7043",
"background": { "gradient": ["#101014", "#1C1C24"] },
"card": { "style": "poster", "corner": "large", "showTitles": true }
},
"layout": {
"home": [
{
"type": "hero",
"id": "featured",
"items": [
{
"image": "https://archive.org/services/img/his_girl_friday",
"title": "His Girl Friday",
"subtitle": { "en": "Screwball comedy, 1940", "vi": "Hài kịch, 1940" },
"target": "his-girl-friday"
},
{
"image": "https://archive.org/services/img/superman_the_mechanical_monsters",
"title": { "en": "Fleischer Superman", "vi": "Superman của Fleischer" },
"subtitle": { "en": "Animated shorts, 1941–1943", "vi": "Phim hoạt hình ngắn, 1941–1943" },
"target": "fleischer-superman"
}
]
},
{
"type": "row",
"id": "continue",
"title": { "en": "Continue watching", "vi": "Xem tiếp" },
"query": { "from": "continueWatching" },
"card": { "style": "landscape" }
},
{
"type": "row",
"id": "movies",
"title": { "en": "Movies", "vi": "Phim lẻ" },
"query": { "from": "movies", "sort": "yearDesc", "limit": 20 }
},
{
"type": "row",
"id": "series",
"title": { "en": "Series", "vi": "Phim bộ" },
"query": { "from": "series" }
},
{
"type": "grid",
"id": "comedy",
"title": { "en": "Comedy", "vi": "Hài" },
"query": { "from": "movies", "genres": ["Comedy"], "sort": "name" },
"card": { "style": "landscape", "corner": "small" }
}
]
},
"movies": [
{
"id": "his-girl-friday",
"name": "His Girl Friday",
"poster": "https://archive.org/services/img/his_girl_friday",
"backdrop": "https://archive.org/services/img/his_girl_friday",
"description": {
"en": "Howard Hawks' screwball comedy. Public domain (archive.org item his_girl_friday).",
"vi": "Phim hài của Howard Hawks. Thuộc phạm vi công cộng (mục his_girl_friday trên archive.org)."
},
"year": 1940,
"releaseDate": "1940-01-18",
"runtimeMinutes": 92,
"genres": ["Comedy"],
"directors": ["Howard Hawks"],
"countries": ["US"],
"languages": ["en"],
"streams": [
{
"name": { "en": "archive.org, MP4 512 kb/s", "vi": "archive.org, MP4 512 kb/s" },
"url": "https://archive.org/download/his_girl_friday/his_girl_friday_512kb.mp4",
"mimeType": "video/mp4",
"quality": "SD",
"language": "en"
}
]
},
{
"id": "big-buck-bunny",
"name": "Big Buck Bunny",
"description": {
"en": "Open movie by the Blender Foundation, CC BY 3.0, streamed from the Mux public HLS test stream.",
"vi": "Phim mở của Blender Foundation, giấy phép CC BY 3.0, phát từ luồng thử nghiệm HLS công khai của Mux."
},
"year": 2008,
"runtimeMinutes": 10,
"genres": ["Animation", "Comedy"],
"url": "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
"mimeType": "application/x-mpegURL"
}
],
"series": [
{
"id": "fleischer-superman",
"name": { "en": "Fleischer Superman", "vi": "Superman của Fleischer" },
"poster": "https://archive.org/services/img/superman_the_mechanical_monsters",
"backdrop": "https://archive.org/services/img/superman_the_mechanical_monsters",
"description": {
"en": "Fleischer Studios' Superman cartoons, now in the public domain.",
"vi": "Loạt phim hoạt hình Superman của Fleischer Studios, nay thuộc phạm vi công cộng."
},
"year": 1941,
"endYear": 1943,
"genres": ["Animation"],
"countries": ["US"],
"seasons": [
{
"number": 1,
"episodes": [
{
"id": "fleischer-superman-s1e1",
"number": 1,
"name": "The Mechanical Monsters",
"thumbnail": "https://archive.org/services/img/superman_the_mechanical_monsters",
"releaseDate": "1941-11-28",
"runtimeMinutes": 10,
"url": "https://archive.org/download/superman_the_mechanical_monsters/superman_the_mechanical_monsters_512kb.mp4",
"mimeType": "video/mp4"
}
]
}
]
}
]
}
- Chữ bằng tiếng Anh và tiếng Việt;
appearancedùng màu nhấn hổ phách, nền chuyển màu tối và thẻ poster bo góc lớn. - Bố cục: một hero với hai banner làm tay (
targetmở phim lẻ hoặc phim bộ), Xem tiếp, hàng Phim lẻ xếp mới nhất trước, hàng Phim bộ, và lưới Hài lọc theo thể loại với thẻ ngang. - His Girl Friday có một luồng kèm tên, chất lượng và ngôn ngữ; Big Buck Bunny dùng cách viết tắt
url; phim bộ có một mùa với một tập.
Một nguồn ghép từ các include
{
"$schema": "https://tsiptv-8bdd6.web.app/schema/tsiptv-source-v1.json",
"format": "tsiptv-source",
"version": 1,
"id": "app.tsiptv.examples.composed",
"meta": {
"name": { "en": "Composed from includes", "vi": "Ghép từ nguồn bên ngoài" },
"description": {
"en": "This source contains no items of its own. It pulls an M3U playlist, an XMLTV guide, a Stremio addon and another TS IPTV Source, and places each one in its own section. Every include points at a TS IPTV example file with public test or public-domain streams.",
"vi": "Nguồn này không tự chứa mục nào. Nó lấy một danh sách M3U, một lịch phát sóng XMLTV, một addon Stremio và một TS IPTV Source khác, rồi đặt mỗi nguồn vào một mục riêng. Mọi nguồn đều trỏ tới tệp ví dụ của TS IPTV, chỉ chứa luồng thử nghiệm công khai hoặc phim thuộc phạm vi công cộng."
},
"author": { "name": "TS IPTV examples" },
"language": "en",
"updatedAt": "2026-09-27T00:00:00Z"
},
"appearance": {
"accent": "#4FC3F7",
"background": { "color": "#06121C" },
"card": { "style": "auto", "corner": "medium" }
},
"includes": [
{
"id": "live",
"type": "m3u",
"url": "https://tsiptv-8bdd6.web.app/examples/playlist.m3u",
"name": { "en": "Example M3U playlist", "vi": "Danh sách M3U ví dụ" },
"refreshHours": 24
},
{
"id": "guide",
"type": "xmltv",
"url": "https://tsiptv-8bdd6.web.app/examples/guide.xml",
"name": { "en": "Example XMLTV guide", "vi": "Lịch phát sóng XMLTV ví dụ" },
"refreshHours": 12
},
{
"id": "sampler",
"type": "stremio",
"url": "https://tsiptv-8bdd6.web.app/examples/stremio-sampler/manifest.json",
"name": { "en": "Public Domain Sampler addon", "vi": "Addon Public Domain Sampler" }
},
{
"id": "cinema",
"type": "tsiptv-source",
"url": "https://tsiptv-8bdd6.web.app/examples/vod-catalog.tsiptv.json",
"refreshHours": 72
}
],
"layout": {
"home": [
{
"type": "hero",
"id": "hero",
"query": { "from": "movies", "include": "cinema", "limit": 3 }
},
{
"type": "row",
"id": "on-air",
"title": { "en": "On air", "vi": "Đang phát" },
"subtitle": { "en": "From the M3U include, with the XMLTV guide", "vi": "Từ danh sách M3U, kèm lịch phát sóng XMLTV" },
"query": { "from": "channels", "include": "live", "sort": "number" },
"card": { "style": "list" }
},
{
"type": "row",
"id": "addon-movies",
"title": { "en": "From the Stremio addon", "vi": "Từ addon Stremio" },
"query": { "from": "catalog", "include": "sampler", "catalog": { "type": "movie", "id": "tspd-movie" } },
"card": { "style": "poster" }
},
{
"type": "row",
"id": "cinema-series",
"title": { "en": "Series", "vi": "Phim bộ" },
"query": { "from": "series", "include": "cinema" }
},
{
"type": "row",
"id": "picked",
"title": { "en": "Picked by hand", "vi": "Chọn tay" },
"query": { "from": "movies", "ids": ["cinema:big-buck-bunny", "cinema:his-girl-friday"] },
"card": { "style": "landscape" },
"seeAll": false
},
{
"type": "grid",
"id": "all-channels",
"title": { "en": "All channels", "vi": "Tất cả kênh" },
"query": { "from": "channels", "sort": "number" },
"groupChips": true
}
]
}
}
- Không có mục riêng: một danh sách M3U (
live), một lịch XMLTV (guide), addon mẫu (sampler) và nguồn vod-catalog ở trên (cinema). - Hero hiện phim từ
cinema; “Đang phát” liệt kê các kênh M3U dạng danh sách kèm chương trình đang phát; một hàng hiện danh mục phim của addon;idschọn hai phim bằng id có tiền tố (cinema:big-buck-bunny); lưới cuối hiện mọi kênh kèm chip nhóm.
Tự tạo nguồn của bạn, từng bước
- Bắt đầu từ tệp tối giản. Tải minimal-live.tsiptv.json và mở bằng VS Code (dòng
$schemacho bạn gợi ý tự động và gạch đỏ dưới lỗi). Đổiidthành tên miền đảo ngược của riêng bạn (com.example.mytv) và đổimeta.name. - Thêm các kênh. Mỗi kênh một đối tượng, có
id,name,url, và tuỳ chọnnumber,logo,groups,epgId,headers:Thêm lịch phát sóng bằng{ "id": "news-hd", "name": "Example News HD", "number": 10, "groups": ["News"], "logo": "https://example.com/logos/news.png", "epgId": "ExampleNews.us", "url": "https://cdn.example.com/news/index.m3u8", "headers": { "User-Agent": "Mozilla/5.0", "Referer": "https://example.com/" } }"epg": ["https://example.com/guide.xml.gz"]. - Thêm phim lẻ và một phim bộ. Phim lẻ cần
id,namevàurl(hoặcstreams); thêmposter,backdrop,year,genresvàdescriptionđể có trang chi tiết đẹp. Phim bộ cầnseasons→episodes, mỗi tập cóidriêng không trùng,number,namevàurl. - Thêm giao diện và bố cục. Chọn màu nhấn nổi bật trên nền tối, rồi liệt kê các mục:
"appearance": { "accent": "#FFB300", "card": { "style": "poster", "corner": "large" } }, "layout": { "home": [ { "type": "hero", "query": { "from": "movies", "limit": 5 } }, { "type": "row", "title": "News", "query": { "from": "channels", "groups": ["News"] }, "card": { "style": "logo" } }, { "type": "row", "title": "New movies", "query": { "from": "movies", "sort": "yearDesc" } }, { "type": "grid", "title": "All channels", "query": { "from": "channels", "sort": "number" }, "groupChips": true } ] } - Dịch. Thay một chuỗi thường bằng
{ "en": "…", "vi": "…" }ở bất cứ đâu bạn muốn thêm ngôn ngữ, và đặtmeta.languagelà ngôn ngữ của các chuỗi thường. - Kiểm tra. Sửa mọi chỗ VS Code gạch dưới, hoặc dán tệp vào công cụ kiểm tra. Bảo đảm mọi id đều không trùng và không có
:. - Đưa tệp lên mạng (phần tiếp theo), thêm vào TS IPTV, rồi đọc màn hình xem trước: các con số, danh sách máy chủ và các mục bị bỏ qua. Khi đăng thay đổi về sau, hãy giữ nguyên đường dẫn và
id, và tăngrevision.
Đã có sẵn danh sách M3U? Bạn không cần chuyển đổi: hãy thêm nó thành một include m3u rồi sắp xếp kênh của nó bằng truy vấn.
Đưa tệp lên mạng
- Mọi máy chủ HTTPS tĩnh trả về chính nội dung tệp đều dùng được:
https://raw.githubusercontent.com/<user>/<repo>/<branch>/my.tsiptv.json,https://<user>.github.io/<repo>/my.tsiptv.json,https://www.example.com/my.tsiptv.json. Trang chia sẻ và đường dẫnblob/của GitHub không dùng được; xem đưa tệp M3U lên mạng. Bạn cũng có thể không cần đưa lên mạng mà dùng Nhập từ tệp. - HTTPS được khuyến nghị; đường dẫn
httpvẫn dùng được nhưng không được mã hoá. - Loại nội dung:
application/json(hoặctext/plain); dù sao TS IPTV cũng nhận dạng theo nội dung. - Nén: nên dùng
Content-Encoding: gzipcho tệp lớn. Giới hạn 5 MiB tính sau khi giải nén. - Bộ nhớ đệm: TS IPTV làm mới tệp gốc như một danh sách phát (khi cũ hơn 24 giờ, hoặc khi bấm Làm mới) và làm mới từng include sau
refreshHourscủa nó. Với chính tệp và với từng include, ứng dụng gửiIf-None-Match/If-Modified-Sincekhi máy chủ của bạn đã trả vềETaghoặcLast-Modified; trả lời304 Not Modifiedgiúp tiết kiệm băng thông và tính là 0 trong hạn mức 50 MiB. - CORS không cần cho TS IPTV. Chỉ thêm
Access-Control-Allow-Origin: *nếu muốn các công cụ web đọc được tệp. - Giữ đường dẫn cố định. Cùng
idtừ cùng đường dẫn là bản cập nhật; từ đường dẫn khác, TS IPTV sẽ hỏi có thay thế nguồn hiện có không.
Thêm vào TS IPTV
- Mở Thêm nguồn IPTV, dán đường dẫn vào Liên kết nguồn rồi chọn Thêm IPTV, hoặc chọn Nhập từ tệp. TS IPTV nhận ra định dạng qua nội dung.
- Hộp thoại xem trước “Thêm nguồn này?” mở ra (chưa lưu gì): logo, tên, tác giả, mô tả, số kênh, radio, phim lẻ và phim bộ, “Nguồn này kết nối tới các máy chủ sau” (máy chủ của tệp và của mọi include), “N mục sẽ bị bỏ qua” kèm Chi tiết (mở “Chi tiết nhập”) nếu có mục không hợp lệ, thông báo rằng nguồn do bên thứ ba tạo, và ô “Tôi đủ 18 tuổi trở lên” nếu nguồn được đánh dấu người lớn.
- Chọn Nhập. TS IPTV tải các include (“Đang tải 2 trên 4…”). Nếu một include hoá ra có nội dung người lớn, ứng dụng hỏi lại (“Một phần nội dung của nguồn này đến từ nguồn hoặc addon có nội dung người lớn.” kèm “Tôi đủ 18 tuổi trở lên”); chọn Hủy thì không lưu gì. Sau đó ứng dụng lưu mọi thứ, báo ví dụ “Đã thêm nguồn: 3 kênh, 1 phim lẻ, 0 phim bộ” (kèm “Đã bỏ qua N mục” nếu có) rồi mở trang chủ của nguồn. Trên điện thoại, thẻ Trang chủ có hai phần Trang chủ (bố cục của bạn) và Kênh (danh sách kênh quen thuộc); trên TV, thanh bên bắt đầu bằng Trang chủ.
- Tìm kiếm, Xem tiếp và kênh yêu thích hoạt động trong phạm vi nguồn. Giới thiệu nguồn (điện thoại: trong menu của trang chủ nguồn; TV: một mục trên thanh bên) hiện tác giả; nút Trang web, hỏi “Mở … trong trình duyệt?” (trên TV không có trình duyệt, đường dẫn được hiện dưới dạng chữ); trạng thái từng include (“Đã cập nhật”, “Không làm mới được — đang hiện bản từ …”, “Không tải được”, hoặc “Đang tạm giữ cho tới khi xác nhận 18+” kèm nút Xác nhận); lần làm mới gần nhất với “Số vấn đề ở lần làm mới gần nhất: N” và nút Chi tiết (“Các vấn đề tìm thấy”); cùng nút Làm mới và Gỡ nguồn.
- Nếu làm mới chính tệp nguồn bị lỗi, phần giới thiệu thêm dòng “Lần thử gần nhất: …”; sau khi bạn tự bấm Làm mới, trang chủ còn báo “Không làm mới được nguồn này. Đang hiện bản đã lưu.”. TS IPTV sẽ thử lại theo lịch bình thường.
Nếu tệp có lỗi tài liệu, TS IPTV báo “Không thể thêm nguồn này” với thông báo trong bảng ở trên và nút Chi tiết cho biết mã và đường dẫn. Nếu mọi include đều lỗi và tệp không có mục riêng nào, ứng dụng báo “Không tải được nội dung nào của nguồn này. Hãy thử lại sau.”
Lỗi thường gặp
| Lỗi | Biểu hiện | Cách sửa |
|---|---|---|
Có cả url và streams trong một mục | Mục bị bỏ qua (E_NO_STREAM) | Chỉ dùng một: url cho một luồng, streams cho nhiều lựa chọn. |
Có : trong id (news:hd) | Mục bị bỏ qua (E_ITEM_ID; với include là E_INCLUDE) | Dùng -, _ hoặc .; dấu hai chấm dành cho mục được include. |
| Một id dùng hai lần (kể cả giữa kênh, phim lẻ, tập và include) | Mục thứ hai bị bỏ qua (E_DUPLICATE_ID) | Đặt id không trùng trong cả tệp. |
Luồng rtmp://, rtsp:// hay udp:// | Luồng bị bỏ (E_URL); mục chỉ có luồng đó bị bỏ qua (E_NO_STREAM) | Ở đây chỉ cho phép http(s). Hãy đưa các kênh đó vào một danh sách M3U và thêm thành include m3u; khi đó phát được hay không tuỳ trình phát của từng nền tảng. |
Hero có cả items và query | Dùng items (W_FIELD) | Chỉ giữ một. |
groupChips trên lưới phim lẻ hoặc trên một hàng | Không có chip | Chip nhóm chỉ dùng cho lưới channels hoặc radio. |
| Màu tương phản thấp (nền sáng, màu nhấn tối) | Màu của bạn bị thay (W_CONTRAST) | Dùng nền tối và màu nhấn có độ tương phản ít nhất 3:1 với nền. |
Truy vấn trỏ tới id include không tồn tại, hoặc tới include xmltv | Mục không hiện (W_QUERY_REF) | Dùng đúng id của include; lịch phát sóng không thể là một mục. |
Gõ sai tên trường (nmae) | Ứng dụng bỏ qua trường đó; trường bắt buộc khi đó bị thiếu | Dùng dòng $schema hoặc công cụ kiểm tra; chúng báo trường không xác định. |
| Có chú thích hoặc dấu phẩy thừa | “Tệp này không phải JSON hợp lệ.” | Xoá chúng; dùng trường x- để ghi chú. |
Ảnh http:// trên máy chủ chuyển hướng hoặc chặn | Thiếu ảnh bìa | Dùng URL ảnh https. |
Id của include bắt đầu bằng epg- | Include bị bỏ (E_INCLUDE) | Tiền tố này dành cho các đường dẫn epg. |
URL của include stremio không có /manifest.json | Include bị bỏ (E_INCLUDE) | Dùng đường dẫn manifest của addon. |
Có dấu cách trong source của xem lại (chế độ default hoặc append) | Mất xem lại, kênh chỉ phát trực tiếp (W_FIELD) | Mã hoá dấu cách thành %20. |
TS IPTV hỗ trợ những gì
| Tính năng | Android | iOS | Máy tính |
|---|---|---|---|
| Nhập bằng đường dẫn hoặc tệp, xem trước, bố cục, giao diện, tìm kiếm, Xem tiếp | Hỗ trợ | Chưa kiểm chứng | Hỗ trợ |
| Kênh, radio, phim lẻ, phim bộ; nhiều luồng mỗi mục (kênh: “Tuỳ chọn phát”; phim lẻ và tập phim: trang chi tiết) | Hỗ trợ | Chưa kiểm chứng | Hỗ trợ |
| Header | Mọi header | Chưa kiểm chứng | Chỉ User-Agent và Referer |
Luồng DASH .mpd không có DRM | Hỗ trợ | Chưa kiểm chứng qua trình phát VLC tích hợp; chỉ gửi header User-Agent và Referer | Hỗ trợ |
| DRM (Widevine, PlayReady; ClearKey cho DASH) | Chỉ Android | Không hỗ trợ | Không hỗ trợ |
| Phụ đề (VTT, SRT), mặc định tắt | Hỗ trợ | Chưa có | Chưa kiểm chứng |
Include: m3u, xmltv, stremio, tsiptv-source | Hỗ trợ Addon tương thích Stremio chỉ phát luồng url. | ||
| Xem lại (catch-up) | Được lưu, phát lại sẽ có sau | ||
| Banner mở trang web | Không thuộc định dạng | ||
iOS: phần hỗ trợ TS IPTV Source chưa được build và kiểm tra trên iPhone và iPad, nên các ô đó ghi “Chưa kiểm chứng”. DRM không có trên iOS theo thiết kế. Luồng DASH không có DRM phát được trên iPhone và iPad qua trình phát VLC tích hợp, trình phát này chỉ gửi header User-Agent và Referer; DASH có DRM thì không hỗ trợ trên các thiết bị đó. Máy tính: các tính năng ghi “Hỗ trợ” đã được build, nhưng ứng dụng máy tính chưa được kiểm tra với TS IPTV Source; phụ đề trên máy tính “Chưa kiểm chứng”.