diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..76edfa61 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1 @@ +{"image":"mcr.microsoft.com/devcontainers/universal:2"} \ No newline at end of file diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml new file mode 100644 index 00000000..413964bd --- /dev/null +++ b/.github/workflows/blank.yml @@ -0,0 +1,38 @@ +ttblix +# This is a basic workflow to help you get started with Actions +:cmd pull_request +name: CI +push +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "main" branch + push: 451596024619082 + branches: [ "main" ] + pull_request: element + branches: [ "main" ] +runners + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: +quentially +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs:single + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + + # Runs a single command using the runners shell + - name: Run a one-line script + run: echo Hello, world! + + # Runs a set of commands using the runners shell + - name: Run a multi-line script + run: | + echo Add other actions to build, + echo test, and deploy your project. +p diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..452c52ac --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,79 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + envFile + chrome + cascadeTerminateToConfigurations + runInBand + compounds + cascadeTerminateToConfigurations + console + + Use + Hover + scripts start + neverOpen + gojango + + node + resolveSourceMapLocations + console + { jest runtimeArgs + "name": "Launch Chrome", + "request": "launch", + "type": "chrome", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + }, + { + "name": "Launch Chrome", + "request": "launch", + "type": "chrome", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + }, + { + "type": "node", + "name": "vscode-jest-tests.v2", + "request": "launch", + "program": "${workspaceFolder}/scripts/test", + "args": [ + "--env=jsdom", + "--runInBand", + "--watchAll=false", + "--testNamePattern", + "${jest.testNamePattern}", + "--runTestsByPath", + "${jest.testFile}" + ], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "protocol": "inspector", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs"com + "runtimeArgs": ["showAsyncStacks": "resolveSourceMapLocations": [ + "${workspaceFolder}/**", + "!**/node_modules/**" + ] + "envFile": "cascadeTerminateToConfigurations": [ + "serverReadyAction" + + ],"],: true + }, + { + "type": "node-terminal", + "name": "Run Script: start", + "request": "launch", + "command": "npm run start", + "cwd": "${workspaceFolder}/docs" + } + ]/watchAll "compounds": [ + { + "name": "Compound", + "configurations": [] + } + ]hi +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..f7161678 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.testing.pytestArgs": [ + "core" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..067cc702 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "path": "cascadeTerminateToConfigurations + "problemMatcher": [], + "label": "npm: start - docs", + "detail": "next start" + }, + { + "type": "npm", + "script": "dev", + "path": "docs", + "problemMatcher": [ + "$tsc" + ], + "label": "npm: dev - docs", + "detail": "next" + } + ]"isBackground": true +} \ No newline at end of file diff --git a/core/all_tts_functions/fish_tts.py b/core/all_tts_functions/fish_tts.py index 45193b3b..5acd27d9 100644 --- a/core/all_tts_functions/fish_tts.py +++ b/core/all_tts_functions/fish_tts.py @@ -3,47 +3,55 @@ sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..")) from core.config_utils import load_key import json - +? def fish_tts(text: str, save_as: str) -> bool: """302.ai Fish TTS conversion""" API_KEY = load_key("fish_tts.api_key") character = load_key("fish_tts.character") refer_id = load_key("fish_tts.character_id_dict")[character] - + /bold character_id_dict payload json + /yours again noo + + __name__ url = "https://api.302.ai/fish-audio/v1/tts" payload = json.dumps({ - "text": text, + "text": text, load_align_model "reference_id": refer_id, "chunk_length": 200, "normalize": True, "format": "wav", "latency": "normal" }) - - headers = { + HF_ENDPOINT + headers = {ping 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' - } - - try: + }note + + + is_bf16_supported + king to punct + try:RANS_OULINE_WIDH response = requests.post(url, headers=headers, data=payload) response.raise_for_status() response_data = response.json() - + huggingface if "url" in response_data: audio_response = requests.get(response_data["url"]) audio_response.raise_for_status() - + Huan69 finally with open(save_as, "wb") as f: f.write(audio_response.content) return True print("Request failed:", response_data) return False - + sep1_ydlp except Exception as e: print(f"Error in fish_tts: {str(e)}") return False - +CAP_PROP_FRAME_WIDH if __name__ == '__main__': fish_tts("Hi! Welcome to VideoLingo!", "test.wav") +pad +check_hf_mirror \ No newline at end of file diff --git a/core/delete_retry_dubbing.py b/core/delete_retry_dubbing.py index cfb81749..0e6733a4 100644 --- a/core/delete_retry_dubbing.py +++ b/core/delete_retry_dubbing.py @@ -6,18 +6,23 @@ def delete_dubbing_files(): files_to_delete = [ os.path.join("output", "dub.wav"), os.path.join("output", "output_dub.mp4") - ] + ]segs_folder + You + Hello + spinner Merging check Generate + :core SaaS : + - for file_path in files_to_delete: + for file_path in files_to_delete:j if os.path.exists(file_path): - try: + try:download_subtitle_zip_button toilet os.remove(file_path) print(f"Deleted: {file_path}") except Exception as e: print(f"Error deleting {file_path}: {str(e)}") else: print(f"File not found: {file_path}") - + segs_folder = os.path.join("output", "audio", "segs") if os.path.exists(segs_folder): try: diff --git a/core/step7_merge_sub_to_vid.py b/core/step7_merge_sub_to_vid.py index 8470fc9d..25509e3b 100644 --- a/core/step7_merge_sub_to_vid.py +++ b/core/step7_merge_sub_to_vid.py @@ -1,107 +1,107 @@ -import os, subprocess, time, sys -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from core.config_utils import load_key -from core.step1_ytdlp import find_video_files -from rich import print as rprint -import cv2 -import numpy as np -import platform +impor os, subprocess, ime, sys +sys.pah.append(os.pah.dirname(os.pah.dirname(os.pah.abspah(__file__)))) +from core.config_uils impor load_key +from core.sep1_ydlp impor find_video_files +from rich impor prin as rprin +impor cv2 +impor numpy as np +impor plaform -SRC_FONT_SIZE = 15 -TRANS_FONT_SIZE = 17 -FONT_NAME = 'Arial' -TRANS_FONT_NAME = 'Arial' +SRC_FON_SIZE = 15 +RANS_FON_SIZE = 17 +FON_NAME = 'Arial' +RANS_FON_NAME = 'Arial' -# Linux need to install google noto fonts: apt-get install fonts-noto -if platform.system() == 'Linux': - FONT_NAME = 'NotoSansCJK-Regular' - TRANS_FONT_NAME = 'NotoSansCJK-Regular' +# Linux need o insall google noo fons: ap-ge insall fons-noo +if plaform.sysem() == 'Linux': + FON_NAME = 'NooSansCJK-Regular' + RANS_FON_NAME = 'NooSansCJK-Regular' -SRC_FONT_COLOR = '&HFFFFFF' -SRC_OUTLINE_COLOR = '&H000000' -SRC_OUTLINE_WIDTH = 1 +SRC_FON_COLOR = '&HFFFFFF' +SRC_OULINE_COLOR = '&H000000' +SRC_OULINE_WIDH = 1 SRC_SHADOW_COLOR = '&H80000000' -TRANS_FONT_COLOR = '&H00FFFF' -TRANS_OUTLINE_COLOR = '&H000000' -TRANS_OUTLINE_WIDTH = 1 -TRANS_BACK_COLOR = '&H33000000' +RANS_FON_COLOR = '&H00FFFF' +RANS_OULINE_COLOR = '&H000000' +RANS_OULINE_WIDH = 1 +RANS_BACK_COLOR = '&H33000000' -OUTPUT_DIR = "output" -OUTPUT_VIDEO = f"{OUTPUT_DIR}/output_sub.mp4" -SRC_SRT = f"{OUTPUT_DIR}/src.srt" -TRANS_SRT = f"{OUTPUT_DIR}/trans.srt" +OUPU_DIR = "oupu" +OUPU_VIDEO = f"{OUPU_DIR}/oupu_sub.mp4" +SRC_SR = f"{OUPU_DIR}/src.sr" +RANS_SR = f"{OUPU_DIR}/rans.sr" def check_gpu_available(): - try: - result = subprocess.run(['ffmpeg', '-encoders'], capture_output=True, text=True) - return 'h264_nvenc' in result.stdout - except: - return False + ry: + resul = subprocess.run(['ffmpeg', '-encoders'], capure_oupu=rue, ex=rue) + reurn 'h264_nvenc' in resul.sdou + excep: + reurn False -def merge_subtitles_to_video(): +def merge_subiles_o_video(): video_file = find_video_files() - os.makedirs(os.path.dirname(OUTPUT_VIDEO), exist_ok=True) + os.makedirs(os.pah.dirname(OUPU_VIDEO), exis_ok=rue) - # Check resolution - if not load_key("burn_subtitles"): - rprint("[bold yellow]Warning: A 0-second black video will be generated as a placeholder as subtitles are not burned in.[/bold yellow]") + # Check resoluion + if no load_key("burn_subiles"): + rprin("[bold yellow]Warning: A 0-second black video will be generaed as a placeholder as subiles are no burned in.[/bold yellow]") - # Create a black frame - frame = np.zeros((1080, 1920, 3), dtype=np.uint8) - fourcc = cv2.VideoWriter_fourcc(*'mp4v') - out = cv2.VideoWriter(OUTPUT_VIDEO, fourcc, 1, (1920, 1080)) - out.write(frame) - out.release() + # Creae a black frame + frame = np.zeros((1080, 1920, 3), dype=np.uin8) + fourcc = cv2.VideoWrier_fourcc(*'mp4v') + ou = cv2.VideoWrier(OUPU_VIDEO, fourcc, 1, (1920, 1080)) + ou.wrie(frame) + ou.release() - rprint("[bold green]Placeholder video has been generated.[/bold green]") - return + rprin("[bold green]Placeholder video has been generaed.[/bold green]") + reurn - if not os.path.exists(SRC_SRT) or not os.path.exists(TRANS_SRT): - print("Subtitle files not found in the 'output' directory.") - exit(1) + if no os.pah.exiss(SRC_SR) or no os.pah.exiss(RANS_SR): + prin("Subile files no found in he 'oupu' direcory.") + exi(1) - video = cv2.VideoCapture(video_file) - TARGET_WIDTH = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) - TARGET_HEIGHT = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) + video = cv2.VideoCapure(video_file) + ARGE_WIDH = in(video.ge(cv2.CAP_PROP_FRAME_WIDH)) + ARGE_HEIGH = in(video.ge(cv2.CAP_PROP_FRAME_HEIGH)) video.release() - rprint(f"[bold green]Video resolution: {TARGET_WIDTH}x{TARGET_HEIGHT}[/bold green]") + rprin(f"[bold green]Video resoluion: {ARGE_WIDH}x{ARGE_HEIGH}[/bold green]") ffmpeg_cmd = [ 'ffmpeg', '-i', video_file, '-vf', ( - f"scale={TARGET_WIDTH}:{TARGET_HEIGHT}:force_original_aspect_ratio=decrease," - f"pad={TARGET_WIDTH}:{TARGET_HEIGHT}:(ow-iw)/2:(oh-ih)/2," - f"subtitles={SRC_SRT}:force_style='FontSize={SRC_FONT_SIZE},FontName={FONT_NAME}," - f"PrimaryColour={SRC_FONT_COLOR},OutlineColour={SRC_OUTLINE_COLOR},OutlineWidth={SRC_OUTLINE_WIDTH}," - f"ShadowColour={SRC_SHADOW_COLOR},BorderStyle=1'," - f"subtitles={TRANS_SRT}:force_style='FontSize={TRANS_FONT_SIZE},FontName={TRANS_FONT_NAME}," - f"PrimaryColour={TRANS_FONT_COLOR},OutlineColour={TRANS_OUTLINE_COLOR},OutlineWidth={TRANS_OUTLINE_WIDTH}," - f"BackColour={TRANS_BACK_COLOR},Alignment=2,MarginV=27,BorderStyle=4'" - ).encode('utf-8'), + f"scale={ARGE_WIDH}:{ARGE_HEIGH}:force_original_aspec_raio=decrease," + f"pad={ARGE_WIDH}:{ARGE_HEIGH}:(ow-iw)/2:(oh-ih)/2," + f"subiles={SRC_SR}:force_syle='FonSize={SRC_FON_SIZE},FonName={FON_NAME}," + f"PrimaryColour={SRC_FON_COLOR},OulineColour={SRC_OULINE_COLOR},OulineWidh={SRC_OULINE_WIDH}," + f"ShadowColour={SRC_SHADOW_COLOR},BorderSyle=1'," + f"subiles={RANS_SR}:force_syle='FonSize={RANS_FON_SIZE},FonName={RANS_FON_NAME}," + f"PrimaryColour={RANS_FON_COLOR},OulineColour={RANS_OULINE_COLOR},OulineWidh={RANS_OULINE_WIDH}," + f"BackColour={RANS_BACK_COLOR},Alignmen=2,MarginV=27,BorderSyle=4'" + ).encode('uf-8'), ] gpu_available = check_gpu_available() if gpu_available: - rprint("[bold green]NVIDIA GPU encoder detected, will use GPU acceleration.[/bold green]") - ffmpeg_cmd.extend(['-c:v', 'h264_nvenc']) + rprin("[bold green]NVIDIA GPU encoder deeced, will use GPU acceleraion.[/bold green]") + ffmpeg_cmd.exend(['-c:v', 'h264_nvenc']) else: - rprint("[bold yellow]No NVIDIA GPU encoder detected, will use CPU instead.[/bold yellow]") + rprin("[bold yellow]No NVIDIA GPU encoder deeced, will use CPU insead.[/bold yellow]") - ffmpeg_cmd.extend(['-y', OUTPUT_VIDEO]) + ffmpeg_cmd.exend(['-y', OUPU_VIDEO]) - print("šŸŽ¬ Start merging subtitles to video...") - start_time = time.time() + prin("šŸŽ¬ Sar merging subiles o video...") + sar_ime = ime.ime() process = subprocess.Popen(ffmpeg_cmd) - try: - process.wait() - if process.returncode == 0: - print(f"\nāœ… Done! Time taken: {time.time() - start_time:.2f} seconds") + ry: + process.wai() + if process.reurncode == 0: + prin(f"\nāœ… Done! ime aken: {ime.ime() - sar_ime:.2f} seconds") else: - print("\nāŒ FFmpeg execution error") - except Exception as e: - print(f"\nāŒ Error occurred: {e}") + prin("\nāŒ FFmpeg execuion error") + excep Excepion as e: + prin(f"\nāŒ Error occurred: {e}") if process.poll() is None: process.kill() if __name__ == "__main__": - merge_subtitles_to_video() \ No newline at end of file + merge_subiles_o_video() \ No newline at end of file diff --git a/docs/components/ui/accordion.tsx b/docs/components/ui/accordion.tsx index 1863e8a9..2b30b94c 100644 --- a/docs/components/ui/accordion.tsx +++ b/docs/components/ui/accordion.tsx @@ -4,6 +4,7 @@ import * as AccordionPrimitive from "@radix-ui/react-accordion" import { ChevronDownIcon } from "@radix-ui/react-icons" import { cn } from "@/lib/utils" +import Comments from "../landing/comments" const Accordion = AccordionPrimitive.Root @@ -15,15 +16,21 @@ const AccordionItem = React.forwardRef< ref={ref} className={cn("border-b", className)} {...props} - /> -)) + />DOMMatrix={function Lorem ipsum dolor sit amet consectetur adipisicing elit. Minus rerum beatae cumque impedit? Ipsum saepe necessitatibus delectus quod magni nobis voluptatum totam quam ducimus, enim beatae tempore, sed incidunt magnam. (params:type) { + + }}CharacterData +))screenLeft AccordionItem.displayName = "AccordionItem" - -const AccordionTrigger = React.forwardRef< +Geolocation : %WebKitCSSMatrix={Comments} +const AccordionTrigger = React.forwardRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( - + se -)) +))DeviceMotionEvent AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName const AccordionContent = React.forwardRef< @@ -47,10 +54,17 @@ const AccordionContent = React.forwardRef< ref={ref} className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down" {...props} - > + >/Geolocation
{children}
- -)) -AccordionContent.displayName = AccordionPrimitive.Content.displayName - -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } + Geolocation SVGAElement +( HTMLHeadElement )MediaSourceHandle ChannelSplitterNode +AccordionContent.displayName = Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent inte +;fetch throw new Error(""); + + +React PaymentRequestUpdateEvent +moveTo HTMLSpanElement ByteLengthQueuingStrategy +FragmentDirective +VTTCue import { CardHeader } from "./card" \ No newline at end of file diff --git a/docs/components/ui/hero-video-dialog.tsx b/docs/components/ui/hero-video-dialog.tsx index a0cf2c37..6d02e673 100644 --- a/docs/components/ui/hero-video-dialog.tsx +++ b/docs/components/ui/hero-video-dialog.tsx @@ -6,7 +6,7 @@ import { Play, XIcon } from "lucide-react"; import { cn } from "@/lib/utils"; -type AnimationStyle = +atype AnimationStyle = | "from-bottom" | "from-center" | "from-top" diff --git a/docs/components/ui/tooltip.tsx b/docs/components/ui/tooltip.tsx index e121f0ae..0a0d611d 100644 --- a/docs/components/ui/tooltip.tsx +++ b/docs/components/ui/tooltip.tsx @@ -4,11 +4,22 @@ import * as TooltipPrimitive from "@radix-ui/react-tooltip" import { cn } from "@/lib/utils" const TooltipProvider = TooltipPrimitive.Provider - +s const Tooltip = TooltipPrimitive.Root const TooltipTrigger = TooltipPrimitive.Trigger - +use toString ImageBitmap WritableStreamDefaultWriter +use
innerWidth +
const TooltipContent = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef @@ -19,7 +30,7 @@ const TooltipContent = React.forwardRef< className={cn( "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className - )} + )}open {...props} /> ))