import subprocess from pathlib import Path VIDEOS_DIR = "/videos" CHUNK_SIZE = 64 * 1024 def _get_stream_urls(youtube_url: str): result = subprocess.run( [ "yt-dlp", "-f", "bestvideo[ext=mp4][vcodec^=avc]+bestaudio[ext=m4a]/best[ext=mp4]", "--print", "urls", youtube_url, ], capture_output=True, text=True, timeout=30, ) if result.returncode != 0: return None, None lines = result.stdout.strip().splitlines() if len(lines) >= 2: return lines[0], lines[1] elif len(lines) == 1: return lines[0], None return None, None def stream_video_live(video_id: int, youtube_url: str): output_path = f"{VIDEOS_DIR}/{video_id}.mp4" video_url, audio_url = _get_stream_urls(youtube_url) if not video_url: return if audio_url: cmd = [ "ffmpeg", "-reconnect", "1", "-reconnect_streamed", "1", "-reconnect_delay_max", "5", "-i", video_url, "-reconnect", "1", "-reconnect_streamed", "1", "-reconnect_delay_max", "5", "-i", audio_url, "-c:v", "copy", "-c:a", "aac", "-movflags", "frag_keyframe+empty_moov+default_base_moof", "-f", "mp4", "pipe:1", ] else: cmd = [ "ffmpeg", "-reconnect", "1", "-reconnect_streamed", "1", "-reconnect_delay_max", "5", "-i", video_url, "-c", "copy", "-movflags", "frag_keyframe+empty_moov+default_base_moof", "-f", "mp4", "pipe:1", ] process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, ) try: with open(output_path, "wb") as f: while True: chunk = process.stdout.read(CHUNK_SIZE) if not chunk: break f.write(chunk) yield chunk except GeneratorExit: pass finally: if process.poll() is None: process.kill() process.wait() if process.stdout: process.stdout.close() path = Path(output_path) if process.returncode != 0 and path.exists(): path.unlink()