whisper / app.py
mirari's picture
Update app.py
155ec2a
import gradio as gr
from pytube import YouTube #Para descargar los videos
from pydub import AudioSegment
import pydub #Para trabajar con el audio
import os
import os.path as osp
from mlxtend.file_io import find_files
from mlxtend.utils import Counter
import re #Para la parte de normalizar
import string
import nltk
nltk.download('punkt')
nltk.download('stopwords')
from nltk.tokenize import word_tokenize
from autocorrect import Speller #Para los errores ortográficos
spell = Speller(lang='es')
from jiwer import wer #Para la métrica
# Definimos las funciones necesarias
def cargarAudio(video, i):
video.streams.filter(only_audio=True)
audio = video.streams.get_by_itag(22)
mp4 = audio.download()
a = mp4.split('/')
titulo = a[-1]
os.rename(titulo, 'video_'+str(i)+'.mp4')
cont = 'video_'+str(i)
return cont
def transcribir(cont, model, device):
audio_outdir = "./extracted_audio"
subtitle_outdir = "./generated_subtitles"
video = cont + '.mp4'
base, ext = osp.splitext(video)
aac_file_out = osp.join(audio_outdir, osp.basename(base)) + ".aac"
os.system(f"ffmpeg -i {video} -vn -acodec copy {aac_file_out} ")
os.system(f"whisper {aac_file_out} --model {model} --language Spanish --output_dir {subtitle_outdir} --verbose False ")
f = open('./generated_subtitles/' + str(cont) + '.aac.txt','r')
trans = f.read()
transcripcion = (trans.split('\n'))[0]
return transcripcion
def numero_to_letras(numero):
indicador = [("",""),("mil","mil"),("millon","millones"),("mil","mil"),("billon","billones")]
entero = int(numero)
decimal = int(round((numero - entero)*100))
#print 'decimal : ',decimal
contador = 0
numero_letras = ""
while entero >0:
a = entero % 1000
if contador == 0:
en_letras = convierte_cifra(a,1).strip()
else :
en_letras = convierte_cifra(a,0).strip()
if a==0:
numero_letras = en_letras+" "+numero_letras
elif a==1:
if contador in (1,3):
numero_letras = indicador[contador][0]+" "+numero_letras
else:
numero_letras = en_letras+" "+indicador[contador][0]+" "+numero_letras
else:
numero_letras = en_letras+" "+indicador[contador][1]+" "+numero_letras
numero_letras = numero_letras.strip()
contador = contador + 1
entero = int(entero / 1000)
if decimal == 0:
numero_letras = numero_letras
else:
numero_letras = numero_letras+" con " + str(decimal) +"/100"
#print('numero: ',numero)
#print(numero_letras)
return numero_letras
def convierte_cifra(numero,sw):
lista_centana = ["",("cien","ciento"),"doscientos","trescientos","cuatrocientos","quinientos","seiscientos","setecientos","ochocientos","novecientos"]
lista_decena = ["",("diez","once","doce","trece","catorce","quince","dieciseis","diecisiete","dieciocho","diecinueve"),
("veinte","veinti"),("treinta","treinta y "),("cuarenta" , "cuarenta y "),
("cincuenta" , "cincuenta y "),("sesenta" , "sesenta y "),
("setenta" , "setenta y "),("ochenta" , "ochenta y "),
("noventa" , "noventa y ")
]
lista_unidad = ["",("un" , "uno"),"dos","tres","cuatro","cinco","seis","siete","ocho","nueve"]
centena = int (numero / 100)
decena = int((numero -(centena * 100))/10)
unidad = int(numero - (centena * 100 + decena * 10))
#print "centena: ",centena, "decena: ",decena,'unidad: ',unidad
texto_centena = ""
texto_decena = ""
texto_unidad = ""
#Validad las centenas
texto_centena = lista_centana[centena]
if centena == 1:
if (decena + unidad)!=0:
texto_centena = texto_centena[1]
else :
texto_centena = texto_centena[0]
#Valida las decenas
texto_decena = lista_decena[decena]
if decena == 1 :
texto_decena = texto_decena[unidad]
elif decena > 1 :
if unidad != 0 :
texto_decena = texto_decena[1]
else:
texto_decena = texto_decena[0]
#Validar las unidades
#print "texto_unidad: ",texto_unidad
if decena != 1:
texto_unidad = lista_unidad[unidad]
if unidad == 1:
texto_unidad = texto_unidad[sw]
return "%s %s %s" %(texto_centena,texto_decena,texto_unidad)
def normalizar(texto):
#print(texto)
tokens=word_tokenize(texto) #Separa el texto por palabras
#print(tokens)
texto = [w.lower() for w in tokens] #Pasamos las palabras a minúsculas
#print(texto)
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
for i in range(len(texto)):
if texto[i].isdigit() and (texto[i] not in string.punctuation):
texto[i]=numero_to_letras(int(texto[i]))
tokens2=word_tokenize(texto[i])
for j in range(len(tokens2)-1):
texto.append('a') #me añado esto simplemente para no tener problemas con el rango
for j in range(i+1, len(texto)-3):
texto[len(texto)-j+i]=texto[len(texto)-j+i-len(tokens2)+1]
for j in range(i, i+len(tokens2)-1):
texto[j+len(tokens2)-1] = texto[j]
for j in range(i, i+len(tokens2)):
texto[j]=tokens2[j-i]
tokens=[w.lower() for w in texto] #Pasamos las palabras a minúsculas por si había números
re_punc = re.compile('[%s]' % re.escape(string.punctuation))
stripped = [re_punc.sub('',w) for w in tokens]
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
words = [word for word in stripped if word.isalpha()] #Elimina los signos de puntuación
return words
def ortografia(texto):
for word in texto:
word = spell(word)
return texto
def unir(texto):
texto_norm = ""
for i in range(len(texto)):
texto_norm = texto_norm + ' ' + texto[i]
return texto_norm
# Definimos una función que se encarga de llevar a cabo las transcripciones
def transcripcion(video):
model = 'medium'
device = 0
cont = cargarVideo(video, model)
texto = transcribir(cont, model, device)
norm = normalizar(texto)
orto = ortografia(norm)
trans = unir(orto)
return trans
# Creamos la interfaz y la lanzamos.
gr.Interface(fn=transcripcion, inputs="video", outputs="text").launch(share=False)