This commit is contained in:
@@ -289,35 +289,26 @@ def _schedule_epoch_utc() -> datetime:
|
|||||||
def stream_live_channel(paths: list[Path], wfile, durations: list[float]) -> None:
|
def stream_live_channel(paths: list[Path], wfile, durations: list[float]) -> None:
|
||||||
"""
|
"""
|
||||||
Run FFmpeg to output a continuous MPEG-TS stream from paths, looping forever.
|
Run FFmpeg to output a continuous MPEG-TS stream from paths, looping forever.
|
||||||
start_offset_sec aligns the stream with the EPG (schedule started at midnight UTC).
|
|
||||||
Stops when wfile write fails (client disconnect).
|
Stops when wfile write fails (client disconnect).
|
||||||
|
(No -ss seek: seeking into a looping concat input is unreliable, so stream
|
||||||
|
always starts from playlist start; EPG order and durations still match.)
|
||||||
"""
|
"""
|
||||||
if not paths:
|
if not paths:
|
||||||
return
|
return
|
||||||
cycle_duration = sum(durations)
|
|
||||||
if cycle_duration <= 0:
|
|
||||||
return
|
|
||||||
now = datetime.now(timezone.utc)
|
|
||||||
epoch = _schedule_epoch_utc()
|
|
||||||
start_offset_sec = (now - epoch).total_seconds() % cycle_duration
|
|
||||||
|
|
||||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
|
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
|
||||||
write_concat_list(paths, f)
|
write_concat_list(paths, f)
|
||||||
list_path = f.name
|
list_path = f.name
|
||||||
try:
|
try:
|
||||||
cmd = [
|
proc = subprocess.Popen(
|
||||||
|
[
|
||||||
"ffmpeg",
|
"ffmpeg",
|
||||||
"-stream_loop", "-1",
|
"-stream_loop", "-1",
|
||||||
"-f", "concat", "-safe", "0", "-i", list_path,
|
"-f", "concat", "-safe", "0", "-i", list_path,
|
||||||
"-c", "copy",
|
"-c", "copy",
|
||||||
"-f", "mpegts",
|
"-f", "mpegts",
|
||||||
"-",
|
"-",
|
||||||
]
|
],
|
||||||
if start_offset_sec >= 0.5:
|
|
||||||
# Seek so "now playing" matches EPG (schedule epoch = midnight UTC)
|
|
||||||
cmd = cmd[:9] + ["-ss", str(round(start_offset_sec, 2))] + cmd[9:]
|
|
||||||
proc = subprocess.Popen(
|
|
||||||
cmd,
|
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.DEVNULL,
|
stderr=subprocess.DEVNULL,
|
||||||
start_new_session=True,
|
start_new_session=True,
|
||||||
|
|||||||
Reference in New Issue
Block a user