454 lines
28 KiB
Markdown
454 lines
28 KiB
Markdown
# IPTV Checker (iptvc)
|
||
|
||
[](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
|
||
|
||
## Компиляция
|
||
|
||
Для сборки потребуется Go версии 1.23.6 или выше.
|
||
Контейнерная сборка выполняется на Go 1.25.
|
||
|
||
```bash
|
||
git clone https://git.axenov.dev/IPTV/iptvc.git
|
||
cd iptvc
|
||
make help
|
||
```
|
||
|
||
### Цели Makefile
|
||
|
||
| Цель | Описание |
|
||
| --------- | --------------------------------------------------------------- |
|
||
| `help` | Показать список доступных целей (по умолчанию) |
|
||
| `build` | Собрать бинарный файл для текущей платформы в `bin/iptvc` |
|
||
| `linux` | Собрать Linux-бинарник и ZIP-архив в `bin/linux_$(GOARCH)/` |
|
||
| `win` | Собрать Windows-бинарник и ZIP-архив в `bin/windows_$(GOARCH)/` |
|
||
| `darwin` | Собрать macOS-бинарник и ZIP-архив в `bin/darwin_$(GOARCH)/` |
|
||
| `release` | Собрать все платформы (`amd64` и `arm64`) и упаковать в ZIP |
|
||
| `clear` | Удалить все собранные бинарники и очистить кеш Go |
|
||
| `image` | Собрать и отправить Docker-образ |
|
||
|
||
### Переменные Makefile
|
||
|
||
| Переменная | По умолчанию | Описание |
|
||
| ------------- | ---------------------------- | ----------------------------------------- |
|
||
| `BINARY_NAME` | `iptvc` | Имя бинарного файла |
|
||
| `GOOS` | `go env GOOS` | Целевая ОС (`linux`, `windows`, `darwin`) |
|
||
| `GOARCH` | `go env GOARCH` | Целевая архитектура (`amd64`, `arm64`) |
|
||
| `IMAGE_TAG` | `latest` | Тег Docker-образа |
|
||
| `VERSION` | `git describe --tags ...` | Версия, вшиваемая в бинарник |
|
||
| `COMMIT` | `git rev-parse --short HEAD` | Коммит, вшиваемый в бинарник |
|
||
|
||
### Примеры сборки
|
||
|
||
```bash
|
||
# Быстрая сборка для текущей платформы
|
||
make build
|
||
|
||
# Сборка для Linux amd64
|
||
make linux GOARCH=amd64
|
||
|
||
# Сборка для Windows arm64
|
||
make win GOARCH=arm64
|
||
|
||
# Сборка всех релизных архивов
|
||
make release
|
||
|
||
# Сборка Docker-образа с тегом
|
||
make image IMAGE_TAG=1.0.0
|
||
```
|
||
|
||
### Запуск из исходников
|
||
|
||
Для быстрого запуска без сборки используйте `go run .`.
|
||
Для запуска тестов и статического анализа:
|
||
|
||
```bash
|
||
go test ./...
|
||
go vet ./...
|
||
```
|
||
|
||
## Быстрый старт
|
||
|
||
Открыть терминал в директории, куда распакован исполняемый файл `iptvc`.
|
||
|
||
Выполнить `./iptvc help` для получения краткой справки.
|
||
|
||
Если был клонирован репозиторий, то вместо `./iptvc` можно запустить `go run .` или `make help`.
|
||
|
||
Ниже рассмотрены простые примеры использования программы для проверки плейлистов.
|
||
|
||
### Проверка файла плейлиста
|
||
|
||
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`
|
||
|
||
Источники плейлистов:
|
||
|
||
* `--file|-f PATH` — локальный файл плейлиста M3U/M3U8; флаг можно указывать несколько раз;
|
||
* `--url|-u URL` — удалённый плейлист по HTTP/HTTPS; флаг можно указывать несколько раз;
|
||
* `--code|-c CODE` — код плейлиста из ini-файла; флаг можно указывать несколько раз;
|
||
* `--ini|-i PATH` — путь к ini-файлу;
|
||
* `--tags|-t PATH` — путь к файлу тегов каналов.
|
||
|
||
Управление выводом и повторными проверками:
|
||
|
||
* `--json|-j` — вывести результаты проверки в формате JSON;
|
||
* `--quiet|-q` — подавить журналы, не отключая вывод JSON;
|
||
* `--verbose|-v` — включить подробный журнал;
|
||
* `--random|-r N` — выбрать N случайных плейлистов из ini-файла;
|
||
* `--repeat N` — повторить проверку N раз, значение `0` означает бесконечный цикл;
|
||
* `--playlists-all-cooldown N` — ждать N секунд между полными циклами проверки; значение также можно задать через `check.playlists.all-cooldown`.
|
||
|
||
Параметры проверки и кеша также можно переопределить CLI-флагами.
|
||
Полный список доступен через `./iptvc check --help`.
|
||
|
||
Например, можно получить только json с результатами, передать его в `jq` и, отфильтровав результат, вывести названия оффлайн каналов:
|
||
|
||
```
|
||
./iptvc check ... -j -q | jq '.[].channels[] | select(.isOnline == false).title'
|
||
```
|
||
|
||
> [!NOTE]
|
||
> Набери `./iptvc help` для получения помощи.
|
||
|
||
## Веб-интерфейс
|
||
|
||
Программа включает встроенный веб-сервер для просмотра плейлистов и результатов их проверки.
|
||
|
||
### Запуск
|
||
|
||
```
|
||
./iptvc serve -i playlists.ini -p 8800
|
||
```
|
||
|
||
### Параметры команды `serve`
|
||
|
||
* `-p, --port` — порт для веб-сервера (переопределяет `config.yml` и `SERVER_PORT`);
|
||
* `--host` — хост для привязки (переопределяет `config.yml` и `SERVER_HOST`);
|
||
* `--check` — включить фоновую проверку плейлистов (по умолчанию выключена).
|
||
|
||
При указании `--check` доступны флаги проверки:
|
||
|
||
* `-i, --ini` — путь к ini-файлу (по умолчанию `./playlists.ini`);
|
||
* `-t, --tags` — путь к файлу тегов (по умолчанию `./channels.json`);
|
||
* `--playlists-all-cooldown N` — пауза между полными циклами проверки в секундах; если флаг не указан, используется `check.playlists.all-cooldown` из конфигурации;
|
||
* `--repeat` — количество циклов проверки (по умолчанию `0` — бесконечно).
|
||
|
||
### Конфигурация
|
||
|
||
Приоритет настроек (от низшего к высшему):
|
||
|
||
1. **Значения по умолчанию** — встроены в код;
|
||
2. **`config.yml`** — YAML-файл в корне проекта (путь можно задать через флаг `--config`);
|
||
3. **Переменные окружения** — переопределяют значения из `config.yml` (если заданы);
|
||
4. **CLI-флаги** — переопределяют значения из окружения и `config.yml` (если заданы явно).
|
||
|
||
Флаги `--port` и `--host` переопределяют конфигурацию только если переданы явно.
|
||
Если флаг не указан, используется значение из переменной окружения, затем из `config.yml`,
|
||
затем значение по умолчанию.
|
||
|
||
Файл `.env` загружается автоматически, переменные из него применяются как переменные окружения.
|
||
|
||
#### `config.yml`
|
||
|
||
```yaml
|
||
app:
|
||
timezone: GMT
|
||
debug: false
|
||
log_level: info
|
||
playlists: ./playlists.ini
|
||
tags: ./channels.json
|
||
|
||
server:
|
||
host: ""
|
||
port: 8800
|
||
|
||
site:
|
||
base-url: http://localhost:8800
|
||
repo-url: https://git.axenov.dev/IPTV
|
||
page-size: 0
|
||
favicon: # опциональный путь к иконке
|
||
title: IPTV Checker
|
||
meta:
|
||
description: Самообновляемые бесплатные IPTV-плейлисты для домашнего просмотра по коротким ссылкам, списки каналов, проверка доступности
|
||
keywords: самообновляемые,бесплатные,iptv-плейлисты,iptv,плейлисты
|
||
tabs:
|
||
raw:
|
||
visible: true
|
||
legal:
|
||
visible: true
|
||
text: |
|
||
Данные, представленные на данной странице, получены автоматически из открыто доступных в интернете IPTV-плейлистов, опубликованных третьими лицами.
|
||
|
||
Сервис не размещает и не транслирует медиаконтент, не создаёт, не призывает использовать и распространять плейлисты третьих лиц, а также не оказывает услуг по ретрансляции телепрограмм.
|
||
|
||
Информация о телеканалах формируется исключительно путём обработки содержимого самого плейлиста.
|
||
header:
|
||
menu:
|
||
- title: Помощь
|
||
icon: help-circle-outline
|
||
children:
|
||
- title: Документация
|
||
url: https://m3u.su/docs
|
||
icon: document-text-outline
|
||
- title: Исходники
|
||
url: https://git.axenov.dev/IPTV
|
||
icon: code-slash-outline
|
||
- title: "@iptv_aggregator"
|
||
url: https://t.me/iptv_aggregator
|
||
icon: paper-plane-outline
|
||
footer:
|
||
links:
|
||
- title: Исходники
|
||
url: https://git.axenov.dev/IPTV
|
||
icon: code-slash-outline
|
||
- title: axenov.dev
|
||
url: https://axenov.dev
|
||
icon: person-outline
|
||
- title: "@iptv_aggregator"
|
||
url: https://t.me/iptv_aggregator
|
||
icon: megaphone-outline
|
||
|
||
check:
|
||
start-on-serve: false
|
||
playlists:
|
||
user-agent:
|
||
- Mozilla/5.0 WINK/1.31.1 (AndroidTV/9) HlsWinkPlayer
|
||
timeout: 10
|
||
all-cooldown: 1800
|
||
one-cooldown: 2
|
||
max-routines: 1
|
||
per-routine: 1
|
||
channels:
|
||
user-agent: Mozilla/5.0 WINK/1.31.1 (AndroidTV/9) HlsWinkPlayer
|
||
timeout: 10
|
||
byte-range: 512
|
||
cooldown: 0
|
||
max-routines: 50
|
||
per-routine: 10
|
||
|
||
cache:
|
||
enabled: false
|
||
host: localhost
|
||
port: 6379
|
||
username:
|
||
password:
|
||
db: 0
|
||
ttl: 30
|
||
```
|
||
|
||
### Часовой пояс
|
||
|
||
Параметр `app.timezone` задаёт часовой пояс, в котором отображается время последнего изменения плейлистов на сайте.
|
||
Поддерживаются значения из базы IANA (`Europe/Moscow`, `UTC`, `GMT` и т.д.) и фиксированные смещения (`UTC+3`, `UTC+03:00`).
|
||
Если указано некорректное значение, используется `UTC`.
|
||
|
||
### SEO-метаданные
|
||
|
||
Секция `site.meta` позволяет задать описание и ключевые слова для главной страницы и других страниц, где мета-данные не переопределяются шаблоном:
|
||
|
||
```yaml
|
||
site:
|
||
meta:
|
||
description: Самообновляемые бесплатные IPTV-плейлисты...
|
||
keywords: самообновляемые,бесплатные,iptv-плейлисты,iptv,плейлисты
|
||
```
|
||
|
||
Те же значения можно переопределить через переменные окружения `SITE_META_DESCRIPTION` и `SITE_META_KEYWORDS`.
|
||
|
||
`check.playlists.all-cooldown` задаёт паузу между полными циклами проверки.
|
||
Она используется командами `check` и `serve` и больше не применяется дополнительно внутри одного цикла. `check.playlists.one-cooldown` задаёт паузу между отдельными плейлистами, а `check.channels.cooldown` — между каналами одного плейлиста.
|
||
|
||
Параметры задержек (`timeout`, `all-cooldown`, `one-cooldown`, `cooldown`) и переменные окружения `CHECK_*_TIMEOUT`, `CHECK_*_COOLDOWN` задаются в секундах.
|
||
Они могут быть заданы как число или диапазон `[min, max]` в секундах.
|
||
При диапазоне для каждой операции выбирается случайное значение.
|
||
|
||
#### Переменные окружения
|
||
|
||
| Переменная | Соответствует в `config.yml` | CLI-флаг | Описание |
|
||
| ----------------------------------- | ------------------------------ | -------------------------- | ----------------------------------- |
|
||
| `APP_DEBUG` | `app.debug` | `--debug` | Режим отладки |
|
||
| `APP_LOG_LEVEL` | `app.log_level` | `--log-level` | Уровень журналирования |
|
||
| `APP_TIMEZONE` | `app.timezone` | — | Часовой пояс |
|
||
| `APP_PLAYLISTS` | `app.playlists` | `-i`, `--ini` | Путь к `playlists.ini` |
|
||
| `APP_TAGS` | `app.tags` | `-t`, `--tags` | Путь к `channels.json` |
|
||
| `SERVER_HOST` | `server.host` | `serve --host` | Хост для привязки |
|
||
| `SERVER_PORT` | `server.port` | `-p`, `serve --port` | Порт веб-сервера |
|
||
| `SITE_BASE_URL` | `site.base-url` | — | Базовый URL для ссылок |
|
||
| `SITE_PAGE_SIZE` | `site.page-size` | — | Размер страницы (0 — без пагинации) |
|
||
| `SITE_REPO_URL` | `site.repo-url` | — | Ссылка на репозиторий |
|
||
| `SITE_FAVICON` | `site.favicon` | — | Путь к иконке сайта |
|
||
| `SITE_TITLE` | `site.title` | — | Заголовок сайта |
|
||
| `SITE_META_DESCRIPTION` | `site.meta.description` | — | Описание сайта (meta) |
|
||
| `SITE_META_KEYWORDS` | `site.meta.keywords` | — | Ключевые слова сайта (meta) |
|
||
| `CHECK_START_ON_SERVE` | `check.start-on-serve` | `serve --check` | Запускать проверку вместе с `serve` |
|
||
| `CHECK_PLAYLISTS_TIMEOUT` | `check.playlists.timeout` | `--playlists-timeout` | Таймаут запроса плейлиста (с) |
|
||
| `CHECK_PLAYLISTS_ALL_COOLDOWN` | `check.playlists.all-cooldown` | `--playlists-all-cooldown` | Пауза между циклами проверки (с) |
|
||
| `CHECK_PLAYLISTS_ONE_COOLDOWN` | `check.playlists.one-cooldown` | `--playlists-one-cooldown` | Пауза между плейлистами (с) |
|
||
| `CHECK_PLAYLISTS_MAX_ROUTINES` | `check.playlists.max-routines` | `--playlists-max-routines` | Параллельных проверок плейлистов |
|
||
| `CHECK_PLAYLISTS_PER_ROUTINE` | `check.playlists.per-routine` | `--playlists-per-routine` | Плейлистов на одну процедуру |
|
||
| `CHECK_PLAYLISTS_USER_AGENT_[1..*]` | `check.playlists.user-agent` | `--playlists-user-agent` | User-Agent для проверки плейлистов |
|
||
| `CHECK_CHANNELS_TIMEOUT` | `check.channels.timeout` | `--channels-timeout` | Таймаут запроса канала (с) |
|
||
| `CHECK_CHANNELS_BYTE_RANGE` | `check.channels.byte-range` | `--channels-byte-range` | Объём данных для получения (байт) |
|
||
| `CHECK_CHANNELS_COOLDOWN` | `check.channels.cooldown` | `--channels-cooldown` | Пауза между каналами (с) |
|
||
| `CHECK_CHANNELS_MAX_ROUTINES` | `check.channels.max-routines` | `--channels-max-routines` | Параллельных проверок каналов |
|
||
| `CHECK_CHANNELS_PER_ROUTINE` | `check.channels.per-routine` | `--channels-per-routine` | Каналов на одну процедуру |
|
||
| `CHECK_CHANNELS_USER_AGENT_[1..*]` | `check.channels.user-agent` | `--channels-user-agent` | User-Agent для проверки каналов |
|
||
| `CACHE_ENABLED` | `cache.enabled` | `--cache-enabled` | Включить кеш (KeyDB/Redis) |
|
||
| `CACHE_HOST` | `cache.host` | `--cache-host` | Хост KeyDB/Redis |
|
||
| `CACHE_PORT` | `cache.port` | `--cache-port` | Порт KeyDB/Redis |
|
||
| `CACHE_USERNAME` | `cache.username` | `--cache-username` | Имя пользователя KeyDB/Redis |
|
||
| `CACHE_PASSWORD` | `cache.password` | `--cache-password` | Пароль KeyDB/Redis |
|
||
| `CACHE_DB` | `cache.db` | `--cache-db` | Номер БД KeyDB/Redis |
|
||
| `CACHE_TTL` | `cache.ttl` | `--cache-ttl` | TTL записей в кеше (сек) |
|
||
|
||
### Маршруты
|
||
|
||
| Метод | Путь | Описание |
|
||
| ----- | -------------------------------- | ---------------------------------------- |
|
||
| GET | `/` | Главная страница со списком плейлистов |
|
||
| GET | `/page/{N}` | Страница N списка плейлистов |
|
||
| GET | `/{code}` | Редирект на прямую ссылку плейлиста |
|
||
| GET | `/{code}.m3u` | Редирект на прямую ссылку плейлиста |
|
||
| GET | `/{code}.m3u8` | Редирект на прямую ссылку плейлиста |
|
||
| GET | `/{code}/details` | Страница с описанием плейлиста |
|
||
| GET | `/api/playlists` | JSON: список плейлистов |
|
||
| GET | `/api/playlists/{code}` | JSON: информация о плейлисте |
|
||
| GET | `/api/playlists/{code}/channels` | JSON: каналы плейлиста |
|
||
| GET | `/api/version` | JSON: версии компонентов |
|
||
| GET | `/api/health` | JSON: состояние сервиса |
|
||
| GET | `/api/stats` | JSON: статистика по плейлистам и каналам |
|
||
| GET | `/api` | Swagger UI документация API |
|
||
|
||
### Связь с проверкой
|
||
|
||
Веб-сервер отображает данные из кеша KeyDB/Redis, который заполняется командой `check`.
|
||
Если кеш недоступен, все плейлисты отображаются со статусом `unknown`.
|
||
|
||
Для обновления данных в фоне запустите `serve` с флагом `--check`:
|
||
|
||
```
|
||
./iptvc serve -i playlists.ini -p 8800 --check
|
||
```
|
||
|
||
Результаты проверок появляются на веб-страницах немедленно после проверки каждого
|
||
плейлиста, не дожидаясь завершения полного цикла.
|
||
После завершения цикла приложение
|
||
ждёт значение `check.playlists.all-cooldown` и затем начинает следующий цикл.
|
||
|
||
Можно запускать `serve` и `check` отдельными процессами:
|
||
|
||
```
|
||
./iptvc check --repeat 0 --playlists-all-cooldown 60 &
|
||
./iptvc serve
|
||
```
|
||
|
||
Или используйте Docker Compose. Перед запуском подготовьте `.env`, `config.yml`, `playlists.ini` и `channels.json` в рабочем каталоге:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
cp config.yml.example config.yml
|
||
docker compose up -d --build
|
||
docker compose logs -f iptvc
|
||
docker compose down
|
||
```
|
||
|
||
Compose запускает сервисы `iptvc`, `keydb` и `docs`.
|
||
В текущем `compose.yml` контексты сборки указаны как `./iptvc` и `./docs`, поэтому запуск из одного только каталога этого репозитория может потребовать внешней структуры проекта или корректировки контекстов.
|
||
|
||
## Результаты проверки
|
||
|
||
Программа логирует процесс и результаты своей работы.
|
||
Рассмотрим лог на примере.
|
||
|
||
В рабочей директории лежит файл `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 1 playlists will be checked (max-routines=1)
|
||
2025/01/02 12:34:00 Fetching playlist [first] (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 channels parameters: timeout=10.00s byte-range=512 max-routines=50
|
||
2025/01/02 12:34:12 Checked successfully! online=101 onlinePercent=88.60% offline=13 offlinePercent=11.40% elapsedTime=12.39s
|
||
2025/01/02 12:34:12 Done! count=1 online=1 offline=0 elapsedTime=12.39s
|
||
```
|
||
|
||
Разберём построчно:
|
||
1. Загрузка ini-файла
|
||
2. Файл загружен, в нём 2 плейлиста
|
||
3. Начало проверки 1 плейлиста (выбран кодом `first`)
|
||
4. Скачивание плейлиста `first` по ссылке `https://example.com/list1.m3u`
|
||
5. Плейлист скачан, начало разбора
|
||
6. Плейлист разобран, начало проверки каналов (114 штук)
|
||
7. Параметры проверки каналов (таймаут, объём данных, число горутин)
|
||
8. (спустя время) Проверка каналов завершена
|
||
9. Проверка плейлиста завершена
|
||
|
||
### Коды возврата
|
||
|
||
* 0 — успех
|
||
* 1 — общая ошибка
|
||
|
||
## Лицензия
|
||
|
||
ПО распространяется на условиях [лицензии MIT](LICENSE).
|