syncing scripts

This commit is contained in:
2026-01-11 15:10:56 -05:00
parent 362c06dab4
commit 203fc69393
24 changed files with 1982 additions and 172 deletions
+77 -86
View File
@@ -18,59 +18,26 @@ sys.path.append(os.path.join(script_dir, 'ai_transcriber'))
from ai_transcriber.translator import translate_srt
from ai_transcriber.utils import validate_and_repair_srt
import pysubs2
from deep_translator import GoogleTranslator
from datetime import datetime
def re_embed_subtitles(video_path, srt_path, output_path=None):
def translate_fallback_free(source_srt_path, output_srt_path, target_lang="en"):
"""
Re-embeds subtitles into an EXISTING video file, replacing the old tracks.
Similar to embed_subtitles but we output to a temp file then overwrite.
Fallback translation using deep-translator (free Google Translate).
Parses SRT, translates text line-by-line, and saves new SRT.
"""
if not os.path.exists(video_path) or not os.path.exists(srt_path):
print("Error: Video or SRT file not found.")
return False
# ... (rest of translate_fallback_free is same) ...
temp_output = video_path + ".temp.mp4"
print(f"Re-embedding subtitles into: {video_path}...")
# We map 0:v and 0:a from source, but ignore existing subs (0:s?)
# Actually, simpler is to just map 0:v, 0:a and 1:0 (new sub)
# and tell ffmpeg to make the new one default.
# If the old file has subs, they might be kept unless we use -map -0:s (negative mapping)
sub_codec = "mov_text" if video_path.lower().endswith(".mp4") else "srt"
command = [
"ffmpeg",
"-i", video_path,
"-i", srt_path,
"-map", "0:v",
"-map", "0:a",
"-map", "1:0", # The new subtitle
"-c", "copy", # Copy AV
"-c:s", sub_codec, # Encode Sub
"-disposition:s:0", "default",
"-metadata:s:s:0", "language=eng",
"-metadata:s:s:0", "title=English (AI Translated)",
"-y",
"-v", "error",
temp_output
]
try:
subprocess.run(command, check=True)
# Move temp over original
os.replace(temp_output, video_path)
print(f"✅ Fixed: {video_path}")
return True
except subprocess.CalledProcessError as e:
print(f"Error re-embedding: {e}")
if os.path.exists(temp_output):
os.remove(temp_output)
return False
# ... (rest of re_embed_subtitles is same) ...
def process_recovery(folder_path, target_lang="English"):
print(f"Scanning {folder_path} for incomplete translations...")
# Define log file
recovery_log_file = os.path.join(folder_path, "recovery_status.log")
print(f"Logging actions to: {recovery_log_file}")
count_fixed = 0
count_skipped = 0
@@ -79,20 +46,19 @@ def process_recovery(folder_path, target_lang="English"):
for root, dirs, files in os.walk(folder_path):
for file in files:
# We are looking for the SOURCE SRT files primarily
if file.endswith(".srt") and not file.endswith(f".{target_lang}.srt"):
# Exclude our output files to avoid loops
if file.endswith(".srt") and \
not file.endswith(f".{target_lang}.srt") and \
not file.endswith(f".{target_lang}.deep_translate.srt"):
source_srt_path = os.path.join(root, file)
base_name = os.path.splitext(file)[0] # e.g. "movie" or "movie.subbed"
base_name = os.path.splitext(file)[0]
# Check if this is a "subbed" file's srt?
# Usually source srt is "movie.srt".
# Video might be "movie.subbed.mp4" (if original was deleted)
# OR "movie.mp4" (if not deleted)
# Check if Translation exists (Standard or Fallback)
path_gemini = os.path.join(root, f"{base_name}.{target_lang}.srt")
path_deep = os.path.join(root, f"{base_name}.{target_lang}.deep_translate.srt")
# Check if Translation exists
expected_translation = os.path.join(root, f"{base_name}.{target_lang}.srt")
if os.path.exists(expected_translation):
# It's already translated, nothing to do unless we force re-embed
if os.path.exists(path_gemini) or os.path.exists(path_deep):
continue
print(f"\nFound untranslated transcript: {file}")
@@ -103,39 +69,64 @@ def process_recovery(folder_path, target_lang="English"):
new_srt_content = translate_srt(content, target_language=target_lang)
if not new_srt_content:
print("❌ Translation failed (API Limit?). Skipping.")
continue
# Save translation
with open(expected_translation, "w", encoding="utf-8") as f:
f.write(new_srt_content)
validate_and_repair_srt(expected_translation)
# Now, find the video file to update
# Case 1: Original name
video_candidates = [
os.path.join(root, base_name + ".mp4"),
os.path.join(root, base_name + ".mkv"),
# Case 2: .subbed name (if original deleted)
os.path.join(root, base_name + ".subbed.mp4"),
]
found_video = None
for v in video_candidates:
if os.path.exists(v):
found_video = v
break
if found_video:
print(f"Found video to fix: {found_video}")
if re_embed_subtitles(found_video, expected_translation):
count_fixed += 1
success = False
method_used = "None"
final_srt_path = path_gemini # Default if success
if new_srt_content:
# Save Gemini translation
with open(path_gemini, "w", encoding="utf-8") as f:
f.write(new_srt_content)
success = True
method_used = "Gemini"
final_srt_path = path_gemini
else:
print("Warning: Could not find a corresponding video file to embed into.")
print("❌ Gemini API failed. Attempting Free Fallback...")
lang_map = {
"English": "en", "French": "fr", "Spanish": "es",
"German": "de", "Italian": "it", "Portuguese": "pt",
"Russian": "ru", "Japanese": "ja", "Chinese": "zh-CN"
}
target_code = lang_map.get(target_lang, "en")
if translate_fallback_free(source_srt_path, path_deep, target_lang=target_code):
success = True
method_used = "DeepTranslate"
final_srt_path = path_deep
else:
print("❌ All translation methods failed. Skipping.")
continue
if success:
# Log result
with open(recovery_log_file, "a", encoding="utf-8") as log:
log.write(f"{datetime.now().isoformat()} | {method_used} | {file} -> {os.path.basename(final_srt_path)}\n")
validate_and_repair_srt(final_srt_path)
# Now, find the video file to update
# Case 1: Original name
video_candidates = [
os.path.join(root, base_name + ".mp4"),
os.path.join(root, base_name + ".mkv"),
# Case 2: .subbed name (if original deleted)
os.path.join(root, base_name + ".subbed.mp4"),
]
found_video = None
for v in video_candidates:
if os.path.exists(v):
found_video = v
break
if found_video:
print(f"Found video to fix: {found_video}")
if re_embed_subtitles(found_video, final_srt_path):
count_fixed += 1
else:
print("Warning: Could not find a corresponding video file to embed into.")
print(f"\nRecovery Complete. Fixed {count_fixed} files.")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: ./recover_and_fix.py <folder_path> [target_lang]")