From 28efc2aa6ccaefb1f020828963fb8d6ec3ba71e5 Mon Sep 17 00:00:00 2001 From: Roy Olav Purser Date: Thu, 20 May 2021 13:46:52 +0200 Subject: [PATCH] streamlink and youtube-dl concurrently --- backend/stream.py | 10 +--------- backend/stream_providers.py | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/backend/stream.py b/backend/stream.py index 78b8c31..9f680df 100755 --- a/backend/stream.py +++ b/backend/stream.py @@ -347,16 +347,8 @@ class MainHandler(tornado.web.RequestHandler): self.write("HTML template missing.") async def handle_stream(self, handler, redir): - upstream = None streams = None - youtube_stream_future = stream_providers.ytdl_get(handler.upstream, handler.proxy, logger) - streamlink_stream_future = stream_providers.streamlink_get(handler.upstream, handler.proxy, logger) - youtube_stream = await youtube_stream_future - streamlink_stream = await streamlink_stream_future - if isinstance(streamlink_stream, str): - upstream = streamlink_stream - elif isinstance(youtube_stream, str): - upstream = youtube_stream + upstream = await stream_providers.get_any(handler.upstream, handler.proxy, logger) if upstream is None: logger.info(f'invalid upstream ({handler.provider})') self.set_status(404) diff --git a/backend/stream_providers.py b/backend/stream_providers.py index b2203b1..86ca260 100755 --- a/backend/stream_providers.py +++ b/backend/stream_providers.py @@ -69,7 +69,7 @@ class YoutubeRunner(StreamProvider): async def run(self): return await asyncio.to_thread(self.stream) -async def ytdl_get(upstream, proxy, logger): +async def get_ytdl(upstream, proxy, logger): url = None try: runner = YoutubeRunner(upstream, proxy) @@ -78,7 +78,7 @@ async def ytdl_get(upstream, proxy, logger): logger.info(e) return url -async def streamlink_get(upstream, proxy, logger): +async def get_streamlink(upstream, proxy, logger): url = None try: runner = StreamlinkRunner(upstream, proxy) @@ -86,3 +86,17 @@ async def streamlink_get(upstream, proxy, logger): except Exception as e: logger.info(e) return url + +async def get_any(upstream, proxy, logger): + tasks = [] + tasks.append(asyncio.create_task(get_streamlink(upstream, proxy, logger))) + tasks.append(asyncio.create_task(get_ytdl(upstream, proxy, logger))) + result = None + for task in asyncio.as_completed(tasks): + result = await task + if isinstance(result, str): + break + for task in tasks: + if not task.done(): + task.cancel() + return result