From 86ce3d94b44568eccd734d241b8ee67d443d9eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D0=BE=D1=84=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94=D0=BC?= =?UTF-8?q?=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=92=D0=B8=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Tue, 1 Sep 2026 11:39:19 +0300 Subject: [PATCH] Document public release and simplify playlist export --- LICENSE | 21 ++++++++++ README.md | 69 ++++++++++++++++++++++++++++---- src/stream_playlist_tools/m3u.py | 2 + 3 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..254ce26 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Dmitry Fofanov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index d2a6485..8bae01f 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,68 @@ # Stream Playlist Tools -Небольшая утилита, восстановленная из `GenerateStream.py`. Она преобразует записи -из M3U-плейлиста в отдельные `.strm`-файлы, которые можно подключать к медиасерверу. +Консольная утилита для преобразования M3U-плейлиста в каталог `.strm`-файлов. +Проект вырос из скрипта `GenerateStream.py`, но оставляет только полезную и +независимую часть: локальный разбор плейлиста и создание файлов для медиасервера. -## Запуск +## Что делает + +- читает пары `#EXTINF` и URL из UTF-8 M3U; +- берёт имя из `tvg-name`, а при его отсутствии — из текста после запятой в + `#EXTINF`; +- заменяет недопустимые для имён файлов символы; +- сохраняет один URL в каждом файле `<название>.strm`; +- различает одинаковые названия, добавляя суффикс `(2)`, `(3)` и т. д. + +Утилита не выполняет HTTP-запросов, не скачивает медиа, не проверяет доступность +ссылок и не хранит токены либо адреса серверов. Она подходит для плейлистов и +источников, которыми вы вправе пользоваться. + +## Установка + +Требуется Python 3.10 или новее. ```bash -python -m pip install -e . -playlist-to-strm input.m3u output/ +git clone https://github.dfv24.com/fofanov.dmitry/stream-playlist-tools.git +cd stream-playlist-tools +python -m venv .venv +. .venv/bin/activate +python -m pip install --editable . ``` -Утилита не загружает контент и не хранит ключи или адреса серверов: она записывает -ссылки из входного плейлиста как есть. Название файла берётся из `tvg-name`, -`#EXTINF` или URL. +На Windows активируйте окружение командой `.venv\Scripts\activate`. + +## Использование + +```bash +playlist-to-strm ./input/channels.m3u ./output/strm +``` + +Например, запись + +```m3u +#EXTINF:-1 tvg-name="Новости / HD",Новости +https://media.example.org/news.m3u8 +``` + +создаст файл `output/strm/Новости _ HD.strm` с единственной строкой — URL потока. +Повторный запуск в тот же каталог перезапишет файлы с совпавшими именами, поэтому +для нового импорта лучше выбирать отдельный каталог. + +## Структура + +```text +src/stream_playlist_tools/ + m3u.py # разбор M3U и запись STRM + cli.py # аргументы командной строки +``` + +## Проверка + +```bash +python -m compileall -q src +PYTHONPATH=src python -m stream_playlist_tools.cli input.m3u output +``` + +## Лицензия + +Код распространяется по лицензии [MIT](LICENSE). diff --git a/src/stream_playlist_tools/m3u.py b/src/stream_playlist_tools/m3u.py index ab59815..ae64878 100644 --- a/src/stream_playlist_tools/m3u.py +++ b/src/stream_playlist_tools/m3u.py @@ -23,6 +23,7 @@ def parse_m3u(text: str) -> list[PlaylistEntry]: for raw_line in text.splitlines(): line = raw_line.strip() if line.startswith("#EXTINF"): + # Метаданные всегда относятся к следующей непустой URL-строке. match = re.search(r'tvg-name="([^"]+)"', line) pending_name = match.group(1) if match else line.rsplit(",", 1)[-1].strip() elif line and not line.startswith("#") and pending_name: @@ -46,6 +47,7 @@ def write_strm(entries: list[PlaylistEntry], output_dir: Path) -> int: for entry in entries: stem = safe_filename(entry.name) candidate, index = stem, 2 + # Один URL в STRM — ожидаемый формат для медиасерверов. while candidate.casefold() in used: candidate = f"{stem} ({index})" index += 1