30.8.2026, 13:19
(Tento příspěvek byl naposledy změněn: 30.8.2026, 13:28 uživatelem JiRo.
Důvod úpravy: Překlepy
)
Podělím se o zkušenosti s tím, jak v Tvheadend, pokud člověk používá příjem prostřednictvím metody pipe s remuxem zdrojového streamu pomocí ffmpeg, dostat na obrazovku TV nějakou informaci získanou v procesu neúspěšného získání zdrojového streamu. Já to používám u mého komplexního řešení streamer-server, které je založeno na databázi streamů, získaných různými metodami, z nich si vlastní script vybere ten nejrychleji dostupný a ten pošle do Tvheadend. Pokud ale pro daný kanál takový stream neexistuje, není v databázi nebo není momentálně žádný z databáze dostupný, pošle do Tvheadend lokálně generované statické video s odpovídající informací.
Postup je celkem jednoduchý. Pokud v rámci získání/zpracování adresy streamu daného kanálu doje k nějaké chybě, která znemožní spuštění přehrávání streamu s obsahem vysílání daného kanálu, místo klasického volání ffmpeg se sadou odpovídajícíh parametrů, zavolá script ffmpeg s parametry, které zobrazí statický obrázek, do kterém lze dynamicky vložit potřebný text, který odpovídá dané mu kontextu. O tom jsou dva výše uvedené screenshoty. První ukazuje volbu kanálu GP 1 TV a druhý informaci, že TVheadend nemá momentálně pro daný kanál k dispozici žádnou službu.
Příklad toho, jak pak taková volání ffmpeg, resp. jeho parametry vypadají najdete níže. Uvádím ho v aktuální podobě mého řešení, ve formě procedury noservice_pipe, která se zavolá, pokud výkonná část scriptu zjistí, že žádná služba pro zvolený kanál nenabízí funkční stream. Z pohledu tématu je podstatné to, co se ukládá do proměnné args a pak dva parametry volání procedury, path a text. Ostatní části kódu jsou už poplatné tomu, kde a jak proceduru používám a nejsou pro toto téma podstatné:
V podstatě jde o variantu řešení, které používá @waladir ve svých skvělých řešeních doplňků a scriptů pro různé OTT služby, hlavně OnePlay, který pro tyhle účely využívá stream OTT služby Sledovanitv.sk::
Postup je celkem jednoduchý. Pokud v rámci získání/zpracování adresy streamu daného kanálu doje k nějaké chybě, která znemožní spuštění přehrávání streamu s obsahem vysílání daného kanálu, místo klasického volání ffmpeg se sadou odpovídajícíh parametrů, zavolá script ffmpeg s parametry, které zobrazí statický obrázek, do kterém lze dynamicky vložit potřebný text, který odpovídá dané mu kontextu. O tom jsou dva výše uvedené screenshoty. První ukazuje volbu kanálu GP 1 TV a druhý informaci, že TVheadend nemá momentálně pro daný kanál k dispozici žádnou službu.
Příklad toho, jak pak taková volání ffmpeg, resp. jeho parametry vypadají najdete níže. Uvádím ho v aktuální podobě mého řešení, ve formě procedury noservice_pipe, která se zavolá, pokud výkonná část scriptu zjistí, že žádná služba pro zvolený kanál nenabízí funkční stream. Z pohledu tématu je podstatné to, co se ukládá do proměnné args a pak dva parametry volání procedury, path a text. Ostatní části kódu jsou už poplatné tomu, kde a jak proceduru používám a nejsou pro toto téma podstatné:
- path je adresa obrázku, který tvoří pozadí, což jsou v uvedeném screenshot-u logo Tvheadend, text Tvheadend a text No Service!,
- text je pak bílý text uvedený níže.
Kód:
def noservice_pipe(service, provider, text, path, loglevel="error"):
args = [
"/usr/bin/ffmpeg",
"-re",
"-loglevel", loglevel,
"-loop", "1",
"-i", path,
"-f", "lavfi",
"-i", "anullsrc=r=48000:cl=stereo",
"-shortest",
"-r", "25",
"-s", "1920x1080",
"-vf", f"format=yuv420p,fps=25,scale=1920:1080,"
f"drawtext=text={text}:fontcolor=white:fontsize=32:"
f"x=(w-text_w)/2:y=900",
"-vcodec", "libx264",
"-preset", "ultrafast",
"-tune", "stillimage",
"-pix_fmt", "yuv420p",
"-acodec", "aac",
"-b:a", "128k",
"-muxrate", "4M",
"-f", "mpegts",
"-mpegts_flags", "+initial_discontinuity",
"-mpegts_service_type", "digital_tv",
"-metadata", f"service_provider={provider}",
"-metadata", f"service_name={service}",
"pipe:1"
]
proc = subprocess.Popen(
args,
stdout=sys.stdout,
stderr=sys.stderr,
preexec_fn=os.setsid
)
try:
proc.wait()
finally:
try:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
except Exception:
passV podstatě jde o variantu řešení, které používá @waladir ve svých skvělých řešeních doplňků a scriptů pro různé OTT služby, hlavně OnePlay, který pro tyhle účely využívá stream OTT služby Sledovanitv.sk::
