### Install Dependencies and Setup Environment Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Clone the repository, install dependencies using Poetry, and configure API keys in a .env file. ```bash git clone https://github.com/alexfazio/viral-clips-crew.git cd viral-clips-crew pip install poetry poetry install poetry update pydantic # Create .env with both required keys echo -e "OPENAI_API_KEY=sk-... GEMINI_API_KEY=AIza..." > .env ``` -------------------------------- ### Install Project Dependencies with Poetry Source: https://github.com/alexfazio/viral-clips-crew/blob/main/README.md Install all required Python packages for the project using Poetry. ```shell poetry install ``` -------------------------------- ### Install Poetry for Dependency Management Source: https://github.com/alexfazio/viral-clips-crew/blob/main/README.md Install Poetry, a Python dependency management tool, which is used to manage project dependencies. ```shell pip install poetry ``` -------------------------------- ### Clone Repository with Git Source: https://github.com/alexfazio/viral-clips-crew/blob/main/README.md Clone the viral-clips-crew repository to your local machine to begin setup. ```shell git clone https://github.com/alexfazio/viral-clips-crew.git ``` -------------------------------- ### clipper.main() / clipper.process_video() — FFmpeg Video Trimming Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Reads start and end timestamps from an SRT file to trim a video. Enforces minimum (30s) and maximum (150s) clip lengths. Optionally crops to a 1:1 square aspect ratio. Output is saved as `*_trimmed.mp4`. ```APIDOC ## `clipper.main()` / `clipper.process_video()` — FFmpeg Video Trimming Reads the start and end timestamps from a crew-generated `.srt` file and uses ffmpeg to trim the source video to that exact duration. Enforces minimum (30s) and maximum (150s / 2.5 min) clip length guards. Optionally crops to 1:1 square aspect ratio for social media. Output is saved as `*_trimmed.mp4` in the specified output folder. ### Parameters - **input_video** (string) - Required - Path to the input video file. - **subtitle_file_path** (string) - Required - Path to the SRT subtitle file. - **output_folder** (string) - Required - Folder where the trimmed video will be saved. - **aspect_ratio_choice** (string) - Optional - "1" to keep original aspect ratio, "2" to crop to 1:1 square. ### Request Example ```python import clipper # Trim a video segment based on SRT timecodes, keeping original aspect ratio clipper.main( input_video="./input_files/interview.mp4", subtitle_file_path="./crew_output/new_file_return_subtitles_1_20241015_143022.srt", output_folder="./clipper_output", aspect_ratio_choice="1" # "1" = keep original, "2" = crop to 1:1 square ) ``` ### Response Example ``` # INFO - Extracted Start Time: 00:01:57.000 # INFO - Extracted End Time: 00:03:12.400 # INFO - Calculated Duration: 75.40 seconds # INFO - Trimmed video saved to ./clipper_output/new_file_return_subtitles_1_20241015_143022_trimmed.mp4 ``` ``` -------------------------------- ### subtitler.adjust_subtitle_timing() — Normalize SRT Timecodes to Clip Start Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Shifts all SRT timecodes so that the first subtitle entry starts at `00:00:00,000`, ensuring correct alignment with trimmed video clips. ```APIDOC ### `subtitler.adjust_subtitle_timing()` — Normalize SRT Timecodes to Clip Start Shifts all SRT timecodes so that the first subtitle entry starts at `00:00:00,000`, making subtitles align correctly when burned into a trimmed clip that starts mid-video. ### Parameters - **subtitle_path** (string) - Required - Path to the input SRT file. - **output_path** (string) - Required - Path where the adjusted SRT file will be saved. ### Request Example ```python from subtitler import adjust_subtitle_timing adjust_subtitle_timing( subtitle_path="./crew_output/segment.srt", output_path="./subtitler_output/segment_adjusted.srt" ) ``` ### Response Example ``` # Input SRT first entry: 00:01:57,000 --> 00:02:00,400 # Output SRT first entry: 00:00:00,000 --> 00:00:03,400 ``` ``` -------------------------------- ### Single-File Whisper Transcription Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Transcribes a single audio/video file using a pre-loaded Whisper model instance. Returns the raw result dict, the plain-text transcript, and the SRT subtitle string. Requires PyTorch and Whisper to be installed. ```python import torch import whisper from local_transcribe import transcribe_file DEVICE = "cuda" if torch.cuda.is_available() else "cpu" model = whisper.load_model("medium.en").to(DEVICE) result, transcript, subtitles = transcribe_file( model=model, srt=True, plain=True, file="./input_files/interview.mp4" ) print(transcript[:200]) # → "Today we're discussing the future of artificial intelligence..." print(subtitles[:150]) # → "1\n00:00:00,000 --> 00:00:03,120\nToday we're discussing\n\n2\n00:00:03,120 --> ..." ``` -------------------------------- ### Configure API Keys in .env File Source: https://github.com/alexfazio/viral-clips-crew/blob/main/README.md Create and populate the .env file with your OpenAI and Google Gemini API keys. Ensure these keys are kept secure. ```shell echo -e "OPENAI_API_KEY=\nGEMINI_API_KEY=" > .env ``` -------------------------------- ### Run viral-clips-crew with Poetry Source: https://github.com/alexfazio/viral-clips-crew/blob/main/README.md Execute the main application script using Poetry. This command initiates the video processing workflow. ```shell poetry run python app.py ``` -------------------------------- ### local_transcribe.local_whisper_process() Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Processes all .mp4 files in input_folder using the locally-running OpenAI Whisper medium.en model. Outputs both .txt transcripts and .srt subtitle files to whisper_output/. Automatically selects CUDA if a GPU is available, otherwise falls back to CPU. ```APIDOC ## `local_transcribe.local_whisper_process()` — Local Whisper Transcription Processes all `.mp4` files in `input_folder` using the locally-running OpenAI Whisper `medium.en` model. Outputs both `.txt` transcripts and `.srt` subtitle files to `whisper_output/`. Automatically selects CUDA if a GPU is available, otherwise falls back to CPU. ```python from local_transcribe import local_whisper_process local_whisper_process( input_folder="./input_files", crew_output_folder="./whisper_output" ) # Logs: # INFO - Processing video: ./input_files/interview.mp4 # INFO - Transcribing file: input_files/interview.mp4 # INFO - Creating text file: whisper_output/interview.txt # INFO - Creating SRT file # INFO - local_transcribe.py completed # # Output: # whisper_output/interview.txt → full plain-text transcript # whisper_output/interview.srt → timestamped subtitle file ``` ``` -------------------------------- ### crew.main() Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Initializes a CrewAI sequential crew with three parallel Gemini 1.5 Pro agents (one per extract). Each agent receives an extracted text segment and the full SRT file, and its task is to match the extract to the corresponding timestamped subtitle block, returning a valid .srt fragment. Output files are written to crew_output/ with timestamped filenames. ```APIDOC ## `crew.main()` — Multi-Agent SRT Alignment Crew Initializes a CrewAI sequential crew with three parallel Gemini 1.5 Pro agents (one per extract). Each agent receives an extracted text segment and the full SRT file, and its task is to match the extract to the corresponding timestamped subtitle block, returning a valid `.srt` fragment. Output files are written to `crew_output/` with timestamped filenames. ```python from crew import main as crew_main from extracts import main as extracts_main # extracts is a list of 3 text strings extracts = extracts_main() crew_main(extracts) # Each Gemini agent produces a timestamped .srt file, e.g.: # crew_output/new_file_return_subtitles_1_20241015_143022_123456.srt # crew_output/new_file_return_subtitles_2_20241015_143022_789012.srt # crew_output/new_file_return_subtitles_3_20241015_143022_345678.srt # ``` ``` -------------------------------- ### reboot.main() — Workspace Reset Utility Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Clears all pipeline output directories by sending files to the system trash, preserving directory structure and placeholder files. Prompts for confirmation before proceeding. ```APIDOC ## `reboot.main()` — Workspace Reset Utility Clears all pipeline output directories by sending files to the system trash (via `send2trash`), preserving the directory structure and the `PLACE_CLIPS_HERE` placeholder. Prompts for confirmation before proceeding. Safe to run between pipeline executions. ### Usage Run interactively from the project root: ```bash poetry run python reboot.py ``` ### Confirmation Prompt ``` WARNING: Running reboot.py will erase both input and output files! Are you sure you want to continue? (y/n): y ``` ### Files Cleared ``` Sends to trash: clipper_output/*.mp4 whisper_output/* crew_output/* (except api_response.json which is cleared to empty) input_files/*.mp4 subtitler_output/*.mp4 ``` ``` -------------------------------- ### Local Whisper Transcription for Multiple Files Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Processes all .mp4 files in a specified input folder using a local OpenAI Whisper model. Outputs both .txt transcripts and .srt subtitle files. Automatically selects CUDA if available, otherwise falls back to CPU. ```python from local_transcribe import local_whisper_process local_whisper_process( input_folder="./input_files", crew_output_folder="./whisper_output" ) # Logs: # INFO - Processing video: ./input_files/interview.mp4 # INFO - Transcribing file: input_files/interview.mp4 # INFO - Creating text file: whisper_output/interview.txt # INFO - Creating SRT file # INFO - local_transcribe.py completed # # Output: # whisper_output/interview.txt → full plain-text transcript # whisper_output/interview.srt → timestamped subtitle file ``` -------------------------------- ### Multi-Agent SRT Alignment Crew Initialization Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Initializes a CrewAI sequential crew with parallel agents to match extracted text segments to corresponding timestamped subtitle blocks. Each agent receives an extract and the full SRT file, producing a valid .srt fragment. Output files are written to `crew_output/`. ```python from crew import main as crew_main from extracts import main as extracts_main # extracts is a list of 3 text strings extracts = extracts_main() crew_main(extracts) # Each Gemini agent produces a timestamped .srt file, e.g.: # crew_output/new_file_return_subtitles_1_20241015_143022_123456.srt # crew_output/new_file_return_subtitles_2_20241015_143022_789012.srt # crew_output/new_file_return_subtitles_3_20241015_143022_345678.srt # ``` -------------------------------- ### Run End-to-End Pipeline Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Execute the main orchestrator in app.py to run the full transcript-to-subtitle pipeline. This script validates environment variables and prompts the user for input. ```python # Run the complete pipeline interactively poetry run python app.py # Runtime prompts: # Please select an option to proceed: # 1: Submit a YouTube Video Link # 2: Use an existing video file # Please choose either option 1 or 2: 2 # # Choose aspect ratio for all videos: (1) Keep as original, (2) 1:1 (square): 1 # # Expected directory outputs after completion: # whisper_output/ → full transcript (.txt) and subtitles (.srt) # crew_output/ → per-segment .srt files + api_response.json # clipper_output/ → *_trimmed.mp4 segments # subtitler_output/ → *_subtitled.mp4 final deliverables ``` -------------------------------- ### extracts.main() Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Reads the Whisper-generated transcript from whisper_output/, sends it to the OpenAI gpt-4o-2024-08-06 API with a structured JSON schema prompt, and returns a ranked list of the top 3 most viral-worthy ~1-minute text segments. The raw API response is also saved to crew_output/api_response.json. ```APIDOC ## `extracts.main()` — GPT-4o Viral Clip Identification Reads the Whisper-generated transcript from `whisper_output/`, sends it to the OpenAI `gpt-4o-2024-08-06` API with a structured JSON schema prompt, and returns a ranked list of the top 3 most viral-worthy ~1-minute text segments. The raw API response is also saved to `crew_output/api_response.json`. ```python from extracts import main as extracts_main extracts = extracts_main() # Returns list of 3 text strings ranked by viral potential, e.g.: # [ # "Demis Hassabis: I think it's more the latter. In the near term it's hyped too much...", # "Well, I think it's great that governments are getting up to speed...", # "The problem is that we need more. I think this is one thing the whole field needs..." # ] # # Also writes: crew_output/api_response.json # { # "clips": [ # {"rank": 1, "text": "...", "wordcount": 102}, # {"rank": 2, "text": "...", "wordcount": 114}, # {"rank": 3, "text": "...", "wordcount": 111} # ] # } ``` ``` -------------------------------- ### Write Plain-Text Transcript to File Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Joins all transcript entries into a single continuous string and writes it to a .txt file. This is used downstream for AI analysis. ```python from youtube_transcript_api import YouTubeTranscriptApi from ytdl import yt_vid_id_to_txt transcript = YouTubeTranscriptApi.get_transcript("dQw4w9WgXcQ") yt_vid_id_to_txt(transcript, "dQw4w9WgXcQ", txt_save_path="./whisper_output") # Output file: ./whisper_output/transcript.txt # Content: "We're no strangers to love You know the rules and so do I..." ``` -------------------------------- ### local_transcribe.transcribe_file() Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Transcribes a single audio/video file using a pre-loaded Whisper model instance. Returns the raw result dict, the plain-text transcript, and the SRT subtitle string. ```APIDOC ### `local_transcribe.transcribe_file()` — Single-File Whisper Transcription Transcribes a single audio/video file using a pre-loaded Whisper model instance. Returns the raw result dict, the plain-text transcript, and the SRT subtitle string. ```python import torch import whisper from local_transcribe import transcribe_file DEVICE = "cuda" if torch.cuda.is_available() else "cpu" model = whisper.load_model("medium.en").to(DEVICE) result, transcript, subtitles = transcribe_file( model=model, srt=True, plain=True, file="./input_files/interview.mp4" ) print(transcript[:200]) # → "Today we're discussing the future of artificial intelligence..." print(subtitles[:150]) # → "1\n00:00:00,000 --> 00:00:03,120\nToday we're discussing\n\n2\n00:00:03,120 --> ..." ``` ``` -------------------------------- ### Download YouTube Video and Extract Transcript Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Use the ytdl.main function to download a YouTube video and save its transcript and subtitles. Ensure the necessary directories exist. ```python from ytdl import main as ytdl_main url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" ytdl_main( yt_vid_url=url, mp4_dir_save_path="./input_files", srt_dir_save_path="./whisper_output", txt_dir_save_path="./whisper_output" ) # Output: # input_files/Rick_Astley_-_Never_Gonna_Give_You_Up.mp4 # whisper_output/subtitles.srt # whisper_output/transcript.txt ``` -------------------------------- ### Reset Workspace Utility Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Clears all pipeline output directories by moving files to the system trash. Preserves directory structure and the `PLACE_CLIPS_HERE` placeholder. Prompts for confirmation before execution. ```python # Run interactively poetry run python reboot.py # WARNING: Running reboot.py will erase both input and output files! # Are you sure you want to continue? (y/n): y # # Sends to trash: # clipper_output/*.mp4 # whisper_output/* # crew_output/* (except api_response.json which is cleared to empty) # input_files/*.mp4 # subtitler_output/*.mp4 ``` -------------------------------- ### extracts.call_openai_api() Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Sends the transcript to GPT-4o with a strict JSON schema response format requesting exactly 3 ranked clips, each with extracted text and word count. Handles JSON decode errors and pads missing clips with filler content to guarantee a 3-element output. ```APIDOC ### `extracts.call_openai_api()` — Structured GPT-4o API Call Sends the transcript to GPT-4o with a strict JSON schema response format requesting exactly 3 ranked clips, each with extracted text and word count. Handles JSON decode errors and pads missing clips with filler content to guarantee a 3-element output. ```python from extracts import call_openai_api transcript = open("whisper_output/transcript.txt").read() response = call_openai_api(transcript) # Returns: # { # "clips": [ # {"rank": 1, "text": "Most impactful quote...", "wordcount": 108}, # {"rank": 2, "text": "Second best moment...", "wordcount": 95}, # {"rank": 3, "text": "Third best moment...", "wordcount": 112} # ] # } if response: for clip in response["clips"]: print(f"Rank {clip['rank']} ({clip['wordcount']} words): {clip['text'][:80]}...") ``` ``` -------------------------------- ### ytdl.yt_vid_id_to_txt() Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Joins all transcript entries into a single continuous string and writes it to a .txt file. This is used downstream by extracts.py for GPT-4o analysis. ```APIDOC ## `ytdl.yt_vid_id_to_txt()` — Write Plain-Text Transcript Joins all transcript entries into a single continuous string and writes it to a `.txt` file — used downstream by `extracts.py` for GPT-4o analysis. ```python from youtube_transcript_api import YouTubeTranscriptApi from ytdl import yt_vid_id_to_txt transcript = YouTubeTranscriptApi.get_transcript("dQw4w9WgXcQ") yt_vid_id_to_txt(transcript, "dQw4w9WgXcQ", txt_save_path="./whisper_output") # Output file: ./whisper_output/transcript.txt # Content: "We're no strangers to love You know the rules and so do I..." ``` ``` -------------------------------- ### FFmpeg Hard-Subtitle Burn Wrapper Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt A low-level Python wrapper for the FFmpeg `-vf subtitles` filter to hard-code subtitles into a video. Audio is copied without re-encoding. ```python from subtitler import burn_subtitles burn_subtitles( video_path="./clipper_output/clip_trimmed.mp4", subtitle_path="./subtitler_output/clip_utf8.srt", output_video_path="./subtitler_output/clip_subtitled.mp4" ) # Equivalent shell command: # ffmpeg -i clip_trimmed.mp4 -vf subtitles=clip_utf8.srt -c:a copy clip_subtitled.mp4 ``` -------------------------------- ### Download Best-Quality MP4 from YouTube URL Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Use yt_vid_url_to_mp4 to download the highest-quality MP4 stream from a YouTube URL to a specified directory using yt-dlp. ```python from ytdl import yt_vid_url_to_mp4 video_path = yt_vid_url_to_mp4( yt_vid_url="https://www.youtube.com/watch?v=dQw4w9WgXcQ", mp4_dir_save_path="./input_files" ) print(video_path) # → "./input_files/Rick_Astley_-_Never_Gonna_Give_You_Up.mp4" ``` -------------------------------- ### Structured GPT-4o API Call for Clips Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Sends a transcript to GPT-4o with a strict JSON schema response format requesting exactly 3 ranked clips. Handles JSON decode errors and pads missing clips with filler content to guarantee a 3-element output. ```python from extracts import call_openai_api transcript = open("whisper_output/transcript.txt").read() response = call_openai_api(transcript) # Returns: # { # "clips": [ # {"rank": 1, "text": "Most impactful quote...", "wordcount": 108}, # {"rank": 2, "text": "Second best moment...", "wordcount": 95}, # {"rank": 3, "text": "Third best moment...", "wordcount": 112} # ] # } if response: for clip in response["clips"]: print(f"Rank {clip['rank']} ({clip['wordcount']} words): {clip['text'][:80]}...") ``` -------------------------------- ### Trim Video Segment with FFmpeg Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Trims video segments based on SRT timecodes, enforcing minimum and maximum clip lengths. Optionally crops to a 1:1 square aspect ratio. Output is saved as `*_trimmed.mp4`. ```python import clipper # Trim a video segment based on SRT timecodes, keeping original aspect ratio clipper.main( input_video="./input_files/interview.mp4", subtitle_file_path="./crew_output/new_file_return_subtitles_1_20241015_143022.srt", output_folder="./clipper_output", aspect_ratio_choice="1" # "1" = keep original, "2" = crop to 1:1 square ) # INFO - Extracted Start Time: 00:01:57.000 # INFO - Extracted End Time: 00:03:12.400 # INFO - Calculated Duration: 75.40 seconds # INFO - Trimmed video saved to ./clipper_output/new_file_return_subtitles_1_20241015_143022_trimmed.mp4 # 1:1 square crop example (useful for Instagram/TikTok) clipper.main( input_video="./input_files/interview.mp4", subtitle_file_path="./crew_output/new_file_return_subtitles_2_20241015_143022.srt", output_folder="./clipper_output", aspect_ratio_choice="2" ) ``` -------------------------------- ### utils.wait_for_file() — File Lock Synchronization Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt A polling utility that blocks execution until a specified file is accessible, using `lockfile.FileLock`. Useful for ensuring downstream processes wait for file generation. ```APIDOC ## `utils.wait_for_file()` — File Lock Synchronization A polling utility using `lockfile.FileLock` that blocks execution until the specified file is accessible (lock acquired). Used by `local_transcribe.py` to ensure Whisper has finished writing the SRT file before downstream processing begins. ### Parameters - **file_path** (string) - Required - The path to the file to wait for. ### Request Example ```python from utils import wait_for_file # Blocks until ./whisper_output/interview.srt is available ready = wait_for_file("./whisper_output/interview.srt") if ready: with open("./whisper_output/interview.srt") as f: subtitles = f.read() ``` ``` -------------------------------- ### Update Pydantic Dependency Source: https://github.com/alexfazio/viral-clips-crew/blob/main/README.md Update the Pydantic library to its latest version using Poetry. ```shell poetry update pydantic ``` -------------------------------- ### subtitler.process_video_and_subtitles() — Burn Subtitles into Video Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt The final rendering step that adjusts subtitle timecodes, converts encoding to UTF-8, and hard-burns subtitles into the video using ffmpeg. Temporary SRT files are cleaned up automatically. ```APIDOC ## `subtitler.process_video_and_subtitles()` — Burn Subtitles into Video The final rendering step. Adjusts subtitle timecodes to be relative to the trimmed clip start time (rather than the original video), converts encoding to UTF-8, then uses ffmpeg to hard-burn the subtitles into the video. Temporary adjusted/converted SRT files are cleaned up automatically. ### Parameters - **video_path** (string) - Required - Path to the trimmed video file. - **subtitle_path** (string) - Required - Path to the original SRT subtitle file. - **output_folder** (string) - Required - Folder where the final video with burned-in subtitles will be saved. ### Request Example ```python import subtitler subtitler.process_video_and_subtitles( video_path="./clipper_output/new_file_return_subtitles_1_20241015_143022_trimmed.mp4", subtitle_path="./crew_output/new_file_return_subtitles_1_20241015_143022.srt", output_folder="./subtitler_output" ) ``` ### Response Example ``` # INFO - Subtitles timings adjusted: subtitler_output/new_file_..._adjusted.srt # INFO - Subtitle encoding converted: subtitler_output/new_file_..._utf8.srt # INFO - Subtitles have been burned into the video: subtitler_output/new_file_..._subtitled.mp4 # INFO - Temporary subtitle files removed. # # Final output: ./subtitler_output/new_file_return_subtitles_1_20241015_143022_trimmed_subtitled.mp4 ``` ``` -------------------------------- ### Wait for File Availability Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Polls for the existence of a specified file using `lockfile.FileLock`. Blocks execution until the file is accessible, ensuring downstream processes wait for file creation. ```python from utils import wait_for_file # Blocks until ./whisper_output/interview.srt is available ready = wait_for_file("./whisper_output/interview.srt") if ready: with open("./whisper_output/interview.srt") as f: subtitles = f.read() ``` -------------------------------- ### Convert Transcript to SRT File Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt The yt_vid_id_to_srt function takes a raw transcript list and writes a properly formatted .srt subtitle file. Requires the youtube-transcript-api library. ```python from youtube_transcript_api import YouTubeTranscriptApi from ytdl import yt_vid_id_to_srt transcript = YouTubeTranscriptApi.get_transcript("dQw4w9WgXcQ") yt_vid_id_to_srt(transcript, "dQw4w9WgXcQ", srt_save_path="./whisper_output") # Output file: ./whisper_output/subtitles.srt # Format: # 1 # 00:00:00,000 --> 00:00:03,420 # We're no strangers to love ``` -------------------------------- ### Normalize SRT Timecodes Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Shifts SRT timecodes so the first subtitle entry begins at `00:00:00,000`. This ensures subtitles align correctly with trimmed video clips. ```python from subtitler import adjust_subtitle_timing adjust_subtitle_timing( subtitle_path="./crew_output/segment.srt", output_path="./subtitler_output/segment_adjusted.srt" ) # Input SRT first entry: 00:01:57,000 --> 00:02:00,400 # Output SRT first entry: 00:00:00,000 --> 00:00:03,400 ``` -------------------------------- ### subtitler.burn_subtitles() — FFmpeg Hard-Subtitle Burn Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt A low-level wrapper for the `ffmpeg -vf subtitles=...` filter to hard-code subtitles into the video stream. Audio is copied without re-encoding. ```APIDOC ### `subtitler.burn_subtitles()` — FFmpeg Hard-Subtitle Burn Low-level wrapper around the `ffmpeg -vf subtitles=...` filter to hard-code subtitles into the video stream. Audio is copied without re-encoding. ### Parameters - **video_path** (string) - Required - Path to the input video file. - **subtitle_path** (string) - Required - Path to the UTF-8 encoded subtitle file. - **output_video_path** (string) - Required - Path for the output video with burned-in subtitles. ### Request Example ```python from subtitler import burn_subtitles burn_subtitles( video_path="./clipper_output/clip_trimmed.mp4", subtitle_path="./subtitler_output/clip_utf8.srt", output_video_path="./subtitler_output/clip_subtitled.mp4" ) ``` ### Response Example ``` # Equivalent shell command: # ffmpeg -i clip_trimmed.mp4 -vf subtitles=clip_utf8.srt -c:a copy clip_subtitled.mp4 ``` ``` -------------------------------- ### Burn Subtitles into Video Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Hard-burns subtitles into the video stream after adjusting their timecodes to align with the trimmed clip. Converts subtitle encoding to UTF-8 and cleans up temporary files. ```python import subtitler subtitler.process_video_and_subtitles( video_path="./clipper_output/new_file_return_subtitles_1_20241015_143022_trimmed.mp4", subtitle_path="./crew_output/new_file_return_subtitles_1_20241015_143022.srt", output_folder="./subtitler_output" ) # INFO - Subtitles timings adjusted: subtitler_output/new_file_..._adjusted.srt # INFO - Subtitle encoding converted: subtitler_output/new_file_..._utf8.srt # INFO - Subtitles have been burned into the video: subtitler_output/new_file_..._subtitled.mp4 # INFO - Temporary subtitle files removed. # # Final output: ./subtitler_output/new_file_return_subtitles_1_20241015_143022_trimmed_subtitled.mp4 ``` -------------------------------- ### GPT-4o Viral Clip Identification Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Reads Whisper-generated transcripts, sends them to the OpenAI GPT-4o API with a structured JSON schema prompt, and returns a ranked list of the top 3 most viral-worthy text segments. The raw API response is also saved. ```python from extracts import main as extracts_main extracts = extracts_main() # Returns list of 3 text strings ranked by viral potential, e.g.: # [ # "Demis Hassabis: I think it's more the latter. In the near term it's hyped too much...", # "Well, I think it's great that governments are getting up to speed...", # "The problem is that we need more. I think this is one thing the whole field needs..." # ] # # Also writes: crew_output/api_response.json # { # "clips": [ # {"rank": 1, "text": "...", "wordcount": 102}, # {"rank": 2, "text": "...", "wordcount": 114}, # {"rank": 3, "text": "...", "wordcount": 111} # ] # } ``` -------------------------------- ### Extract YouTube Video ID Source: https://context7.com/alexfazio/viral-clips-crew/llms.txt Utilize the extract_video_id function to parse the 11-character video ID from various YouTube URL formats. Returns None for invalid URLs. ```python from ytdl import extract_video_id # Standard watch URL extract_video_id("https://www.youtube.com/watch?v=dQw4w9WgXcQ") # → "dQw4w9WgXcQ" # Short URL extract_video_id("https://youtu.be/dQw4w9WgXcQ") # → "dQw4w9WgXcQ" # YouTube Shorts extract_video_id("https://www.youtube.com/shorts/dQw4w9WgXcQ") # → "dQw4w9WgXcQ" # Invalid URL extract_video_id("https://vimeo.com/123456") # → None ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.