From 19df74b4e095d6f1a5edaa048c9aebe6a3f6326a Mon Sep 17 00:00:00 2001 From: PranAD-dev Date: Wed, 7 Jan 2026 20:44:47 -0800 Subject: [PATCH 1/3] yt shorts now work, (playlist containing shorts do NOT work yet.) --- modules/cache.py | 24 +++++++++++++++++++----- requirements.txt | 2 +- server.py | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/modules/cache.py b/modules/cache.py index 3d2b9f4..21b70c7 100644 --- a/modules/cache.py +++ b/modules/cache.py @@ -36,10 +36,9 @@ def __init__( self.video_id_to_path = OrderedDict() def add(self, url: str): - video = YouTube(url) - # Download video of set resolution + yt = YouTube(url) video = ( - video.streams.filter( + yt.streams.filter( resolution="360p", progressive=True, ) @@ -47,6 +46,17 @@ def add(self, url: str): .desc() .first() ) + # Fallback for Shorts - get any progressive stream + if video is None: + video = ( + yt.streams.filter(progressive=True) + .order_by("resolution") + .asc() + .first() + ) + if video is None: + logging.error(f"No suitable stream found for {url}") + return None if video.filesize > self.max_size_bytes: logging.info( f"Video size ({video.filesize} bytes) exceeds max cache size ({self.max_size_bytes} bytes). Caching cancelled." @@ -67,8 +77,8 @@ def add(self, url: str): logging.info(f"downloaded {url} to path {video_file_path}") video_info = VideoInfo( file_path=video_file_path, - thumbnail=YouTube(url).thumbnail_url, - title=YouTube(url).title, + thumbnail=yt.thumbnail_url, + title=yt.title, size_bytes=video.filesize, ) self.video_id_to_path[video_id] = video_info @@ -156,5 +166,9 @@ def write_cache(self): @staticmethod def get_video_id(url) -> str: parsed_url = urlparse(url) + # handled yt shorts URL format: youtube.com/shorts/id + if "/shorts/" in parsed_url.path: + return parsed_url.path.split("/shorts/")[1].split("?")[0] + # handled regular URL format: youtube.com/watch?v=VIDEO_ID video_id = parse_qs(parsed_url.query)["v"][0] return video_id diff --git a/requirements.txt b/requirements.txt index aa4276d..d7a9dce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ fastapi==0.96.0 uvicorn==0.22.0 py-grpc-prometheus==0.7.0 psutil==5.9.8 -pytubefix==9.1.1 \ No newline at end of file +pytubefix>=9.1.1 \ No newline at end of file diff --git a/server.py b/server.py index 06c23e5..5a81043 100644 --- a/server.py +++ b/server.py @@ -111,7 +111,7 @@ def create_ffmpeg_stream( "-i", video_path, "-vf", - f"scale=640:360", + "scale=640:360:force_original_aspect_ratio=decrease,pad=640:360:(ow-iw)/2:(oh-ih)/2", "-c:v", "libx264", "-preset", From 2f237ae88e561a97ee88b6767d4c4fe401daf2f1 Mon Sep 17 00:00:00 2001 From: PranAD-dev Date: Wed, 7 Jan 2026 21:02:36 -0800 Subject: [PATCH 2/3] check --- static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.html b/static/index.html index 3867f2c..2056326 100644 --- a/static/index.html +++ b/static/index.html @@ -21,7 +21,7 @@

SCE TV

- +
From fc8671bfc668a0dc9815967321698b1f6d6b5248 Mon Sep 17 00:00:00 2001 From: PranAD-dev Date: Wed, 7 Jan 2026 21:59:58 -0800 Subject: [PATCH 3/3] you can now play youtube shorts on sce-tv!! --- modules/cache.py | 24 +++++++++++++++++++----- requirements.txt | 2 +- server.py | 3 ++- static/index.html | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/modules/cache.py b/modules/cache.py index 3d2b9f4..4c3071f 100644 --- a/modules/cache.py +++ b/modules/cache.py @@ -36,10 +36,9 @@ def __init__( self.video_id_to_path = OrderedDict() def add(self, url: str): - video = YouTube(url) - # Download video of set resolution + yt = YouTube(url) video = ( - video.streams.filter( + yt.streams.filter( resolution="360p", progressive=True, ) @@ -47,6 +46,17 @@ def add(self, url: str): .desc() .first() ) + # for shorts get any progressive stream + if video is None: + video = ( + yt.streams.filter(progressive=True) + .order_by("resolution") + .asc() + .first() + ) + if video is None: + logging.error(f"No suitable stream found for {url}") + return None if video.filesize > self.max_size_bytes: logging.info( f"Video size ({video.filesize} bytes) exceeds max cache size ({self.max_size_bytes} bytes). Caching cancelled." @@ -67,8 +77,8 @@ def add(self, url: str): logging.info(f"downloaded {url} to path {video_file_path}") video_info = VideoInfo( file_path=video_file_path, - thumbnail=YouTube(url).thumbnail_url, - title=YouTube(url).title, + thumbnail=yt.thumbnail_url, + title=yt.title, size_bytes=video.filesize, ) self.video_id_to_path[video_id] = video_info @@ -156,5 +166,9 @@ def write_cache(self): @staticmethod def get_video_id(url) -> str: parsed_url = urlparse(url) + # handled yt shorts URL format: youtube.com/shorts/id + if "/shorts/" in parsed_url.path: + return parsed_url.path.split("/shorts/")[1].split("?")[0] + # handled regular URL format: youtube.com/watch?v=VIDEO_ID video_id = parse_qs(parsed_url.query)["v"][0] return video_id diff --git a/requirements.txt b/requirements.txt index aa4276d..d7a9dce 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ fastapi==0.96.0 uvicorn==0.22.0 py-grpc-prometheus==0.7.0 psutil==5.9.8 -pytubefix==9.1.1 \ No newline at end of file +pytubefix>=9.1.1 \ No newline at end of file diff --git a/server.py b/server.py index 06c23e5..de17b93 100644 --- a/server.py +++ b/server.py @@ -111,7 +111,8 @@ def create_ffmpeg_stream( "-i", video_path, "-vf", - f"scale=640:360", + # this helps the shorts to actually be vertical and not compressed + "scale=640:360:force_original_aspect_ratio=decrease,pad=640:360:(ow-iw)/2:(oh-ih)/2", "-c:v", "libx264", "-preset", diff --git a/static/index.html b/static/index.html index 3867f2c..2056326 100644 --- a/static/index.html +++ b/static/index.html @@ -21,7 +21,7 @@

SCE TV

- +