feat(ffmpeg_handling): dictonary expansion, change russ search function
generate search function from translation keys dont require perfect match for translation expand vocabulary
This commit is contained in:
1 parent
4b4b0fcb5f
commit
22522549b5
1 file changed
+77
-80
@@ -49,26 +49,41 @@ commands = {
|
|||||||
}
|
}
|
||||||
# ------ Russian Dictonary --------------#
|
# ------ Russian Dictonary --------------#
|
||||||
AUDIO_TRANSLATIONS = {
|
AUDIO_TRANSLATIONS = {
|
||||||
# Additional descriptors
|
# Voice-over / dubbing
|
||||||
"Закадровый": "Voice-over",
|
"Закадровый": "Voice-over",
|
||||||
"Закадровое озвучивание": "Voice-over",
|
"Закадровое озвучивание": "Voice-over",
|
||||||
"Многоголосый закадровый": "Multi-voice voice-over",
|
|
||||||
"Многоголосное закадровое озвучивание": "Multi-voice voice-over",
|
|
||||||
# Variants found in metadata
|
|
||||||
"Оригинален език": "Original language",
|
|
||||||
"Многоголосное озвучивание": "Multi-voice dub",
|
|
||||||
"Многоголосый": "Multi-voice",
|
|
||||||
"Любительский": "Amateur voice-over",
|
|
||||||
"многоголосый": "Multi-voice",
|
|
||||||
"Профессиональный": "Professional",
|
|
||||||
"Одноголосый": "Single voice",
|
|
||||||
"Двухголосый": "Dual voice",
|
|
||||||
"Авторский": "Author voice-over",
|
|
||||||
"закадровый": "Voice-over",
|
"закадровый": "Voice-over",
|
||||||
|
"Многоголосый закадровый": "Voice-over",
|
||||||
|
"Многоголосное закадровое озвучивание": "Voice-over",
|
||||||
|
"Многоголосное озвучивание": "Voice-over",
|
||||||
|
"Многоголосый": "Voice-over",
|
||||||
|
"Одноголосый": "Voice-over",
|
||||||
|
"Двухголосый": "Voice-over",
|
||||||
|
"Авторский": "Voice-over",
|
||||||
|
"Любительский": "Voice-over",
|
||||||
|
"Профессиональный": "Professional",
|
||||||
"Оригинал": "Original",
|
"Оригинал": "Original",
|
||||||
"Дубляж": "Dubbed",
|
"Дубляж": "Dubbed",
|
||||||
# Russian groups
|
# Languages
|
||||||
|
r"русск": "Russian",
|
||||||
|
"Английски": "English",
|
||||||
|
"български": "Bulgarian",
|
||||||
|
"Български": "Bulgarian",
|
||||||
|
"Українська": "Ukrainian",
|
||||||
|
"українська": "Ukrainian",
|
||||||
|
"Македонски": "Macedonian",
|
||||||
|
"Српски": "Serbian",
|
||||||
|
"Немецкая": "German",
|
||||||
|
"Немецкое": "German",
|
||||||
|
"немецкие": "German",
|
||||||
|
"Английская": "English",
|
||||||
|
"Английское": "English",
|
||||||
|
"Французская": "French",
|
||||||
|
"Французское": "French",
|
||||||
|
# Studios / groups
|
||||||
"Кубик в кубе": "Kubik v Kube",
|
"Кубик в кубе": "Kubik v Kube",
|
||||||
|
"Синема УС": "Cinema US",
|
||||||
|
"Озвучка Rumble": "Rumble",
|
||||||
"LostFilm": "LostFilm",
|
"LostFilm": "LostFilm",
|
||||||
"AlexFilm": "AlexFilm",
|
"AlexFilm": "AlexFilm",
|
||||||
"Baibako": "Baibako",
|
"Baibako": "Baibako",
|
||||||
@@ -77,60 +92,42 @@ AUDIO_TRANSLATIONS = {
|
|||||||
"Kerob": "Kerob",
|
"Kerob": "Kerob",
|
||||||
"TVShows": "TVShows",
|
"TVShows": "TVShows",
|
||||||
"HDRezka": "HDRezka",
|
"HDRezka": "HDRezka",
|
||||||
# Groups / studios
|
|
||||||
"Синема УС": "Cinema US",
|
|
||||||
"KinoPub": "KinoPub",
|
"KinoPub": "KinoPub",
|
||||||
"Озвучка Rumble": "Rumble",
|
|
||||||
"Rumble": "Rumble",
|
"Rumble": "Rumble",
|
||||||
# Voice actor
|
"супербит": "Superbit",
|
||||||
|
"Видеосервис": "Videoservice",
|
||||||
|
"Семён Гальцев": "Semyon Galtsev",
|
||||||
|
# Voice actors
|
||||||
"Юрий Сербин": "Yuriy Serbin",
|
"Юрий Сербин": "Yuriy Serbin",
|
||||||
"Ю. Сербин": "Y. Serbin",
|
"Ю. Сербин": "Y. Serbin",
|
||||||
# Languages
|
"П.Либергал": "P. Libergal",
|
||||||
"Английски": "English",
|
"Визгунов": "Vizgunov",
|
||||||
"Русский": "Russian",
|
# Misc
|
||||||
"Русская": "Russian",
|
# Subtitles
|
||||||
"Русское": "Russian",
|
"субтитры": "Russian Subtitles",
|
||||||
# ISO codes
|
"Оригинален език": "Original language",
|
||||||
|
# ISO
|
||||||
"rus": "Russian",
|
"rus": "Russian",
|
||||||
"ru": "Russian",
|
"ru": "Russian",
|
||||||
"ger": "German",
|
|
||||||
"deu": "German",
|
|
||||||
"eng": "English",
|
|
||||||
"und": "Unknown",
|
|
||||||
}
|
}
|
||||||
|
IGNORE_WORDS = {
|
||||||
|
"English",
|
||||||
|
"German",
|
||||||
|
"French",
|
||||||
|
}
|
||||||
|
|
||||||
RUSSIAN_RE = re.compile(
|
RUSSIAN_RE = re.compile(
|
||||||
r"\brus\b|"
|
"|".join(
|
||||||
r"\bru\b|"
|
sorted(
|
||||||
r"russian|"
|
(
|
||||||
r"рус|"
|
re.escape(key)
|
||||||
r"русский|"
|
for key in AUDIO_TRANSLATIONS
|
||||||
r"русская|"
|
if AUDIO_TRANSLATIONS[key] not in IGNORE_WORDS
|
||||||
r"русское|"
|
),
|
||||||
r"дубляж|"
|
key=len,
|
||||||
r"оригинал|"
|
reverse=True,
|
||||||
r"многоголос|"
|
)
|
||||||
r"двухголос|"
|
),
|
||||||
r"одноголос|"
|
|
||||||
r"авторский|"
|
|
||||||
r"любительский|"
|
|
||||||
r"профессиональн|"
|
|
||||||
r"закадров|"
|
|
||||||
r"юрий\s+сербин|"
|
|
||||||
r"ю\.\s*сербин|"
|
|
||||||
r"сербин|"
|
|
||||||
r"синема\s+ус|"
|
|
||||||
r"kinopub|"
|
|
||||||
r"rumble|"
|
|
||||||
r"озвучка\s+rumble|"
|
|
||||||
r"кубик\s+в\s+кубе|"
|
|
||||||
r"lostfilm|"
|
|
||||||
r"alexfilm|"
|
|
||||||
r"baibako|"
|
|
||||||
r"newstudio|"
|
|
||||||
r"jaskier|"
|
|
||||||
r"kerob|"
|
|
||||||
r"tvshows|"
|
|
||||||
r"hdrezka",
|
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -175,18 +172,13 @@ def translate_audio_tracks(tracks: list[dict]) -> list[dict]:
|
|||||||
for key, value in new_track.items():
|
for key, value in new_track.items():
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for src, dst in AUDIO_TRANSLATIONS.items():
|
for src, dst in AUDIO_TRANSLATIONS.items():
|
||||||
value = re.sub(
|
if re.search(rf"\b{re.escape(src)}\b", value, flags=re.IGNORECASE):
|
||||||
rf"\b{re.escape(src)}\b",
|
value = dst
|
||||||
dst,
|
break
|
||||||
value,
|
|
||||||
flags=re.IGNORECASE,
|
|
||||||
)
|
|
||||||
|
|
||||||
if CYRILLIC_RE.search(value):
|
if CYRILLIC_RE.search(value):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Contains unidentified Cyrillic characters in {key}: {value}"
|
f"Track contains unidentified Cyrillic characters in {key}: {value}"
|
||||||
)
|
)
|
||||||
|
|
||||||
new_track[key] = value
|
new_track[key] = value
|
||||||
@@ -520,7 +512,10 @@ def cmd_convert_video(args):
|
|||||||
)
|
)
|
||||||
return True, out
|
return True, out
|
||||||
|
|
||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
|
|
||||||
|
|
||||||
def remove_streams(
|
def remove_streams(
|
||||||
args,
|
args,
|
||||||
remove_indices: set[int] | list[int],
|
remove_indices: set[int] | list[int],
|
||||||
@@ -533,8 +528,7 @@ def remove_streams(
|
|||||||
remaining_audio = [
|
remaining_audio = [
|
||||||
s
|
s
|
||||||
for s in probe["streams"]
|
for s in probe["streams"]
|
||||||
if s["codec_type"] == "audio"
|
if s["codec_type"] == "audio" and s["index"] not in remove_indices
|
||||||
and s["index"] not in remove_indices
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if not remaining_audio:
|
if not remaining_audio:
|
||||||
@@ -618,14 +612,13 @@ def remove_streams(
|
|||||||
logger.error("STDERR:\n%s", e.stderr)
|
logger.error("STDERR:\n%s", e.stderr)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def cmd_remove_subs(args):
|
def cmd_remove_subs(args):
|
||||||
probe = ffmpeg.probe(str(args.input))
|
probe = ffmpeg.probe(str(args.input))
|
||||||
|
|
||||||
if args.num is None:
|
if args.num is None:
|
||||||
remove_indices = {
|
remove_indices = {
|
||||||
s["index"]
|
s["index"] for s in probe["streams"] if s["codec_type"] == "subtitle"
|
||||||
for s in probe["streams"]
|
|
||||||
if s["codec_type"] == "subtitle"
|
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
remove_indices = set(args.num)
|
remove_indices = set(args.num)
|
||||||
@@ -635,10 +628,10 @@ def cmd_remove_subs(args):
|
|||||||
remove_indices=remove_indices,
|
remove_indices=remove_indices,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def cmd_remove_audio_track(args):
|
def cmd_remove_audio_track(args):
|
||||||
remove_indices = {
|
remove_indices = {
|
||||||
select_audio_stream(args.input, audio_index)
|
select_audio_stream(args.input, audio_index) for audio_index in args.audio_index
|
||||||
for audio_index in args.audio_index
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return remove_streams(
|
return remove_streams(
|
||||||
@@ -646,6 +639,8 @@ def cmd_remove_audio_track(args):
|
|||||||
remove_indices=remove_indices,
|
remove_indices=remove_indices,
|
||||||
output_subtitle_codec=True,
|
output_subtitle_codec=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def cmd_extract_audio_track(args):
|
def cmd_extract_audio_track(args):
|
||||||
"""
|
"""
|
||||||
1. Saves that specific audio track as a standalone MP3 (Extra Output).
|
1. Saves that specific audio track as a standalone MP3 (Extra Output).
|
||||||
@@ -929,6 +924,7 @@ def cmd_set_primary_audio(args):
|
|||||||
|
|
||||||
return True, out
|
return True, out
|
||||||
|
|
||||||
|
|
||||||
def cmd_show_metadata(args, show_metadata=False, return_tags=None):
|
def cmd_show_metadata(args, show_metadata=False, return_tags=None):
|
||||||
probe = ffmpeg.probe(str(args.input))
|
probe = ffmpeg.probe(str(args.input))
|
||||||
format_tags = probe.get("format", {}).get("tags", {})
|
format_tags = probe.get("format", {}).get("tags", {})
|
||||||
@@ -942,7 +938,6 @@ def cmd_show_metadata(args, show_metadata=False, return_tags=None):
|
|||||||
for k, v in format_tags.items():
|
for k, v in format_tags.items():
|
||||||
logger.info(f"{k}: {v}")
|
logger.info(f"{k}: {v}")
|
||||||
|
|
||||||
|
|
||||||
# logger.info(f"\n=== STREAM METADATA ===")
|
# logger.info(f"\n=== STREAM METADATA ===")
|
||||||
# for i, stream in enumerate(probe.get("streams", [])):
|
# for i, stream in enumerate(probe.get("streams", [])):
|
||||||
# logger.info(f"\n--- Stream {i} ({stream.get('codec_type')}) ---")
|
# logger.info(f"\n--- Stream {i} ({stream.get('codec_type')}) ---")
|
||||||
@@ -1113,8 +1108,8 @@ def cmd_remove_russian_from_db(args):
|
|||||||
try:
|
try:
|
||||||
audio_tracks = translate_audio_tracks(get_audio_tracks(file))
|
audio_tracks = translate_audio_tracks(get_audio_tracks(file))
|
||||||
subtitle_tracks = translate_audio_tracks(get_subtitle_tracks(file))
|
subtitle_tracks = translate_audio_tracks(get_subtitle_tracks(file))
|
||||||
except ValueError as e:
|
except ValueError as error_msg:
|
||||||
logger.warning("%s", e)
|
logger.warning(f"File {file.name} {error_msg}")
|
||||||
return False, "nooutputneeded"
|
return False, "nooutputneeded"
|
||||||
|
|
||||||
logger.trace("Remove Russian from File: %s", file.name)
|
logger.trace("Remove Russian from File: %s", file.name)
|
||||||
@@ -1409,7 +1404,9 @@ def cmd_test(args):
|
|||||||
logger.debug(f"Subtitle tracks: {subtitle_tracks}")
|
logger.debug(f"Subtitle tracks: {subtitle_tracks}")
|
||||||
for subtitle_track in subtitle_tracks:
|
for subtitle_track in subtitle_tracks:
|
||||||
if is_russian_track(subtitle_track):
|
if is_russian_track(subtitle_track):
|
||||||
logger.error(f"Found russian track: {subtitle_track} in file {file_path}")
|
logger.error(
|
||||||
|
f"Found russian track: {subtitle_track} in file {file_path}"
|
||||||
|
)
|
||||||
return return_value and False
|
return return_value and False
|
||||||
|
|
||||||
logger.info(f"{green_tag('PASS')} {file_path}")
|
logger.info(f"{green_tag('PASS')} {file_path}")
|
||||||
|
|||||||
Reference in new issue
Block a user