Skip to content

Commit 4818708

Browse files
committed
Update transcribe_wav.py
1 parent b033ae7 commit 4818708

1 file changed

Lines changed: 250 additions & 34 deletions

File tree

scripts/transcribe_wav.py

Lines changed: 250 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,192 @@
99
import threading
1010
import math
1111
from datetime import datetime, timedelta
12+
import argparse
13+
import logging
14+
15+
# Configurazione Logging
16+
logging.basicConfig(
17+
level=logging.INFO,
18+
format='%(asctime)s - %(levelname)s - %(message)s',
19+
datefmt='%Y-%m-%d %H:%M:%S'
20+
)
21+
logger = logging.getLogger(__name__)
22+
23+
# Lista di stringhe da rimuovere dalla trascrizione
24+
WRONG_SUBSTRINGS = [
25+
"Sottotitoli e revisione a cura di QTSS.",
26+
"Sottotitoli e revisione a cura di QTSS",
27+
"www.mooji.org",
28+
"Ondertitels ingediend door de Amara.org gemeenschap",
29+
"Ondertiteld door de Amara.org gemeenschap",
30+
"Ondertiteling door de Amara.org gemeenschap",
31+
"Untertitelung aufgrund der Amara.org-Community",
32+
"Untertitel im Auftrag des ZDF für funk, 2017",
33+
"Untertitel von Stephanie Geiges",
34+
"Untertitel der Amara.org-Community",
35+
"Untertitel im Auftrag des ZDF, 2017",
36+
"Untertitel im Auftrag des ZDF, 2020",
37+
"Untertitel im Auftrag des ZDF, 2018",
38+
"Untertitel im Auftrag des ZDF, 2021",
39+
"Untertitelung im Auftrag des ZDF, 2021",
40+
"Copyright WDR 2021",
41+
"Copyright WDR 2020",
42+
"Copyright WDR 2019",
43+
"SWR 2021",
44+
"SWR 2020",
45+
"Sous-titres réalisés para la communauté d'Amara.org",
46+
"Sous-titres réalisés par la communauté d'Amara.org",
47+
"Sous-titres fait par Sous-titres par Amara.org",
48+
"Sous-titres réalisés par les SousTitres d'Amara.org",
49+
"Sous-titres par Amara.org",
50+
"Sous-titres par la communauté d'Amara.org",
51+
"Sous-titres réalisés pour la communauté d'Amara.org",
52+
"Sous-titres réalisés par la communauté de l'Amara.org",
53+
"Sous-Titres faits par la communauté d'Amara.org",
54+
"Sous-titres par l'Amara.org",
55+
"Sous-titres fait par la communauté d'Amara.org",
56+
"Sous-titrage ST' 501",
57+
"Sous-titrage ST'501",
58+
"Merci d'avoir regardé cette vidéo.",
59+
"Merci d'avoir regardé cette vidéo!",
60+
"Merci d'avoir regardé cette vidéo !",
61+
"Merci d'avoir regardé la vidéo.",
62+
"J'espère que vous avez apprécié la vidéo.",
63+
"Je vous remercie de vous abonner",
64+
"Cliquez-vous sur les sous-titres et abonnez-vous à la chaîne d'Amara.org",
65+
"❤️ par SousTitreur.com",
66+
"Sottotitoli creati dalla comunità Amara.org",
67+
"Sottotitoli di Sottotitoli di Amara.org",
68+
"Sottotitoli e revisione al canale di Amara.org",
69+
"Sottotitoli e revisione a cura di Amara.org",
70+
"Sottotitoli e revisione a cura di QTSS.",
71+
"Sottotitoli e revisione a cura di QTSS",
72+
"Sottotitoli a cura di QTSS",
73+
"Sottotitoli creati dalla comunità Amara.org per te.",
74+
"Subtítulos realizados por la comunidad de Amara.org",
75+
"Subtitulado por la comunidad de Amara.org",
76+
"Subtítulos por la comunidad de Amara.org",
77+
"Subtítulos creados por la comunidad de Amara.org",
78+
"Subtítulos en español de Amara.org",
79+
"Subtítulos hechos por la comunidad de Amara.org",
80+
"Subtitulos por la comunidad de Amara.org",
81+
"— Sous-titrage ST'501 —",
82+
"Más información www.alimmenta.com",
83+
"www.mooji.org",
84+
"Subtítulos realizados por la comunidad de Amara.org",
85+
"Legendas pela comunidade Amara.org",
86+
"Legendas pela comunidade de Amara.org",
87+
"Legendas pela comunidade do Amara.org",
88+
"Legendas pela comunidade das Amara.org",
89+
"Transcrição e Legendas pela comunidade de Amara.org",
90+
"Sottotitoli creati dalla comunità Amara.org",
91+
"Sous-titres réalisés para la communauté d'Amara.org",
92+
"Sous-titres réalisés para la communauté d'Amara.org",
93+
"Napisy stworzone przez społeczność Amara.org",
94+
"Napisy wykonane przez społeczność Amara.org",
95+
"Zdjęcia i napisy stworzone przez społeczność Amara.org",
96+
"napisy stworzone przez społeczność Amara.org",
97+
"Tłumaczenie i napisy stworzone przez społeczność Amara.org",
98+
"Napisy stworzone przez społeczności Amara.org",
99+
"Tłumaczenie stworzone przez społeczność Amara.org",
100+
"Napisy robione przez społeczność Amara.org",
101+
"www.multi-moto.eu",
102+
"Редактор субтитров А.Синецкая Корректор А.Егорова",
103+
"Yorumlarınızıza abone olmayı unutmayın.",
104+
"Sottotitoli creati dalla comunità Amara.org","字幕由Amara.org社区提供",
105+
"小編字幕由Amara.org社區提供",
106+
"[Music]",
107+
"[promo]",
108+
"[Promo]",
109+
"♪",
110+
"(upbeat music)",
111+
"(Instrumental)",
112+
"[BLANK_AUDIO]",
113+
"[ cease fire ]",
114+
"gu.se",
115+
"(majestic music)",
116+
"[Pause]",
117+
"(snow crunching)",
118+
"[Sounds of wind blowing]",
119+
"(gulp)",
120+
"Sottotitoli e Tsub atki",
121+
"[silenzio]",
122+
"[LAUGH]",
123+
"[ Background noise ]",
124+
"[Clapping]",
125+
"[SOUND]",
126+
"[Sound of metal being hammered against the floor] ",
127+
"Subtitles by the Amara.org community",
128+
"Transcripts by the Amara.org community",
129+
"*laughing*",
130+
"(laughs)",
131+
"[laughs]",
132+
"[Laughter]",
133+
"*laughter*",
134+
"(thud)",
135+
"*laughs*",
136+
"*lacht*",
137+
"[BLANK_AUDIO]",
138+
"[Chuckle]",
139+
"*Chuckle*",
140+
"(laughing)",
141+
"Subs by www.zeoranger.co.uk",
142+
"*thud*",
143+
"*sniff*",
144+
"[BLANK_AU",
145+
"[BLANK",
146+
"[Lacht]",
147+
"[Silence]",
148+
"[]",
149+
"(smacking)",
150+
"[Chuckling]",
151+
"(air whooshing)",
152+
"(whooshing)",
153+
"(sighs)",
154+
"(blows kiss)",
155+
"[Musica]",
156+
"[MUSIC PLAYING]",
157+
"[BREATHING HEAVILY]",
158+
"[Whispering]",
159+
"[BEEPING]",
160+
"(scratching)",
161+
"(wind blowing)",
162+
"(swooshing)",
163+
"(chicken clucking)",
164+
"(footsteps crunching)",
165+
"(beeping)",
166+
"(birds chirping)",
167+
"(sniffing)",
168+
"(footsteps)",
169+
"Transcribed by https://otter.ai",
170+
"[SPEAKING ENGLISH]",
171+
"[AUDIO EN BLANCO]",
172+
"[AUDIO_EN_BLANCO]",
173+
"*Crofie*",
174+
"org Subtítulos realizados por la comunidad de Amara.",
175+
"(Sonido de campanita)",
176+
"(Música de suspenso)",
177+
"Translation & subtitling by Quentin Dewaghe Traduction &-titrage par Quentin Dewaghe q.",
178+
"Transcription by ESO;",
179+
"translation by —"
180+
]
181+
182+
def clean_transcription(text):
183+
"""
184+
Rimuove le stringhe indesiderate dalla trascrizione.
185+
"""
186+
if not text:
187+
return ""
188+
189+
cleaned_text = text
190+
for wrong_string in WRONG_SUBSTRINGS:
191+
if wrong_string in cleaned_text:
192+
cleaned_text = cleaned_text.replace(wrong_string, "")
193+
194+
# Rimuove spazi doppi creati dalla rimozione
195+
import re
196+
cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
197+
return cleaned_text
12198

