Files
ffmpeg/main.py
2026-02-10 14:35:18 +03:00

101 lines
3.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import subprocess
import threading
import time
import shlex
import sys
from datetime import datetime
FFMPEG = "ffmpeg" # или r"C:\ffmpeg\bin\ffmpeg.exe"
# ВХОД: обычно listener (vMix = caller)
IN_URL = "srt://127.0.0.1:9000?mode=caller&reuseaddr=1"
# ВЫХОД: обычно caller (приемник = listener)
# OUT_URL = "srt://127.0.0.1:9001?mode=listener&latency=200000&transtype=live&connect_timeout=5000"
# OUT_URL = "srt://0.0.0.0:9001?mode=listener&transtype=live&connect_timeout=5000"
OUT_URL = "srt://0.0.0.0:9001?mode=listener&reuseaddr=1"
# Если хочешь, чтобы ffmpeg "держал" выход и ждал подключение (удобно для VLC):
# OUT_URL = "srt://0.0.0.0:9001?mode=listener&latency=200000&reuseaddr=1&transtype=live"
# тогда VLC открывай как caller: srt://127.0.0.1:9001?latency=200000
LOGLEVEL = "info" # debug для диагностики
def now():
return datetime.now().strftime("%H:%M:%S")
def reader_thread(pipe, prefix):
"""Читает stderr ffmpeg и печатает, чтобы не забивался буфер."""
try:
for line in iter(pipe.readline, ""):
if not line:
break
line = line.rstrip("\n")
if line:
print(f"[{now()}] {prefix} {line}")
except Exception:
pass
def build_cmd():
return [
FFMPEG,
"-hide_banner",
"-loglevel", LOGLEVEL,
# полезно для лайва
"-fflags", "+genpts",
"-flags", "low_delay",
# вход
"-i", IN_URL,
# без перекодирования (минимальная задержка/нагрузка)
"-c", "copy",
"-f", "mpegts",
# выход
OUT_URL,
]
def run_forever():
backoff = 1.0
backoff_max = 10.0
while True:
cmd = build_cmd()
print(f"[{now()}] Starting ffmpeg:\n {shlex.join(cmd) if hasattr(shlex,'join') else ' '.join(cmd)}")
try:
proc = subprocess.Popen(
cmd,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
text=True,
bufsize=1,
)
t = threading.Thread(target=reader_thread, args=(proc.stderr, "ffmpeg:"), daemon=True)
t.start()
rc = proc.wait()
print(f"[{now()}] ffmpeg exited with code {rc}")
except FileNotFoundError:
print(f"[{now()}] ERROR: ffmpeg not found. Set FFMPEG path correctly.")
sys.exit(2)
except Exception as e:
print(f"[{now()}] ERROR running ffmpeg: {e}")
rc = -1
# Если поток отвалился или приемник недоступен — ffmpeg завершится.
# Мы НЕ падаем, а перезапускаем.
sleep_s = backoff
print(f"[{now()}] Restarting in {sleep_s:.1f}s...\n")
time.sleep(sleep_s)
backoff = min(backoff * 1.5, backoff_max)
if __name__ == "__main__":
run_forever()