fix: use returncode is None instead of .done() for subprocess check
This commit is contained in:
parent
565c524c6f
commit
122d732db2
1 changed files with 13 additions and 19 deletions
|
|
@ -10,10 +10,14 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _deltacast_device_exists(port_index: int) -> bool:
|
def _deltacast_device_exists(port_index: int) -> bool:
|
||||||
"""Return True if the deltacast device node exists on the host."""
|
|
||||||
return os.path.exists(f"/dev/deltacast{port_index}")
|
return os.path.exists(f"/dev/deltacast{port_index}")
|
||||||
|
|
||||||
|
|
||||||
|
def _proc_running(proc) -> bool:
|
||||||
|
"""Return True if the subprocess is still alive."""
|
||||||
|
return proc is not None and proc.returncode is None
|
||||||
|
|
||||||
|
|
||||||
class HLSPreviewManager:
|
class HLSPreviewManager:
|
||||||
"""
|
"""
|
||||||
Manages FFmpeg HLS transcoding processes for video preview.
|
Manages FFmpeg HLS transcoding processes for video preview.
|
||||||
|
|
@ -26,13 +30,10 @@ class HLSPreviewManager:
|
||||||
self._processes: dict[int, asyncio.subprocess.Process] = {}
|
self._processes: dict[int, asyncio.subprocess.Process] = {}
|
||||||
|
|
||||||
async def start_preview(self, port_index: int) -> None:
|
async def start_preview(self, port_index: int) -> None:
|
||||||
if port_index in self._processes and self._processes[port_index] is not None:
|
existing = self._processes.get(port_index)
|
||||||
proc = self._processes[port_index]
|
if _proc_running(existing):
|
||||||
if not proc.done():
|
logger.info(f"Port {port_index}: HLS preview already running")
|
||||||
logger.info(f"Port {port_index}: HLS preview already running")
|
return
|
||||||
return
|
|
||||||
# Process died — clean up and restart
|
|
||||||
self._processes.pop(port_index)
|
|
||||||
|
|
||||||
self.hls_dir.mkdir(parents=True, exist_ok=True)
|
self.hls_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
|
@ -44,8 +45,6 @@ class HLSPreviewManager:
|
||||||
else:
|
else:
|
||||||
logger.info(f"Port {port_index}: Starting HLS preview from deltacast{port_index}")
|
logger.info(f"Port {port_index}: Starting HLS preview from deltacast{port_index}")
|
||||||
|
|
||||||
logger.debug(f"Port {port_index}: FFmpeg command: {' '.join(command)}")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
process = await asyncio.create_subprocess_exec(
|
process = await asyncio.create_subprocess_exec(
|
||||||
*command,
|
*command,
|
||||||
|
|
@ -60,10 +59,10 @@ class HLSPreviewManager:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def stop_preview(self, port_index: int) -> None:
|
async def stop_preview(self, port_index: int) -> None:
|
||||||
if port_index not in self._processes or self._processes[port_index] is None:
|
process = self._processes.get(port_index)
|
||||||
|
if not _proc_running(process):
|
||||||
return
|
return
|
||||||
|
|
||||||
process = self._processes[port_index]
|
|
||||||
logger.info(f"Port {port_index}: Stopping HLS preview (PID: {process.pid})")
|
logger.info(f"Port {port_index}: Stopping HLS preview (PID: {process.pid})")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -107,23 +106,18 @@ class HLSPreviewManager:
|
||||||
return self.hls_dir / f"port_{port_index}.m3u8"
|
return self.hls_dir / f"port_{port_index}.m3u8"
|
||||||
|
|
||||||
def is_previewing(self, port_index: int) -> bool:
|
def is_previewing(self, port_index: int) -> bool:
|
||||||
if port_index not in self._processes:
|
return _proc_running(self._processes.get(port_index))
|
||||||
return False
|
|
||||||
process = self._processes[port_index]
|
|
||||||
return process is not None and not process.done()
|
|
||||||
|
|
||||||
def _build_hls_command(self, port_index: int, use_test_src: bool = False) -> list[str]:
|
def _build_hls_command(self, port_index: int, use_test_src: bool = False) -> list[str]:
|
||||||
playlist_path = self.get_playlist_path(port_index)
|
playlist_path = self.get_playlist_path(port_index)
|
||||||
|
|
||||||
if use_test_src:
|
if use_test_src:
|
||||||
# lavfi test source: colour bars + timestamp overlay + tone
|
|
||||||
# Port number overlaid so each card is visually distinct
|
|
||||||
command = [
|
command = [
|
||||||
self.settings.ffmpeg_path,
|
self.settings.ffmpeg_path,
|
||||||
"-f", "lavfi",
|
"-f", "lavfi",
|
||||||
"-i", (
|
"-i", (
|
||||||
f"testsrc2=size=1280x720:rate=30,"
|
f"testsrc2=size=1280x720:rate=30,"
|
||||||
f"drawtext=text='SDI PORT {port_index} — NO SIGNAL':"
|
f"drawtext=text='SDI PORT {port_index} \u2014 NO SIGNAL':"
|
||||||
f"fontsize=36:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2,"
|
f"fontsize=36:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2,"
|
||||||
f"drawtext=text='%{{localtime\\:%H\\:%M\\:%S}}':"
|
f"drawtext=text='%{{localtime\\:%H\\:%M\\:%S}}':"
|
||||||
f"fontsize=24:fontcolor=yellow:x=10:y=10"
|
f"fontsize=24:fontcolor=yellow:x=10:y=10"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue