|
import gradio as gr |
|
|
|
from pytube import YouTube |
|
from pydub import AudioSegment |
|
import pydub |
|
|
|
import os |
|
import os.path as osp |
|
from mlxtend.file_io import find_files |
|
from mlxtend.utils import Counter |
|
|
|
import re |
|
import string |
|
import nltk |
|
nltk.download('punkt') |
|
nltk.download('stopwords') |
|
from nltk.tokenize import word_tokenize |
|
from autocorrect import Speller |
|
spell = Speller(lang='es') |
|
from jiwer import wer |
|
|
|
|
|
|
|
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)) |
|
|
|
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" |
|
|
|
|
|
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)) |
|
|
|
|
|
texto_centena = "" |
|
texto_decena = "" |
|
texto_unidad = "" |
|
|
|
|
|
texto_centena = lista_centana[centena] |
|
if centena == 1: |
|
if (decena + unidad)!=0: |
|
texto_centena = texto_centena[1] |
|
else : |
|
texto_centena = texto_centena[0] |
|
|
|
|
|
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] |
|
|
|
|
|
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): |
|
|
|
tokens=word_tokenize(texto) |
|
|
|
texto = [w.lower() for w in tokens] |
|
|
|
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))] |
|
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') |
|
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] |
|
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))] |
|
words = [word for word in stripped if word.isalpha()] |
|
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 |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
gr.Interface(fn=transcripcion, inputs="video", outputs="text").launch(share=False) |
|
|