13199
def upgrade_pip_and_install_packages():
14200
"""
@@ -255,7 +441,7 @@ def transcribe_chunk_parallel(chunk_path, model, language='it'):
255441
model: Modello Whisper già caricato
256442
language: Lingua del contenuto
257443
Returns:
258-
str: Testo trascritto del chunk
444+
str: Testo trascritto del chunk (pulito)
259445
"""
260446
try:
261447
print(f" DEBUG: Inizio trascrizione chunk {os.path.basename(chunk_path)}")
@@ -282,7 +468,7 @@ def transcribe_chunk_parallel(chunk_path, model, language='it'):
282468
try:
283469
result = model.transcribe(chunk_path, language=language)
284470
print(f" DEBUG: Trascrizione completata per {os.path.basename(chunk_path)}")
285-
return result['text']
471+
return clean_transcription(result['text'])
286472
except (AttributeError, KeyError) as e:
287473
if "Linear" in str(e) or any(x in str(e) for x in ["KeyError", "transcribe", "decoder", "encoder"]):
288474
print(f" ❌ ERRORE CRITICO: Modello Whisper danneggiato durante la trascrizione")
@@ -602,7 +788,7 @@ def update_progress():
602788
except:
603789
pass
604790

605-
return result['text']
791+
return clean_transcription(result['text'])
606792

