aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-01 09:53:34 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-01 09:53:34 +0200
commit0673922e704f718037eeffd2724debcfa8ac0b4b (patch)
tree78fee9a5c04542f006c1757bc76c0af7f57a79db /packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py
parent6426912946270bb02e7b94508008edf8f949d993 (diff)
downloadmeshbay-0673922e704f718037eeffd2724debcfa8ac0b4b.tar.gz
fix(node): ffprobe over a member's file is bounded, and stopped when it is
probe_video waits 30 s at most and kills ffprobe on a timeout or when its caller gives up — a cancelled wait left the process running. The seek probe kills what it timed out on. Stream, subtitle and enrichment requests no longer hang on a file that keeps ffprobe busy (F-18, timeouts; the protocol whitelist was dropped: ffmpeg already confines nested protocols of a local input, measured on 8.0 against HLS and concat inputs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py7
1 files changed, 7 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py
index 7ecb0a5..22c1690 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/media_tools.py
@@ -165,6 +165,7 @@ async def _seek_lands_at(file_path: Path, t: float, map_args: list[str]) -> floa
fd, tmp_name = tempfile.mkstemp(suffix=".mp4")
os.close(fd)
tmp_path = Path(tmp_name)
+ proc = probe = None
try:
proc = await asyncio.create_subprocess_exec(
platform.ffmpeg_cmd(), "-hide_banner", "-loglevel", "error", "-y",
@@ -189,6 +190,12 @@ async def _seek_lands_at(file_path: Path, t: float, map_args: list[str]) -> floa
log.warning("stream: seek probe failed at %.1fs: %r", t, e)
return None
finally:
+ # A timed-out wait leaves its process running; it is stopped here, not
+ # left to finish a seek nobody is waiting for.
+ for p in (proc, probe):
+ if p is not None and p.returncode is None:
+ p.kill()
+ await p.wait()
await _discard_scratch(tmp_path)
text = stdout.decode(errors="replace").strip().rstrip(",")
try: