Files
iptvc/README.md
T
2026-07-15 10:02:40 +08:00

305 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IPTV Checker (iptvc)
[![Последний релиз](https://img.shields.io/gitea/v/release/IPTV/iptvc?gitea_url=https%3A%2F%2Fgit.axenov.dev&display_name=release&color=green&cacheSeconds=600)](https://git.axenov.dev/IPTV/iptvc/releases/latest)
Консольная программа для проверки IPTV-плейлистов в формате m3u или m3u8.
> **Веб-сайт:** [m3u.su](https://m3u.su)
> Документация: [m3u.su/docs](https://m3u.su/docs)
> Telegram-канал: [@iptv_aggregator](https://t.me/iptv_aggregator)
> Исходный код: [git.axenov.dev/IPTV](https://git.axenov.dev/IPTV)
## Установка
Достаточно скачать и распаковать архив с подходящим исполняемым файлом [со страницы последнего релиза](https://git.axenov.dev/IPTV/iptvc/releases/latest):
| ОС | Скачать для `amd64` | Скачать для `arm64` |
| ------- | ---------------------------------- | ---------------------------------- |
| Linux | [linux_amd64.zip][linux_amd64] | [linux_arm64.zip][linux_arm64] |
| MacOS | [darwin_amd64.zip][darwin_amd64] | [darwin_arm64.zip][darwin_arm64] |
| Windows | [windows_amd64.zip][windows_amd64] | [windows_arm64.zip][windows_arm64] |
[linux_amd64]: https://git.axenov.dev/IPTV/iptvc/releases/download/latest/linux_amd64.zip
[darwin_amd64]: https://git.axenov.dev/IPTV/iptvc/releases/download/latest/darwin_amd64.zip
[windows_amd64]: https://git.axenov.dev/IPTV/iptvc/releases/download/latest/windows_amd64.zip
[linux_arm64]: https://git.axenov.dev/IPTV/iptvc/releases/download/latest/linux_arm64.zip
[darwin_arm64]: https://git.axenov.dev/IPTV/iptvc/releases/download/latest/darwin_arm64.zip
[windows_arm64]: https://git.axenov.dev/IPTV/iptvc/releases/download/latest/windows_arm64.zip
## Компиляция
Для сборки потребуется golang v1.23.6 и выше.
На версиях ниже не проверялось.
1. Склонировать репозиторий
2. Находясь в корне репозитория, следует выполнить `make` или `make help` для получения справки.
3. Другой способ — выполнить `go run .` для быстрого запуска.
## Быстрый старт
Открыть терминал в директории, куда распакован исполняемый файл `iptvc`.
Выполнить `./iptvc help` для получения краткой справки.
Если был клонирован репозиторий, то вместо `./iptvc` можно запустить `go run .`
Ниже рассмотрены простые примеры использования программы для проверки плейлистов.
### Проверка файла плейлиста
1. Скачать любой файл плейлиста, сохранив его в файл с именем, например, `mypls.m3u`
2. Выполнить команду `./iptvc check -f mypls.m3u`
Можно указывать множество разных файлов (каждый с `-f`) и комбинировать с другими аргументами.
### Проверка плейлиста по ссылке
1. Найти прямую ссылку на плейлист в интернете, например, `http://m3u.su/XYZ`
2. Выполнить команду `./iptvc check -u http://m3u.su/XYZ`
Можно указывать множество разных ссылок (каждый с `-u`) и комбинировать с другими аргументами.
### Проверка плейлиста из ini-списка
Подробности об ini-файле и его формате можно прочесть здесь: https://git.axenov.dev/IPTV/playlists
1. Скачать файл [`playlists.ini`](https://git.axenov.dev/IPTV/playlists/raw/branch/master/playlists.ini) или создать локальный файл в аналогичном формате (например, `./test.ini`)
2. Выполнить команду `./iptvc check` или `./iptvc check -i playlist.ini` для проверки всех плейлистов из файла `./playlists.ini`
3. Выполнить команду `./iptvc check -i test.ini -c ABC`, чтобы проверить только плейлист с кодом `ABC` из файла `./test.ini`
Если `-i` не указан явно, то будет попытка прочитать файл `playlists.ini`, находящийся в одной директории с iptvc.
Аргумент `-i` можно указывать только однажды, но его можно комбинировать с `-f` и `-u`.
### Другие возможности команды `check`
* `--random|-r X` — проверить X случайных плейлистов из ini-файла
* `--json|-j` — вывести результаты проверки в формате JSON
* `--quiet|-q` — полностью подавить вывод лога (включая отладочную информацию)
* `--verbose|-v` — добавить в лог более подробную отладочную информацию (значительно увеличит количество строк!)
* `--tags|-t` — файл с перечислением тегов (подробности см. [здесь](https://git.axenov.dev/IPTV/playlists#файл-channelsjson))
Например, можно получить только json с результатами, передать его в `jq` и, отфильтровав результат, вывести названия оффлайн каналов:
```
./iptvc check ... -j -q | jq '.[].channels[] | select(.isOnline == false).title'
```
> [!NOTE]
> Набери `./iptvc help` для получения помощи.
## Веб-интерфейс
Программа включает встроенный веб-сервер для просмотра плейлистов и результатов их проверки.
### Запуск
```
./iptvc serve -i playlists.ini -p 8080
```
### Параметры команды `serve`
* `-p, --port` — порт для веб-сервера (переопределяет `config.yml` и `WEB_PORT`);
* `--host` — хост для привязки (переопределяет `config.yml` и `WEB_HOST`);
* `--check` — включить фоновую проверку плейлистов (по умолчанию выключена).
При указании `--check` доступны флаги проверки:
* `-i, --ini` — путь к ini-файлу (по умолчанию `./playlists.ini`);
* `-t, --tags` — путь к файлу тегов (по умолчанию `./channels.json`);
* `-r, --random` — проверить N случайных плейлистов из ini-файла;
* `--every` — интервал между проверками в секундах (по умолчанию `60`);
* `--repeat` — количество циклов проверки (по умолчанию `0` — бесконечно).
### Конфигурация
Приоритет настроек (от низшего к высшему):
1. **Значения по умолчанию** — встроены в код;
2. **`config.yml`** — YAML-файл в корне проекта (путь можно задать через флаг `--config`);
3. **Переменные окружения** — переопределяют значения из `config.yml` (если заданы);
4. **CLI-флаги** — переопределяют значения из окружения и `config.yml` (если заданы явно).
Флаги `--port` и `--host` переопределяют конфигурацию только если переданы явно.
Если флаг не указан, используется значение из переменной окружения, затем из `config.yml`,
затем значение по умолчанию.
Файл `.env` загружается автоматически, переменные из него применяются как переменные окружения.
#### `config.yml`
```yaml
app:
title: IPTV Checker
timezone: GMT
debug: false
log_level: info
server:
host: localhost
port: 8080
base_url: http://localhost:8080
page_size: 0
repo_url: https://git.axenov.dev/IPTV
check:
playlists:
user-agent:
- Mozilla/5.0 WINK/1.31.1 (AndroidTV/9) HlsWinkPlayer
timeout: [0, 10000] # ms, макс время ожидания ответа при проверке каждого плейлиста
all-cooldown: [0, 10000] # ms, задержка между проверками всех плейлистов
one-cooldown: [0, 10000] # ms, задержка между проверками каждого плейлиста
per-routine: [0, 10000] # количество одновременно проверяемых плейлистов
channels:
user-agent: Mozilla/5.0 WINK/1.31.1 (AndroidTV/9) HlsWinkPlayer
timeout: 10 # sec, макс время ожидания ответа при проверке каждого канала
byte-range: 512 # bytes, количество байт для получения от сервера
all-cooldown: 0 # ms, задержка между проверками всех каналов плейлиста
one-cooldown: 0 # ms, задержка между проверками каждого канала плейлиста
per-routine: 10 # количество одновременно проверяемых каналов
cache:
enabled: false
host: localhost
port: 6379
username:
password:
db: 1
ttl: 1800
```
Параметры `check.playlists` и `check.channels` (кроме `byte-range`) могут быть заданы как скаляр или массив `[min, max]`. При массиве каждый раз выбирается случайное значение в диапазоне. `user-agent` может быть строкой или массивом строк (случайный выбор). `byte-range` — всегда целое число.
#### Переменные окружения
| Переменная | Соответствует в `config.yml` | Описание |
| ---------------- | ---------------------------- | ----------------------------------- |
| `APP_DEBUG` | `app.debug` | Режим отладки |
| `APP_TITLE` | `app.title` | Заголовок сайта |
| `APP_TIMEZONE` | `app.timezone` | Часовой пояс |
| `APP_URL` | `server.base_url` | Базовый URL для ссылок |
| `CACHE_ENABLED` | `cache.enabled` | Включить кеш (KeyDB/Redis) |
| `CACHE_HOST` | `cache.host` | Хост KeyDB/Redis |
| `CACHE_PORT` | `cache.port` | Порт KeyDB/Redis |
| `CACHE_USERNAME` | `cache.username` | Имя пользователя KeyDB/Redis |
| `CACHE_PASSWORD` | `cache.password` | Пароль KeyDB/Redis |
| `CACHE_DB` | `cache.db` | Номер БД KeyDB/Redis |
| `CACHE_TTL` | `cache.ttl` | TTL записей в кеше (сек) |
| `WEB_PORT` | `server.port` | Порт веб-сервера |
| `WEB_HOST` | `server.host` | Хост для привязки |
| `PAGE_SIZE` | `server.page_size` | Размер страницы (0 — без пагинации) |
| `REPO_URL` | `server.repo_url` | Ссылка на репозиторий |
### Маршруты
| Метод | Путь | Описание |
| ----- | ----------------------- | ---------------------------------------- |
| GET | `/` | Главная страница со списком плейлистов |
| GET | `/page/{N}` | Страница N списка плейлистов |
| GET | `/{code}` | Редирект на прямую ссылку плейлиста |
| GET | `/{code}.m3u[8]` | Редирект на прямую ссылку плейлиста |
| GET | `/{code}/details` | Страница с описанием плейлиста |
| GET | `/api/playlists/{code}` | JSON: информация о плейлисте |
| GET | `/api/version` | JSON: версии компонентов |
| GET | `/api/health` | JSON: состояние сервиса |
| GET | `/api/stats` | JSON: статистика по плейлистам и каналам |
### Связь с проверкой
Веб-сервер отображает данные из кеша KeyDB/Redis, который заполняется командой `check`.
Если кеш недоступен, все плейлисты отображаются со статусом `unknown`.
Для обновления данных в фоне запустите `serve` с флагом `--check`:
```
./iptvc serve -i playlists.ini -p 8080 --check
```
Результаты проверок появляются на веб-страницах немедленно после проверки каждого
плейлиста, не дожидаясь завершения полного цикла.
Можно запускать `serve` и `check` отдельными процессами:
```
./iptvc check --repeat 0 --every 60 &
./iptvc serve
```
Или используйте docker-окружение проекта.
## Результаты проверки
Программа логирует процесс и результаты своей работы.
Рассмотрим лог на примере.
В рабочей директории лежит файл `playlists.ini`, в котором минимально описано два плейлиста:
```ini
[first]
pls='https://example.com/list1.m3u'
[second]
pls='https://example.com/list2.m3u'
```
Программа запущена следующим образом: `./iptvc check -c first` (чтобы проверить только плейлист с кодом `first` из ini-файла).
Вывод будет примерно таким:
```
2025/01/02 12:34:00 Loading playlists from ini-file: /home/user/playlists.ini
2025/01/02 12:34:00 Loaded 2 playlists
2025/01/02 12:34:00 [001/001] Playlist [first]
2025/01/02 12:34:00 Fetching... (https://example.com/list1.m3u)
2025/01/02 12:34:00 Parsing content...
2025/01/02 12:34:00 Parsed, checking channels (114)...
2025/01/02 12:34:00 Check parameters calculated: count=114 timeout=8.00s routines=12
2025/01/02 12:34:12 Checked successfully! online=101 onlinePercent=88.60% offline=13 offlinePercent=11.40% elapsedTime=12.39s
```
Разберём построчно:
1. Загрузка ini-файла
2. Файл загружен, в нём 2 плейлиста
3. Начало обработки плейлиста `first`
4. Скачивание плейлиста `first` по ссылке `https://example.com/list1.m3u` в оперативную память
5. Плейлист скачан, начало разбора плейлиста
6. Плейлист разобран, начало проверки каналов (114 штук)
7. Определены параметры проверки (подробности ниже)
8. (спустя время) Проверка успешно завершена: онлайн каналов 101 (88.60% от всех), оффлайн каналов 13 (11.40% от всех), затрачено 12 секунд.
### Параметры проверки
Выше в п.7 видно некоторые служебные данные:
* `timeout` — таймаут каждого запроса в секундах (макс. время ожидания ответа канала);
* `routines` — количество одновременных проверок.
Эти параметры рассчитываются динамически для каждого плейлиста в отдельности, исходя из количества каналов в каждом (`count`).
См. [app/checker/checker.go](app/checker/checker.go) для подробностей.
Идея в том, чтобы найти баланс между скоростью проверки и качеством:
* чем ниже коэффициент `k`, тем больше горутин, меньше таймаут, быстрее проверка, хуже результаты;
* чем выше коэффициент `k`, тем меньше горутин, больше таймаут, медленнее проверка, лучше результаты.
На скорость проверки влияют:
* количество горутин (чем выше, тем больше каналов проверяется параллельно);
* таймаут (тем ниже, тем быстрее закончится проверка канала);
* количество каналов (чем больше, тем дольше общий процесс);
* скорость ответа сервера (чем выше, тем хуже) и количество данных, которые он отдаёт (чем больше, тем хуже).
На качество проверки влияет таймаут:
* чем выше, тем выше вероятность получить успешный ответ от сервера, транслирующего поток;
* чем ниже, тем выше вероятность не дождаться успешного ответа и засчитать канал нерабочим.
> [!NOTE]
> Логика балансирования будет уточняться и корректироваться по мере развития проекта, исходя из реального применения.
### Коды возврата
* 0 — успех
* 1 — общая ошибка, см. вывод
* 2 — команде `check` не переданы параметры `--file`, `--url` и `--code`
## Лицензия
ПО распространяется на условиях [лицензии MIT](LICENSE).