607793
def save_transcription(transcription, output_path):
608794
"""
@@ -860,44 +1046,74 @@ def main(podcast_dir, model_name='medium', language='it', parallel=False):
8601046
if processed_files > 0:
8611047
print(f"📈 Tempo medio per file: {total_elapsed/processed_files:.1f} secondi")
8621048

1049+
def parse_arguments():
1050+
"""
1051+
Analizza gli argomenti da riga di comando.
1052+
"""
1053+
parser = argparse.ArgumentParser(description="Trascrizione automatica file audio con Whisper.")
1054+
parser.add_argument("--dir", type=str, help="Directory contenente i file audio")
1055+
parser.add_argument("--model", type=str, default="medium", help="Modello Whisper da utilizzare (tiny, base, small, medium, large)")
1056+
parser.add_argument("--lang", type=str, default="it", help="Lingua dell'audio (es. it, en)")
1057+
parser.add_argument("--parallel", action="store_true", help="Abilita trascrizione parallela")
1058+
parser.add_argument("--no-parallel", action="store_false", dest="parallel", help="Disabilita trascrizione parallela")
1059+
parser.set_defaults(parallel=False)
1060+
1061+
return parser.parse_args()
1062+
8631063
if __name__ == "__main__":
8641064
# Verifica che sia utilizzata una versione compatibile di Python
8651065
ensure_python_version()
8661066

8671067
# Aggiorna pip e installa correttamente whisper e tqdm (solo una volta)
868-
upgrade_pip_and_install_packages()
1068+
try:
1069+
upgrade_pip_and_install_packages()
1070+
except Exception as e:
1071+
print(f"Errore durante l'aggiornamento dei pacchetti: {e}")
1072+
1073+
args = parse_arguments()
8691074

870-
while True:
871-
podcast_dir = input("\nInserisci il percorso della cartella contenente i podcast: ").strip()
872-
873-
if os.path.isdir(podcast_dir):
874-
print(f"\nIniziando l'elaborazione della cartella: {podcast_dir}")
1075+
# Se viene passato un argomento directory, esegui in modalità non interattiva
1076+
if args.dir:
1077+
if os.path.isdir(args.dir):
1078+
print(f"\nIniziando l'elaborazione della cartella: {args.dir}")
1079+
print(f"Modello: {args.model}, Lingua: {args.lang}, Parallelo: {args.parallel}")
1080+
main(args.dir, model_name=args.model, language=args.lang, parallel=args.parallel)
1081+
else:
1082+
print(f"❌ Errore: La directory {args.dir} non esiste.")
1083+
sys.exit(1)
1084+
else:
1085+
# Modalità interattiva
1086+
while True:
1087+
podcast_dir = input("\nInserisci il percorso della cartella contenente i podcast: ").strip()
1088+
1089+
if os.path.isdir(podcast_dir):
1090+
print(f"\nIniziando l'elaborazione della cartella: {podcast_dir}")
1091+
1092+
# Chiedi se utilizzare il processamento parallelo
1093+
while True:
1094+
parallel_choice = input("Vuoi utilizzare il processamento parallelo per velocizzare la trascrizione? (s/n): ").strip().lower()
1095+
if parallel_choice in ['s', 'si', 'yes', 'y']:
1096+
parallel = True
1097+
print("Modalità processamento parallelo attivata")
1098+
break
1099+
elif parallel_choice in ['n', 'no', 'nope']:
1100+
parallel = False
1101+
print("Modalità normale attivata")
1102+
break
1103+
else:
1104+
print("Rispondi 's' per sì o 'n' per no.")
8751105

876-
# Chiedi se utilizzare il processamento parallelo
1106+
main(podcast_dir, model_name='medium', language='it', parallel=parallel)
1107+
else:
1108+
print("Il percorso inserito non è valido. Per favori riprova.")
1109+
continue
1110+
8771111
while True:
878-
parallel_choice = input("Vuoi utilizzare il processamento parallelo per velocizzare la trascrizione? (s/n): ").strip().lower()
879-
if parallel_choice in ['s', 'si', 'yes', 'y']:
880-
parallel = True
881-
print("Modalità processamento parallelo attivata")
882-
break
883-
elif parallel_choice in ['n', 'no', 'nope']:
884-
parallel = False
885-
print("Modalità normale attivata")
1112+
scelta = input("\n🔄 Utilizzare di nuovo lo script con una nuova cartella? (1=sì, 0=no): ").strip()
1113+
if scelta == '1':
8861114
break
1115+
elif scelta == '0':
1116+
print("👋 Arrivederci!")
1117+
sys.exit(0)
8871118
else:
888-
print("Rispondi 's' per sì o 'n' per no.")
889-
890-
main(podcast_dir, model_name='medium', language='it', parallel=parallel)
891-
else:
892-
print("Il percorso inserito non è valido. Per favore riprova.")
893-
continue
894-
895-
while True:
896-
scelta = input("\n🔄 Utilizzare di nuovo lo script con una nuova cartella? (1=sì, 0=no): ").strip()
897-
if scelta == '1':
898-
break
899-
elif scelta == '0':
900-
print("👋 Arrivederci!")
901-
sys.exit(0)
902-
else:
903-
print("❌ Scelta non valida. Inserire 1 o 0.")
1119+
print("❌ Scelta non valida. Inserire 1 o 0.")

0 commit comments

Comments
 (0)