diff --git a/.gitignore b/.gitignore index 1fa933a..82af27f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ __pycache__ twitch_secrets.json .vscode/settings.json download +output.log +*.mp4 diff --git a/build_videos.py b/build_videos.py index 9cc1a5c..f0456b8 100644 --- a/build_videos.py +++ b/build_videos.py @@ -33,7 +33,7 @@ def build_chat_video(): print(f"๐Ÿš€ Transcribe: {title}") print("====================================================") - twitch_chat_vod.combine_twitch_vod_and_chat(f"download/videos/{id}/{id}.mp4", "overlay") + twitch_chat_vod.combine_twitch_vod_and_chat(f"download/videos/{id}/{id}.mp4") def build_transcribe(): @@ -106,4 +106,6 @@ def build_shorts(): if __name__ =="__main__": DB = database.Database() - build_shorts() \ No newline at end of file + #build_shorts() + build_transcribe() + build_chat_video() \ No newline at end of file diff --git a/database.py b/database.py index 606bbd8..83f10f7 100755 --- a/database.py +++ b/database.py @@ -80,18 +80,18 @@ class Database: """Flags a specific row record to downloaded (0).""" self.__mark_as(record_id, "downloaded", "0") - def __get_unuploaded(self, set_row: str) -> list[Any]: + def __get_unuploaded(self, set_row: str, also: str = "") -> list[Any]: """Retrieve all rows that were download but not uploaded""" - self.cursor.execute(f"SELECT {self.columns} FROM twitch_videos WHERE downloaded = 1 AND {set_row} = 0") + self.cursor.execute(f"SELECT {self.columns} FROM twitch_videos WHERE downloaded = 1 AND {set_row} = 0 {also}") return self.cursor.fetchall() def get_unuploaded_shorts(self) -> list[Any]: """Retrieve all rows that were download but not uploaded_yt_shorts""" - return self.__get_unuploaded("uploaded_yt_shorts") + return self.__get_unuploaded("uploaded_yt_shorts", "AND clip_is = 1") def get_unuploaded_chats(self) -> list[Any]: """Retrieve all rows that were download but not uploaded_yt_chats""" - return self.__get_unuploaded("uploaded_yt_chats") + return self.__get_unuploaded("uploaded_yt_chats", "AND clips_is = 0") def get_unuploaded(self) -> list[Any]: """Retrieve all rows that were download but not uploaded_yt""" diff --git a/twitch_chat_vod.py b/twitch_chat_vod.py index 5becb8b..6dc73e3 100644 --- a/twitch_chat_vod.py +++ b/twitch_chat_vod.py @@ -2,7 +2,7 @@ import os import linux -def combine_twitch_vod_and_chat(vod_path: str, layout: str = "side-by-side") -> bool: +def combine_twitch_vod_and_chat(vod_path: str, layout: str = "side-by-side", force: bool = False) -> bool: """ Renders Twitch chat JSON to video and combines it with the source VOD. Provides real-time terminal feedback for all processing steps. @@ -14,6 +14,10 @@ def combine_twitch_vod_and_chat(vod_path: str, layout: str = "side-by-side") -> mask_path = video_path.replace(".mp4", "_temp_chat_mask.mp4") # Step 1: Pre-flight checks + if os.path.exists(video_chat) and force is False: + print(f"โŒ Error: Chat video allready exists: {video_chat}") + return False + if not os.path.exists(video_path): print(f"โŒ Error: Source video not found: {video_path}") return False diff --git a/youtube_short.py b/youtube_short.py index 2d0c153..53d1ef6 100755 --- a/youtube_short.py +++ b/youtube_short.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import os import linux import tempfile from pathlib import Path @@ -20,11 +21,16 @@ def apply_gaussian_blur(frame, radius: int = 30): # Return back as a numpy array for MoviePy return np.array(blurred_image) -def fit_to_9_16_letterbox(input_path: str, top_text: str = "TOP TEXT", bottom_text: str = "BOTTOM TEXT", use_blur: bool = True): +def fit_to_9_16_letterbox(input_path: str, top_text: str = "TOP TEXT", bottom_text: str = "BOTTOM TEXT", use_blur: bool = True, force: bool = False): input_file = Path(input_path) output_suffix = "gaussian_9_16" if use_blur else "black_9_16" output_path = input_file.parent / f"{input_file.stem}_{output_suffix}{input_file.suffix}" + if os.path.exists(output_path) and force is False: + print(f"โŒ Error: Short video allready exists: {output_path}") + return + + print("๐Ÿงผ Sanitizing video metadata streams inside an automated safe context...") with tempfile.NamedTemporaryFile(suffix=input_file.suffix, delete=False) as temp_file: temp_path = temp_file.name