feat(#5): play YouTube (and any yt-dlp URL) by passing it as the video arg

resolve_video_path() now detects URLs and resolves them through yt-dlp before
playback:

    python stream_server.py 'https://youtu.be/<id>' --mode 3

ytdl.py downloads <=480p (ASCILINE downscales every frame to a tiny grid, so HD
is wasted bandwidth), prefers H.264 for OpenCV compatibility and re-encodes
AV1/VP9 as a fallback, and caches by video id in videos/ so re-runs are instant.
Only activates when the input is a URL; local files/folders/playlists are
untouched. Requires 'pip install yt-dlp'.

Verified end-to-end: is_url() detection + a real URL download decoding cleanly in
OpenCV (300 frames, 360x640).
This commit is contained in:
Nate 2026-06-13 23:34:35 -04:00
parent e130b0cc2f
commit 64f03efbed
2 changed files with 85 additions and 0 deletions

View file

@ -25,6 +25,7 @@ from websockets.exceptions import ConnectionClosed
# Import the existing engine (ascii_video_player2.py)
from ascii_video_player2 import VideoDecoder, AsciiMapper
from codec import encode_frame
import ytdl
app = FastAPI()
@ -64,11 +65,15 @@ def get_html_content():
def resolve_video_path(video: str) -> str:
"""
Resolves a video path by checking multiple locations in order:
0. If it's a URL (YouTube, etc.) -> download via yt-dlp and use that file
1. As-is (absolute or relative to CWD)
2. Inside the project root (BASE_DIR)
3. Inside BASE_DIR/videos/ subfolder
Returns the first path that exists, or the original string if none found.
"""
if ytdl.is_url(video):
return ytdl.download(video, cache_dir=os.path.join(BASE_DIR, "videos"))
candidates = [
video,
os.path.join(BASE_DIR, video),