diff --git a/MANUAL_PIPELINE_GUIDE.md b/MANUAL_PIPELINE_GUIDE.md index e92e6da..0e87e3e 100644 --- a/MANUAL_PIPELINE_GUIDE.md +++ b/MANUAL_PIPELINE_GUIDE.md @@ -98,8 +98,17 @@ background_video = "minecraft" # Video nền background_audio = "lofi" # Audio nền background_audio_volume = 0.15 # Âm lượng audio nền (0 = tắt) max_video_length = 120 # Max thời lượng video (giây) +watermark_enabled = true # Enable/disable watermark overlay +watermark_path = "assets/backgrounds/transparent-bg.png" # Path to watermark PNG file ``` +**Watermark:** +- `watermark_enabled`: Set to `true` để thêm watermark vào tất cả videos, `false` để tắt +- `watermark_path`: Đường dẫn tới file PNG watermark (mặc định: `assets/transparent-bg.png`) + - File phải có kích thước 1080×1920 pixels với alpha transparency + - Vùng transparent sẽ hiển thị video phía dưới + - Watermark xuất hiện suốt thời lượng của video + TTS engine được lấy từ section `[settings.tts]` trong `config.toml`. Mặc định dùng **GoogleTranslate** (không cần API key). --- diff --git a/TTS/OhFreeMe.py b/TTS/OhFreeMe.py index 2f9b904..a3ca218 100644 --- a/TTS/OhFreeMe.py +++ b/TTS/OhFreeMe.py @@ -16,7 +16,7 @@ load_dotenv() OHFREEME_API_URL = os.getenv("OHFREEME_API_URL", "") OHFREEME_BASE_URL = os.getenv("OHFREEME_BASE_URL", "") -JWT_TOKEN = os.getenv("OHFREEME_JWT_TOKEN", "") +OHFREEME_JWT_TOKEN = os.getenv("OHFREEME_JWT_TOKEN", "") VOICES_FILE = Path(__file__).resolve().parent.parent / "config" / "ohfreeme_voices.json" MAX_RETRIES = 3 RATE_LIMIT_WAIT = 10 @@ -101,13 +101,16 @@ class OhFreeMe: "pitch": settings.config["settings"]["tts"].get("ohfreeme_pitch", 0), } headers = { - "accept": "*/*", "cache-control": "no-cache", "content-type": "application/json", - "origin": OHFREEME_BASE_URL, - "cookie": f"auth_token={JWT_TOKEN}", - "referer": OHFREEME_BASE_URL, - "user-agent": self._pick_user_agent(), + "accept": "*/*", + "accept-language": "en-GB,en-US;q=0.9,en;q=0.8,vi;q=0.7", # important + "sec-fetch-mode": "cors", # important + "sec-fetch-site": "same-origin", # important + "Cookie": f"auth_token={OHFREEME_JWT_TOKEN}", # important + "user-agent": self._pick_user_agent(), # important + # "origin": OHFREEME_BASE_URL, + # "referer": f"{OHFREEME_BASE_URL}/", } # streaming NDJSON response with debug logging @@ -138,7 +141,7 @@ class OhFreeMe: continue # debug: print raw line (decoded) to terminal if data.get("status") == "done": - print_substep(f"[OhFreeMe debug] Received line: {data}", style="blue") + print_substep(f"[OhFreeMe debug] Received") return self._extract_audio(data) raise RuntimeError(f"OhFreeMe TTS failed after {MAX_RETRIES} retries (rate limited)") diff --git a/manual/video_builder.py b/manual/video_builder.py index b11ff5d..6ad5f7e 100644 --- a/manual/video_builder.py +++ b/manual/video_builder.py @@ -111,6 +111,10 @@ class ManualVideoBuilder: # Output settings self.output_dir = Path(self.config.get("output_dir", "manual_results")) + # Watermark settings + self.watermark_enabled = self.config.get("watermark_enabled", True) + self.watermark_path = Path(self.config.get("watermark_path", "assets/backgrounds/transparent-bg.png")) + def build(self) -> str: """Build the final video. @@ -189,12 +193,24 @@ class ManualVideoBuilder: ) current_time += s["audio_duration"] - # Step 7: Render + # Step 7: Overlay watermark (if enabled) + if self.watermark_enabled and self.watermark_path.exists(): + print_step("🎨 Applying watermark...") + watermark_input = ffmpeg.input(str(self.watermark_path))["v"] + background_clip = background_clip.overlay( + watermark_input, + x=0, + y=0, + ) + elif self.watermark_enabled and not self.watermark_path.exists(): + print_substep(f"Warning: Watermark enabled but file not found: {self.watermark_path}", style="yellow") + + # Step 8: Render print_step("🎥 Rendering the video...") self.output_dir.mkdir(parents=True, exist_ok=True) # Normalize filename - filename = self._normalize_filename(self.post.get("title", self.post_id)) + filename = self._normalize_filename(self.post_id) output_path = str(self.output_dir / f"{filename}.mp4") # Prevent path too long if len(output_path) > 251: diff --git a/manual_main.py b/manual_main.py index 4e351e1..74dd68b 100644 --- a/manual_main.py +++ b/manual_main.py @@ -50,7 +50,9 @@ MANUAL_DEFAULTS = { "background_audio_dir": "assets/backgrounds/audio", "background_audio_volume": 0.1, "max_video_length": 120, - "screenshot_width_percent": 85 + "screenshot_width_percent": 85, + "watermark_enabled": True, + "watermark_path": "assets/backgrounds/transparent-bg.png", } # Full default settings.config that TTS engines and shared modules expect.