Files
projects/Dockers/self-hosted-iptv/main.py
T
Bram 2706a21818
Build and Push Docker Images / build-and-push (push) Successful in 23s
channel ids
2026-02-11 22:37:58 +01:00

83 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""
Self-hosted IPTV: serves M3U playlists that schedule video files from /movies and /series
with randomized order so the same show never appears twice in a row.
"""
import logging
import os
from iptv.config import (
CHANNELS_FILE,
EPG_TIMESPAN_DAYS,
SCHEDULE_CACHE_TTL_SEC,
NORMALIZE_LIVE_STREAM,
NORMALIZE_TARGET_RES,
init_epg_timespan,
)
from iptv.cache import CacheManager
from iptv.channel import ChannelRepository
from iptv.schedule import ScheduleBuilder
from iptv.tmdb_client import TMDBClient
from iptv.metadata_prefetcher import MetadataPrefetcher
from iptv.epg_builder import EPGBuilder
from iptv.server import create_server
logger = logging.getLogger(__name__)
def main():
init_epg_timespan()
log_level = getattr(logging, os.environ.get("LOG_LEVEL", "INFO").upper(), logging.INFO)
logging.basicConfig(
level=log_level,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
if not CHANNELS_FILE.exists():
print(f"Warning: {CHANNELS_FILE} not found. Create it from data/channels.json.example")
logger.info(
"EPG timespan: %s days, schedule refresh after: %.1f h",
EPG_TIMESPAN_DAYS,
SCHEDULE_CACHE_TTL_SEC / 3600,
)
if NORMALIZE_LIVE_STREAM:
logger.info(
"Live stream normalization enabled (target: %s) — prevents crashes when switching episodes",
NORMALIZE_TARGET_RES,
)
channel_repo = ChannelRepository()
schedule_builder = ScheduleBuilder()
schedule_builder.set_channel_repo(channel_repo)
cache_manager = CacheManager(schedule_builder=schedule_builder)
schedule_builder.set_cache_manager(cache_manager)
if not cache_manager._ensure_cache_dir():
logger.warning(
"Cannot create cache dir %s — schedule will rebuild on every restart. "
"Ensure /data is mounted read-write (not :ro).",
cache_manager._cache_dir,
)
tmdb_client = TMDBClient()
prefetcher = MetadataPrefetcher(schedule_builder, tmdb_client, channel_repo)
prefetcher.start()
epg_builder = EPGBuilder(
schedule_builder, tmdb_client, channel_repo, cache_manager, prefetcher
)
port = 8080
server = create_server(
channel_repo=channel_repo,
schedule_builder=schedule_builder,
epg_builder=epg_builder,
host="0.0.0.0",
port=port,
cache_manager=cache_manager,
)
print(f"Serving at http://0.0.0.0:{port}/ (playlist: http://<host>:{port}/playlist.m3u)")
server.serve_forever()
if __name__ == "__main__":
main()