mirari commited on
Commit
9d665a4
1 Parent(s): e2d1b14

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -0
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastai.vision.all import *
2
+ import gradio as gr
3
+
4
+ from pytube import YouTube #Para descargar los videos
5
+ from pydub import AudioSegment
6
+ import pydub #Para trabajar con el audio
7
+
8
+ import os
9
+ import os.path as osp
10
+ from mlxtend.file_io import find_files
11
+ from mlxtend.utils import Counter
12
+
13
+ import re #Para la parte de normalizar
14
+ import string
15
+ import nltk
16
+ nltk.download('punkt')
17
+ nltk.download('stopwords')
18
+ from nltk.tokenize import word_tokenize
19
+ from autocorrect import Speller #Para los errores ortográficos
20
+ spell = Speller(lang='es')
21
+ from jiwer import wer #Para la métrica
22
+
23
+ # Cargamos el learner
24
+ learn = load_learner('export.pkl')
25
+
26
+ # Definimos las funciones necesarias
27
+
28
+ def cargarAudio(video, i):
29
+ video.streams.filter(only_audio=True)
30
+ audio = video.streams.get_by_itag(22)
31
+ mp4 = audio.download()
32
+ a = mp4.split('/')
33
+ titulo = a[-1]
34
+ os.rename(titulo, 'video_'+str(i)+'.mp4')
35
+ cont = 'video_'+str(i)
36
+ return cont
37
+
38
+ def transcribir(cont, model, device):
39
+ audio_outdir = "./extracted_audio"
40
+ subtitle_outdir = "./generated_subtitles"
41
+ video = cont + '.mp4'
42
+ base, ext = osp.splitext(video)
43
+ aac_file_out = osp.join(audio_outdir, osp.basename(base)) + ".aac"
44
+ os.system(f"ffmpeg -i {video} -vn -acodec copy {aac_file_out} ")
45
+ os.system(f"whisper {aac_file_out} --model {model} --language Spanish --output_dir {subtitle_outdir} --verbose False --device cuda:{device}")
46
+ f = open('./generated_subtitles/' + str(cont) + '.aac.txt','r')
47
+ trans = f.read()
48
+ transcripcion = (trans.split('\n'))[0]
49
+ return transcripcion
50
+
51
+
52
+ def numero_to_letras(numero):
53
+ indicador = [("",""),("mil","mil"),("millon","millones"),("mil","mil"),("billon","billones")]
54
+ entero = int(numero)
55
+ decimal = int(round((numero - entero)*100))
56
+ #print 'decimal : ',decimal
57
+ contador = 0
58
+ numero_letras = ""
59
+ while entero >0:
60
+ a = entero % 1000
61
+ if contador == 0:
62
+ en_letras = convierte_cifra(a,1).strip()
63
+ else :
64
+ en_letras = convierte_cifra(a,0).strip()
65
+ if a==0:
66
+ numero_letras = en_letras+" "+numero_letras
67
+ elif a==1:
68
+ if contador in (1,3):
69
+ numero_letras = indicador[contador][0]+" "+numero_letras
70
+ else:
71
+ numero_letras = en_letras+" "+indicador[contador][0]+" "+numero_letras
72
+ else:
73
+ numero_letras = en_letras+" "+indicador[contador][1]+" "+numero_letras
74
+ numero_letras = numero_letras.strip()
75
+ contador = contador + 1
76
+ entero = int(entero / 1000)
77
+
78
+ if decimal == 0:
79
+ numero_letras = numero_letras
80
+ else:
81
+ numero_letras = numero_letras+" con " + str(decimal) +"/100"
82
+ #print('numero: ',numero)
83
+ #print(numero_letras)
84
+ return numero_letras
85
+
86
+
87
+ def convierte_cifra(numero,sw):
88
+ lista_centana = ["",("cien","ciento"),"doscientos","trescientos","cuatrocientos","quinientos","seiscientos","setecientos","ochocientos","novecientos"]
89
+ lista_decena = ["",("diez","once","doce","trece","catorce","quince","dieciseis","diecisiete","dieciocho","diecinueve"),
90
+ ("veinte","veinti"),("treinta","treinta y "),("cuarenta" , "cuarenta y "),
91
+ ("cincuenta" , "cincuenta y "),("sesenta" , "sesenta y "),
92
+ ("setenta" , "setenta y "),("ochenta" , "ochenta y "),
93
+ ("noventa" , "noventa y ")
94
+ ]
95
+ lista_unidad = ["",("un" , "uno"),"dos","tres","cuatro","cinco","seis","siete","ocho","nueve"]
96
+ centena = int (numero / 100)
97
+ decena = int((numero -(centena * 100))/10)
98
+ unidad = int(numero - (centena * 100 + decena * 10))
99
+ #print "centena: ",centena, "decena: ",decena,'unidad: ',unidad
100
+
101
+ texto_centena = ""
102
+ texto_decena = ""
103
+ texto_unidad = ""
104
+
105
+ #Validad las centenas
106
+ texto_centena = lista_centana[centena]
107
+ if centena == 1:
108
+ if (decena + unidad)!=0:
109
+ texto_centena = texto_centena[1]
110
+ else :
111
+ texto_centena = texto_centena[0]
112
+
113
+ #Valida las decenas
114
+ texto_decena = lista_decena[decena]
115
+ if decena == 1 :
116
+ texto_decena = texto_decena[unidad]
117
+ elif decena > 1 :
118
+ if unidad != 0 :
119
+ texto_decena = texto_decena[1]
120
+ else:
121
+ texto_decena = texto_decena[0]
122
+ #Validar las unidades
123
+ #print "texto_unidad: ",texto_unidad
124
+ if decena != 1:
125
+ texto_unidad = lista_unidad[unidad]
126
+ if unidad == 1:
127
+ texto_unidad = texto_unidad[sw]
128
+ return "%s %s %s" %(texto_centena,texto_decena,texto_unidad)
129
+
130
+ def normalizar(texto):
131
+ #print(texto)
132
+ tokens=word_tokenize(texto) #Separa el texto por palabras
133
+ #print(tokens)
134
+ texto = [w.lower() for w in tokens] #Pasamos las palabras a minúsculas
135
+ #print(texto)
136
+ texto = [texto[i].replace(' apdo.', ' apartado').replace(' art. ',' articulo ').replace(' atte.',' atentamente').replace(' avda.',' avenida').replace(' cap.',' capítulo').replace(' cía.',' compañía').replace(' coord.',' coordinador').replace(' d.',' don').replace(' dña.',' doña').replace(' dcho.',' derecho').replace(' dcha.',' derecha').replace(' depto.',' departamento').replace(' dr.',' doctor').replace(' dra.',' doctora').replace(' etc.',' etcétera').replace(' fdo.',' firmado').replace(' izqdo.',' izquierdo').replace(' izqda.',' izquierda').replace(' max.',' máximo').replace(' min.',' mínimo').replace(' núm.',' número').replace(' pág.',' página').replace(' ej.',' ejemplo').replace(' prov.',' provincia').replace(' sr.',' señor').replace(' sra.',' señora').replace(' srta.',' señorita').replace(' tfno.',' teléfono') for i in range(len(texto))] #quitamos las abreviaciones
137
+ for i in range(len(texto)):
138
+ if texto[i].isdigit() and (texto[i] not in string.punctuation):
139
+ texto[i]=numero_to_letras(int(texto[i]))
140
+ tokens2=word_tokenize(texto[i])
141
+ for j in range(len(tokens2)-1):
142
+ texto.append('a') #me añado esto simplemente para no tener problemas con el rango
143
+ for j in range(i+1, len(texto)-3):
144
+ texto[len(texto)-j+i]=texto[len(texto)-j+i-len(tokens2)+1]
145
+ for j in range(i, i+len(tokens2)-1):
146
+ texto[j+len(tokens2)-1] = texto[j]
147
+ for j in range(i, i+len(tokens2)):
148
+ texto[j]=tokens2[j-i]
149
+ tokens=[w.lower() for w in texto] #Pasamos las palabras a minúsculas por si había números
150
+ re_punc = re.compile('[%s]' % re.escape(string.punctuation))
151
+ stripped = [re_punc.sub('',w) for w in tokens]
152
+ stripped=[stripped[i].replace('¿', '').replace('¡','').replace("'",'') for i in range(len(tokens))] #quita los símbolos de puntuación que string.punctuation no tiene en cuenta
153
+ words = [word for word in stripped if word.isalpha()] #Elimina los signos de puntuación
154
+ return words
155
+
156
+
157
+ def ortografia(texto):
158
+ for word in texto:
159
+ word = spell(word)
160
+ return texto
161
+
162
+ def unir(texto):
163
+ texto_norm = ""
164
+ for i in range(len(texto)):
165
+ texto_norm = texto_norm + ' ' + texto[i]
166
+ return texto_norm
167
+
168
+ # Definimos una función que se encarga de llevar a cabo las transcripciones
169
+
170
+ def transcripcion(video, texto, device, model, i):
171
+ cont = cargarAudio(video, i)
172
+ trans = transcribir(cont, model, device)
173
+
174
+ #Calculamos la métrica con el texto sin normalizar
175
+ metrica = wer(trans, texto)
176
+
177
+ #Normalizamos el texto tanto del modelo como el original
178
+ norm = normalizar(trans)
179
+ texto_norm = normalizar(texto)
180
+
181
+ #Pasamos el corrector ortográfico tanto al texto del modelo como al original
182
+ ort = ortografia(norm)
183
+ texto_ort = ortografia(texto_norm)
184
+
185
+ #Unimos ambos textos
186
+ transcri = unir(ort)
187
+ texto_unido = unir(texto_ort)
188
+
189
+ #Calculamos la métrica con el texto normalizado
190
+ metrica_norm = wer(transcri, texto_unido)
191
+
192
+ return metrica, transcri, metrica_norm
193
+
194
+ # Creamos la interfaz y la lanzamos.
195
+ gr.Interface(fn=predict, inputs="video", outputs="text").launch(share=False)
196
+