From 402d44111e081e3434103633b12fff5b6547e2d6 Mon Sep 17 00:00:00 2001 From: NANDI Date: Thu, 5 Mar 2026 10:46:21 +0100 Subject: [PATCH] =?UTF-8?q?Fix=20Windows=20compatibility:=20pipe=20streaml?= =?UTF-8?q?ink=E2=86=92ffmpeg=20manually?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows, asyncio subprocess stdin can't accept another process's StreamReader directly. Use a background task to forward data instead. Co-Authored-By: Claude Opus 4.6 --- capture.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/capture.py b/capture.py index 88adf99..f7f0f20 100644 --- a/capture.py +++ b/capture.py @@ -1,8 +1,22 @@ import asyncio -import struct from collections.abc import AsyncIterator +async def _pipe_stream(source: asyncio.StreamReader, dest: asyncio.StreamWriter): + """Forward data from streamlink stdout to ffmpeg stdin.""" + try: + while True: + chunk = await source.read(65536) + if not chunk: + break + dest.write(chunk) + await dest.drain() + except (BrokenPipeError, ConnectionResetError): + pass + finally: + dest.close() + + async def capture_frames( channel: str, quality: str, interval: int ) -> AsyncIterator[bytes]: @@ -35,13 +49,15 @@ async def capture_frames( ffmpeg_proc = await asyncio.create_subprocess_exec( *ffmpeg_cmd, - stdin=streamlink_proc.stdout, + stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.DEVNULL, ) - # Release streamlink's stdout so ffmpeg owns the pipe - streamlink_proc.stdout = None + # Forward streamlink → ffmpeg in background + pipe_task = asyncio.create_task( + _pipe_stream(streamlink_proc.stdout, ffmpeg_proc.stdin) + ) try: buf = b"" @@ -59,13 +75,13 @@ async def capture_frames( break eoi = buf.find(b"\xff\xd9", soi + 2) if eoi == -1: - # Keep from SOI onward, discard junk before buf = buf[soi:] break frame = buf[soi : eoi + 2] buf = buf[eoi + 2 :] yield frame finally: + pipe_task.cancel() for proc in (ffmpeg_proc, streamlink_proc): try: proc.terminate()