*/
Engenhocas alternativas do Tipoalgo (tipoalgo @ gmail . com)
- Copie e cole o texto abaixo no editor do OpenScad para melhor entender o assunto.
a=[]; // Declara "a" como um vetor vazio
//
for (i=[0:9]) { a=a[i]; } //Acusa warning porque sobrescreveu o objeto "a".
//
for (i=[0:9]) { echo ("====>",str(a[i])); } //Lista "a" item a item no Console.
echo ("Todos itens de a =", str(a)); //Lista todos os itens de "a" no Console.
//
a = [ for (i = [0:9]) [i*2,i*2] ];
echo ("Valores duplicados de a =", str(a)); //Lista todos os itens de "a" no Console.
//
//Acusa warning porque torna a sobrescrever o objeto "a", mas atualizou também os valores de "a" na linha 5. Vale o momento de geração da árvore de compilação CSG. Ou seja, o fonte do OpenScad é compilado e não interpretado linha a linha.
//
// Como gerar um vetor via loop for com número n de iterações
//
a = [ for (a = [0 : 1 : 180]) [ 20 * cos(a), 20 * sin(a) ] ];
echo ("Valores de \"a\" reais =", str(a)); //Lista todos os itens de "a" no Console.
//
//Vale sempre o valor da última atribuição.
polygon(a);
/*
Avaliação das informações acima pelo ChatGPT
O código e os comentários que você forneceu são úteis para entender como o OpenSCAD lida com variáveis e atribuições. Aqui estão algumas observações importantes que podem ser extraídas desses exemplos:
1. Sobrescrita de Variáveis: O OpenSCAD permite que você declare variáveis e as sobrescreva. No entanto, é importante notar que sobrescrever uma variável pode causar perda de dados, como ilustrado na primeira iteração do loop onde a é sobrescrito com um valor numérico, resultando em um vetor vazio.
2. Impressão de Variáveis: Você pode usar a função echo para imprimir o valor das variáveis no console. Isso é útil para depuração e visualização dos dados.
3. Compilação vs. Interpretação: Como mencionado nos comentários, o OpenSCAD compila o código em uma árvore de compilação CSG (Computational Solid Geometry) antes de renderizar o modelo. Portanto, a ordem de execução das operações pode não ser estritamente linear como em uma linguagem interpretada.
4. Criação de Vetores: O OpenSCAD permite criar vetores (arrays) de várias maneiras, incluindo a utilização de loops, como no exemplo em que um vetor a é preenchido com valores calculados em um loop.
5. Última Atribuição Prevalece: Quando uma variável é atribuída várias vezes, o valor atribuído por último prevalece. Por exemplo, no último exemplo, a é sobrescrito com um vetor calculado no loop for, e esse valor é usado na criação do polígono.
Esses conceitos são importantes para entender como o OpenSCAD funciona e como você pode manipular variáveis e dados em seus modelos. O OpenSCAD é uma linguagem de modelagem paramétrica e, portanto, é útil compreender como as atribuições e operações afetam o resultado final do modelo. Seu exemplo também demonstra como você pode criar vetores usando loops, o que pode ser útil para gerar geometria de forma programática.
*/
- Este código em python gera as coordenadas dos vértices de um icosaedro truncado (não regular).
- Um icosaedro truncado regular possui 90 arestas, 60 vértices e 32 faces, sendo 12 pentágonos e 20 hexágonos.
import numpy as np
def format_coordinate(value):
rounded_value = round(value, 1)
if rounded_value.is_integer():
return str(int(rounded_value))
else:
return str(rounded_value)
# Definindo os pontos de referência para um icosaedro
phi = (1 + np.sqrt(5)) / 2
icosahedron_vertices = np.array([
[0, 1, phi],
[0, 1, -phi],
[0, -1, phi],
[0, -1, -phi],
[1, phi, 0],
[1, -phi, 0],
[-1, phi, 0],
[-1, -phi, 0],
[phi, 0, 1],
[phi, 0, -1],
[-phi, 0, 1],
[-phi, 0, -1]
])
# Definindo a matriz de truncamento
truncation_matrix = np.array([
[1, 0, 1],
[0, 1, 1],
[-1, 0, 1],
[0, -1, 1],
[1, 1, 0],
[-1, 1, 0],
[1, -1, 0],
[-1, -1, 0],
[1, 0, -1],
[0, 1, -1],
[-1, 0, -1],
[0, -1, -1]
])
# Calculando o centro do icosaedro truncado
center = np.mean(icosahedron_vertices, axis=0)
# Calculando as coordenadas dos vértices dos pentágonos
unique_vertices = []
for i in range(12):
pentagon_vertices = icosahedron_vertices + truncation_matrix[i]
pentagon_vertices_center = np.mean(pentagon_vertices, axis=0)
pentagon_vertices = [
vertex for vertex in pentagon_vertices if
np.count_nonzero(vertex == 0) != 2 and
not (np.all(vertex > 0) and np.all(vertex < 1)) and
not np.all((np.abs(vertex[0]) > 0 and np.abs(vertex[0]) < 1) or
(np.abs(vertex[1]) > 0 and np.abs(vertex[1]) < 1) or
(np.abs(vertex[2]) > 0 and np.abs(vertex[2]) < 1))
]
pentagon_vertices = np.unique(pentagon_vertices, axis=0)
unique_vertices.extend(pentagon_vertices)
# Convertendo para um array numpy para eliminar duplicatas
unique_vertices = np.array(unique_vertices)
# Calculando as distâncias entre os vértices e o centro
distances_to_center = np.linalg.norm(unique_vertices - center, axis=1)
# Encontrando a distância máxima entre os vértices dos pentágonos
max_distance_pentagon = np.max(np.linalg.norm(icosahedron_vertices, axis=1))
# Eliminando os vértices mais próximos do centro do que qualquer vértice dos pentágonos
filtered_vertices = unique_vertices[distances_to_center > max_distance_pentagon]
# Imprimindo as coordenadas dos vértices formatadas com duas vírgulas entre cada valor
for i, vertex in enumerate(filtered_vertices):
formatted_coords = [format_coordinate(coord) for coord in vertex]
formatted_coords_str = ', '.join(formatted_coords)
#print(f"Vértice {i + 1}: [{formatted_coords_str}]")
print(f"translate ([{formatted_coords_str}]) pnt(0.1);")
-Para visualizar a forma aproximada deste sólido geométrico no OpenScad use o código abaixo:
IcosaedroVertices = [
[10, -10, 26], //0
[10, 10, 26], //1
[0, 20, 26], //2
[-10, 10, 26], //3
[-10, -10, 26], //4
[0, -20, 26], //5
[26, -10, -10], //6
[26, -10, 10], //7
[26, 0, 20], //8
[26, 10, -10], //10
[26, 10, 10], //9
[26, 0, -20], //11
[10, -10, -26], //12
[10, 10, -26], //13
[0, 20, -26], //14
[-10, -10, -26], //16
[-10, 10, -26], //15
[0, -20, -26], //17
[-26, -10, -10], //18
[-26, -10, 10], //19
[-26, 0, 20], //20
[-26, 10, -10], //22
[-26, 10, 10], //21
[-26, 0, -20], //23
[-20, -26, 0], //24
[-10, -26, 10], //25
[10, -26, 10], //26
[20, -26, 0], //27
[10, -26, -10], //28
[-10, -26, -10], //29
[20, 26, 0], //30
[10, 26, 10], //31
[-10, 26, 10], //33
[-20, 26, 0], //32
[-10, 26, -10], //34
[10, 26, -10], //35
/*[-20, 16, 10], //36 triângulos internos
[-10, 20, 16], //37
[-16, 10, 20], //38
[20, -16, 10], //39
[10, -20, 16], //40
[16, -10, 20], //41
[20, 16, -10], //42
[10, 20, -16], //43
[16, 10, -20], //44
[20, 16, 10], //45
[10, 20, 16], //46
[16, 10, 20], //47
[-20, -16, 10], //48
[-10, -20, 16], //49
[-16, -10, 20], //50
[20, -16, -10], //51
[10, -20, -16], //52
[16, -10, -20], //53
[-20, -16, -10], //54
[-10, -20, -16], //55
[-16, -10, -20], //56
[-20, 16, -10], //57
[-10, 20, -16], //58
[-16, 10, -20]]; //59 */
];
IcosaedroFaces = [
[0,1,2,3,4,5], // hexágonos centrais
[6,7,8,10,9,11],
[12,13,14,16,15,17],
[18,19,20,22,21,23],
[24,25,26,27,28,29],
[31,32,33,34,35,30],
/* [36,37,38], // triângulos internos
[39,40,41],
[42,43,44],
[45,46,47],
[48,49,50],
[51,52,53],
[54,55,56],
[57,58,59],
[2,37,46],
[5,40,49],
[14,43,58],
[17,52,55],
[24,48,54],
[27,39,51],
[11,44,53],
[23,56,59],
[8,41,47],
[20,50,38],
[30,42,45],
[33,36,57]];*/
[2,31,32], // triângulos externos
[5,25,26],
[8,0,1],
[11,12,13],
[14,34,35],
[17,28,29],
[20,3,4],
[23,15,16],
[24,18,19],
[27,6,7],
[30,9,10],
[33,21,22],
[2,33,20], // hexágonos laterais abertos
[2,30,8],
[5,8,27],
[5,20,24],
[11,14,30],
[11,17,27],
[17,23,24],
[14,23,33],
//[5,26,27,7,20,4],
];
polyhedron( IcosaedroVertices, IcosaedroFaces );
color ("blue") {
translate ([10, -10, 26]) linear_extrude(8) text("0", 5); //0
translate ([10, 10, 26]) linear_extrude(8) text("1", 5); //1
translate ([0, 20, 26]) linear_extrude(8) text("2", 5); //2
translate ([-10, 10, 26]) linear_extrude(8) text("3", 5); //3
translate ([-10, -10, 26]) linear_extrude(8) text("4", 5); //4
translate ([0, -20, 26]) linear_extrude(8) text("5", 5); //5
translate ([26, -10, -10]) linear_extrude(8) text("6", 5); //6
translate ([26, -10, 10]) linear_extrude(8) text("7", 5); //7
translate ([26, 0, 20]) linear_extrude(8) text("8", 5); //8
translate ([26, 10, -10]) linear_extrude(8) text("10", 5); //10
translate ([26, 10, 10]) linear_extrude(8) text("9", 5); //9
translate ([26, 0, -20]) linear_extrude(8) text("11", 5); //11
translate ([10, -10, -26]) linear_extrude(8) text("12", 5); //12
translate ([10, 10, -26]) linear_extrude(8) text("13", 5); //13
translate ([0, 20, -26]) linear_extrude(8) text("14", 5); //14
translate ([-10, -10, -26]) linear_extrude(8) text("16", 5); //16
translate ([-10, 10, -26]) linear_extrude(8) text("15", 5); //15
translate ([0, -20, -26]) linear_extrude(12) text("17", 8); //17
translate ([-26, -10, -10]) linear_extrude(8) text("18", 5); //18
translate ([-26, -10, 10]) linear_extrude(8) text("19", 5); //19
translate ([-26, 0, 20]) linear_extrude(8) text("20", 5); //20
translate ([-26, 10, -10]) linear_extrude(8) text("22", 5); //22
translate ([-26, 10, 10]) linear_extrude(8) text("21", 5); //21
translate ([-26, 0, -20]) linear_extrude(12) text("23", 8); //23
translate ([-20, -26, 0]) linear_extrude(8) text("24", 5); //24
translate ([-10, -26, 10]) linear_extrude(8) text("25", 5); //25
translate ([10, -26, 10]) linear_extrude(8) text("26", 5); //26
translate ([20, -26, 0]) linear_extrude(8) text("27", 5); //27
translate ([10, -26, -10]) linear_extrude(8) text("28", 5); //28
translate ([-10, -26, -10]) linear_extrude(8) text("29", 5); //29
translate ([20, 26, 0]) linear_extrude(8) text("30", 5); //30
translate ([10, 26, 10]) linear_extrude(8) text("31", 5); //31
translate ([-10, 26, 10]) linear_extrude(8) text("32", 5); //32
translate ([-20, 26, 0]) linear_extrude(8) text("33", 5); //33
translate ([-10, 26, -10]) linear_extrude(8) text("34", 5); //34
translate ([10, 26, -10]) linear_extrude(8) text("35", 5); //35
}
- A ideia é usar uma placa de teclado USB como interface alternativa para se criar 3 chaves liga/desliga controladas via computador.
- Segue abaixo um tutorial de produção do programa e o código fonte.
- Passo a passo para implementar e testar o código que permite ligar e desligar os LEDs Caps Lock, Num Lock e Scroll Lock usando um teclado padrão no Linux.
Passo 1: Instalar Dependências
Garanta que as dependências corretas estejam instaladas. O pacote libevdev-dev é necessário para acessar os LEDs via sysfs.
Para instalar o pacote libevdev-dev no Ubuntu, você pode usar o seguinte comando:
bash
sudo apt update sudo apt install libevdev-dev
Passo 2: Criar o Código
Crie um novo arquivo de código-fonte chamado ligadesliga_leds.c e cole o código C fornecido anteriormente no arquivo.
Passo 3: Compilar o Código
Abra um terminal e navegue até o diretório onde você criou o arquivo ligadesliga_leds.c. Em seguida, execute o seguinte comando para compilar o código:
bash
sudo gcc -oligadesliga_ledsligadesliga_leds.c-levdev
Isso compilará o código e gerará um executável chamado ligadesliga_leds.
Passo 4: Executar o Programa
Agora, você pode executar o programa usando o comando sudo para garantir que tenha as permissões necessárias para acessar os LEDs:
bash
sudo ./ligadesliga_leds
Passo 5: Testar o Programa
Após executar o programa, ele exibirá instruções no terminal. Pressione as teclas 'c', 'n' ou 's' para alternar o brilho dos LEDs Caps Lock, Num Lock e Scroll Lock, respectivamente. Pressione 'x' para sair do programa.
Lembre-se de que a capacidade de controlar os LEDs Caps Lock, Num Lock e Scroll Lock depende do seu hardware e do suporte do sistema operacional. Pode haver variações entre sistemas e distribuições Linux.
CÓDIGO FONTE DO PROGRAMA
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#define CAPSLOCK_PATH "/sys/class/leds/input4::capslock/brightness"
#define NUMLOCK_PATH "/sys/class/leds/input4::numlock/brightness"
#define SCROLLLOCK_PATH "/sys/class/leds/input4::scrolllock/brightness"
int main() {
struct termios old_settings, new_settings;
char input;
tcgetattr(STDIN_FILENO, &old_settings);
new_settings = old_settings;
new_settings.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &new_settings);
printf("Pressione 'c' para alternar o LED Caps Lock.\n");
printf("Pressione 'n' para alternar o LED Num Lock.\n");
printf("Pressione 's' para alternar o LED Scroll Lock.\n");
printf("Pressione 'x' para sair.\n");
while (1) {
input = getchar();
if (input == 'x') {
break;
} else if (input == 'c') {
FILE* capslock_file = fopen(CAPSLOCK_PATH, "r+");
if (capslock_file) {
char value;
fscanf(capslock_file, "%c", &value);
fseek(capslock_file, 0, SEEK_SET);
fprintf(capslock_file, "%c", (value == '0') ? '1' : '0');
fclose(capslock_file);
}
} else if (input == 'n') {
FILE* numlock_file = fopen(NUMLOCK_PATH, "r+");
if (numlock_file) {
char value;
fscanf(numlock_file, "%c", &value);
fseek(numlock_file, 0, SEEK_SET);
fprintf(numlock_file, "%c", (value == '0') ? '1' : '0');
fclose(numlock_file);
}
} else if (input == 's') {
FILE* scrolllock_file = fopen(SCROLLLOCK_PATH, "r+");
if (scrolllock_file) {
char value;
fscanf(scrolllock_file, "%c", &value);
fseek(scrolllock_file, 0, SEEK_SET);
fprintf(scrolllock_file, "%c", (value == '0') ? '1' : '0');
fclose(scrolllock_file);
}
}
}
tcsetattr(STDIN_FILENO, TCSANOW, &old_settings);
return 0;
}
- Este programa gera uma sequência que pode ser usada para alimentar as 3 fases de um motor trifásico a partir de uma fonte de corrente contínua.
- Implementa os seguintes controles:
. liga e desliga a marcha;
. sentido de funcionamento;
. frequência; e
. potência (largura de pulso).
const int dirPin = 3; // Pino de entrada para controlar a direção
const int controlPin = 2; // Pino para controlar o estado 000
const int outputPins[] = {5, 6, 9}; // Pinos de saída para a sequência desejada
int currentState = 0;
int currentDirection = 1; // 1 para contar para cima, -1 para contar para baixo
void setup() {
pinMode(dirPin, INPUT);
pinMode(controlPin, INPUT);
for (int i = 0; i < 3; i++) {
pinMode(outputPins[i], OUTPUT);
}
}
void loop() {
int controlState = digitalRead(controlPin);
int direction = digitalRead(dirPin);
int sequence[] = {5, 4, 6, 2, 3, 1}; // Sequência de estados: 101, 100, 110, 010, 011, 001
if (controlState == LOW) {
sequence[0] = 0;
digitalWrite(outputPins[0], LOW);
digitalWrite(outputPins[1], LOW);
digitalWrite(outputPins[2], LOW);
while (digitalRead(controlPin) == LOW) {
// Aguarda o pino de controle ficar alto para continuar
}
}
if (direction == HIGH) {
currentDirection = 1;
} else {
currentDirection = -1;
}
int frequency = map(analogRead(A0), 0, 1023, 0, 300); // Mapeia a leitura analógica para a faixa de frequência
int pulseWidth = map(analogRead(A1), 0, 1023, 0, 255); // Mapeia a leitura analógica para a faixa de largura de pulsos
int delayTime = 1000 / frequency; // Calcula o tempo de atraso com base na frequência
currentState = (currentState + currentDirection + 6) % 6; // Calcula o próximo estado
int currentOutput = sequence[currentState];
digitalWrite(outputPins[0], bitRead(currentOutput, 2));
digitalWrite(outputPins[1], bitRead(currentOutput, 1));
digitalWrite(outputPins[2], bitRead(currentOutput, 0));
delayMicroseconds(pulseWidth); // Mantém o pulso ativo de acordo com a largura de pulsos
digitalWrite(outputPins[0], LOW);
digitalWrite(outputPins[1], LOW);
digitalWrite(outputPins[2], LOW);
delay(delayTime); // Atraso entre os estados
}
- Esta versão fornece legenda melhor sincronizada à fala.
- A qualidade do reconhecimento da fala está ligada à qualidade do modelo de idioma usado.
import os
import subprocess
import vosk
import pysrt
import json
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
from moviepy.editor import VideoFileClip
app = Flask(__name__)
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def segundos_para_subrip_time(segundos):
minutos, segundos = divmod(segundos, 60)
horas, minutos = divmod(minutos, 60)
return pysrt.SubRipTime(hours=int(horas), minutes=int(minutos), seconds=segundos)
def recognize_speech(file_path, language):
if language == "en":
model_path = "vosk-model-small-en-us-0.15"
elif language == "pt":
model_path = "vosk-model-small-pt-0.3" #model_path = "vosk-model-pt-fb-v0.1.1-20220516_2113" #Para melhor reconhecimento da fala.
elif language == "es":
model_path = "vosk-model-small-es-0.42"
else:
raise ValueError("Idioma não suportado.")
if not os.path.isfile(file_path):
raise FileNotFoundError("O arquivo de vídeo não existe.")
sample_rate = 16000
model = vosk.Model(model_path)
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
audio_duration = VideoFileClip(file_path).duration
ffmpeg_command = f"ffmpeg -y -i {file_path} -vn -acodec pcm_s16le -ar {sample_rate} -ac 1 -f wav -"
ffmpeg_process = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
subtitles = []
current_subtitle = None
subtitle_index = 1
while True:
audio_data = ffmpeg_process.stdout.read(sample_rate * 2)
if not audio_data:
break
rec.AcceptWaveform(audio_data)
result = json.loads(rec.Result())
if "result" in result:
words = result["result"]
if not words:
break
start_time = words[0]["start"]
end_time = words[-1]["end"]
transcript = " ".join([word["word"] for word in words])
if current_subtitle:
current_subtitle.text += " " + transcript
current_subtitle.end = segundos_para_subrip_time(end_time)
else:
current_subtitle = pysrt.SubRipItem(
index=subtitle_index, start=segundos_para_subrip_time(start_time), end=segundos_para_subrip_time(end_time), text=transcript
)
subtitle_index += 1
# Se a legenda tiver mais de 9 palavras, finalizamos a legenda
if len(current_subtitle.text.split()) >= 9:
subtitles.append(current_subtitle)
current_subtitle = None
else:
if current_subtitle:
subtitles.append(current_subtitle)
current_subtitle = None
if current_subtitle:
subtitles.append(current_subtitle)
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
return subtitles
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
file = request.files["video_file"]
language = request.form["language_choice"]
if file and file.filename.endswith(".mp4"):
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
file_path = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(file.filename))
file.save(file_path)
try:
subtitles = recognize_speech(file_path, language)
output_file = os.path.splitext(file_path)[0]
if language == "en":
output_file += "_ing.srt"
elif language == "pt":
output_file += "_por.srt"
elif language == "es":
output_file += "_esp.srt"
with open(output_file, "w", encoding="utf-8") as f:
for subtitle in subtitles:
f.write(str(subtitle))
f.write("\n")
message = f"Processo concluído. Legenda gerada em {output_file}"
except Exception as e:
message = f"Erro durante o reconhecimento: {str(e)}"
else:
message = "Selecione um arquivo de vídeo no formato .mp4."
return render_template("index.html", message=message)
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
- A ideia desta versão é gerar o arquivo de legenda no formato .srt a partir de uma interface Web.
- Instale o Flask com o comando:
pip install flask
- Segue o código para criar um aplicativo da web usando Flask:
import os
import subprocess
import vosk
import pysrt
import json
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
from moviepy.editor import VideoFileClip
app = Flask(__name__)
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def recognize_speech(file_path, language, text_widget=None, subtitles=None):
# Configurar o caminho do modelo de idioma Vosk de acordo com a escolha do usuário
if language == "en":
model_path = "vosk-model-small-en-us-0.15"
elif language == "pt":
model_path = "vosk-model-pt-fb-v0.1.1-20220516_2113"
elif language == "es":
model_path = "vosk-model-small-es-0.42"
else:
raise ValueError("Idioma não suportado.")
# Verificar se o arquivo de entrada existe
if not os.path.isfile(file_path):
raise FileNotFoundError("O arquivo de vídeo não existe.")
# Configurar a taxa de amostragem para o modelo Vosk
sample_rate = 16000
# Carregar o modelo de idioma Vosk
model = vosk.Model(model_path)
# Inicializar o reconhecedor de fala Vosk
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
# Obter a duração do áudio para atualização da barra de progresso
audio_duration = VideoFileClip(file_path).duration
# Comando FFmpeg para extrair o áudio e converter para WAV
ffmpeg_command = f"ffmpeg -y -i {file_path} -vn -acodec pcm_s16le -ar {sample_rate} -ac 1 -f wav -"
ffmpeg_process = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
# Realizar o reconhecimento de fala por blocos de áudio
start_time = 0
block_duration = 9 # Definir a duração do bloco em segundos
while start_time < audio_duration:
# Ler o próximo bloco de áudio do processo ffmpeg
audio_data = ffmpeg_process.stdout.read(sample_rate * block_duration)
# Realizar o reconhecimento de fala no bloco atual
rec.AcceptWaveform(audio_data)
# Extrair o texto reconhecido do resultado
result = json.loads(rec.Result())
if "result" in result:
transcript = " ".join([word["word"] for word in result["result"]])
if transcript.strip(): # Verificar se o texto não está vazio
end_time = min(start_time + block_duration, audio_duration)
subtitles.append(pysrt.SubRipItem(index=len(subtitles) + 1, start=pysrt.SubRipTime(seconds=start_time), end=pysrt.SubRipTime(seconds=end_time), text=transcript))
# Atualizar o texto no widget Text (interface do usuário)
if text_widget is not None:
text_widget.insert(tk.END, f"--> {transcript}\n")
text_widget.see(tk.END) # Rolar o texto para mantê-lo visível
text_widget.update() # Atualizar a interface do usuário
# Atualizar o tempo de início para o próximo bloco
start_time += block_duration
# Fechar o processo ffmpeg
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
return subtitles
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
file = request.files["video_file"]
language = request.form["language_choice"]
# Verificar se o arquivo foi enviado corretamente
if file and file.filename.endswith(".mp4"):
# Crie o diretório de uploads se ainda não existir
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
# Salvar o arquivo de vídeo com um nome exclusivo no diretório "uploads"
file_path = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(file.filename))
file.save(file_path)
try:
subtitles = pysrt.SubRipFile()
recognize_speech(file_path, language, text_widget=None, subtitles=subtitles)
output_file = os.path.splitext(file_path)[0]
if language == "en":
output_file += "_ing.srt"
elif language == "pt":
output_file += "_por.srt"
elif language == "es":
output_file += "_esp.srt"
with open(output_file, "w", encoding="utf-8") as f:
for subtitle in subtitles:
f.write(str(subtitle))
f.write("\n")
message = f"Processo concluído. Legenda gerada em {output_file}"
except Exception as e:
message = f"Erro durante o reconhecimento: {str(e)}"
else:
message = "Selecione um arquivo de vídeo no formato .mp4."
return render_template("index.html", message=message)
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
- Crie um diretório chamado "templates" no mesmo diretório onde se encontra o aplicativo web com o código acima (arquivo Python com extensão .py) e crie um arquivo chamado "index.html" dentro desse diretório. O conteúdo do arquivo "index.html" será a interface do aplicativo da web. Você pode escrever o HTML, CSS e JavaScript necessários para criar a interface do usuário de acordo com suas preferências e requisitos.
Exemplo básico do arquivo "index.html":
html
<!DOCTYPE html>
<html>
<head>
<title>Gerador de Legendas</title>
</head>
<body>
<h1>Gerador de Legendas</h1>
<form action="/" method="post" enctype="multipart/form-data">
<label for="video_file">Escolha o arquivo de vídeo:</label>
<input type="file" name="video_file" id="video_file" accept=".mp4"><br>
<label>Selecione o idioma para reconhecimento:</label><br>
<input type="radio" name="language_choice" value="en" checked> Inglês<br>
<input type="radio" name="language_choice" value="pt"> Português<br>
<input type="radio" name="language_choice" value="es"> Espanhol<br>
<input type="submit" value="Iniciar Reconhecimento">
</form>
{% if message %}
<p>{{ message }}</p>
{% endif %}
</body>
</html>
- Este é um exemplo simples que mostra a página com um formulário para enviar o arquivo de vídeo e selecionar o idioma para o reconhecimento. O resultado do reconhecimento será exibido como uma mensagem na mesma página após o processamento. Note que este é apenas um exemplo básico, e você pode estilizar e aprimorar a interface do usuário conforme necessário.
- Depois de criar o arquivo "index.html" e o diretório "templates", execute o script Python para iniciar o servidor da web:
python3 seu_script.py
- Acesse o aplicativo em um navegador web acessando http://127.0.0.1:5000/ e utilize-o para reconhecer o áudio do arquivo de vídeo selecionado e gerar as legendas.
- O arquivo de vídeo carregado e o arquivo de legenda no formato .srt gerado são salvos no diretório "uploads". O código do aplicativo web garante que o arquivo seja salvo com um nome exclusivo para evitar conflitos se várias pessoas usarem o aplicativo simultaneamente.
- Ideia para comprimir com segurança a mola de espingardas de pressão.
- É possível (e até melhor) usar sem o cano raiado.
- Sem esta ferramenta é praticamente impossível recolocar o gatilho na posição, pois neste modelo de espingarda o pino que fixa o batente da mola de pressão serve de eixo para o gatilho.
- Nesta versão foi acrescentada uma interface gráfica ao script;
- A parte de tradução das foi retirada;
- O reconhecimento da fala suporta 3 idiomas: Inglês, Português e Espanhol.
import os
import subprocess
import vosk
import pysrt
import json
import sys
import tkinter as tk
from tkinter import filedialog
import threading
from moviepy.editor import VideoFileClip
def recognize_speech(file_path, language, text_widget, subtitles):
# Configurar o caminho do modelo de idioma Vosk de acordo com a escolha do usuário
if language == "en":
model_path = "vosk-model-small-en-us-0.15"
elif language == "pt":
model_path = "vosk-model-pt-fb-v0.1.1-20220516_2113"
elif language == "es":
model_path = "vosk-model-small-es-0.42"
else:
raise ValueError("Idioma não suportado.")
# Verificar se o arquivo de entrada existe
if not os.path.isfile(file_path):
raise FileNotFoundError("O arquivo de vídeo não existe.")
# Configurar a taxa de amostragem para o modelo Vosk
sample_rate = 16000
# Carregar o modelo de idioma Vosk
model = vosk.Model(model_path)
# Inicializar o reconhecedor de fala Vosk
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
# Obter a duração do áudio para atualização da barra de progresso
audio_duration = VideoFileClip(file_path).duration
# Comando FFmpeg para extrair o áudio e converter para WAV
ffmpeg_command = f"ffmpeg -y -i {file_path} -vn -acodec pcm_s16le -ar {sample_rate} -ac 1 -f wav -"
ffmpeg_process = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
# Realizar o reconhecimento de fala por blocos de áudio
start_time = 0
prev_end_time = 0
while True:
# Ler o próximo bloco de áudio do processo ffmpeg
audio_data = ffmpeg_process.stdout.read(sample_rate * 9)
if len(audio_data) == 0:
break
# Realizar o reconhecimento de fala no bloco atual
rec.AcceptWaveform(audio_data)
# Extrair o texto reconhecido do resultado
result = json.loads(rec.Result())
if "result" in result:
transcript = " ".join([word["word"] for word in result["result"]])
if transcript.strip(): # Verificar se o texto não está vazio
block_duration = result["result"][-1]["end"] - prev_end_time
progress_percentage = (start_time + block_duration) / audio_duration * 100
subtitles.append(pysrt.SubRipItem(index=len(subtitles) + 1, start=pysrt.SubRipTime(seconds=start_time), end=pysrt.SubRipTime(seconds=start_time + block_duration), text=transcript))
# Atualizar o texto no widget Text
text_widget.insert(tk.END, f"--> {transcript}\n")
text_widget.see(tk.END) # Rolar o texto para mantê-lo visível
# Atualizar o tempo de início para o próximo bloco
start_time += block_duration
prev_end_time = result["result"][-1]["end"]
# Fechar o processo ffmpeg
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
return subtitles
class SpeechRecognitionApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("Gerador de Legendas")
self.geometry("500x500")
self.file_path = tk.StringVar()
self.language_choice = tk.StringVar(value="en")
tk.Label(self, text="Escolha o arquivo de vídeo:").pack(pady=10)
tk.Button(self, text="Procurar", command=self.browse_file).pack(pady=5)
tk.Label(self, text="Selecione o idioma para reconhecimento:").pack(pady=10)
tk.Radiobutton(self, text="Inglês", variable=self.language_choice, value="en").pack(anchor=tk.W)
tk.Radiobutton(self, text="Português", variable=self.language_choice, value="pt").pack(anchor=tk.W)
tk.Radiobutton(self, text="Espanhol", variable=self.language_choice, value="es").pack(anchor=tk.W)
self.display_text = tk.Text(self, wrap="word", width=60, height=10)
self.display_text.pack(pady=10)
self.start_recognition_button = tk.Button(self, text="Iniciar Reconhecimento", command=self.start_recognition_process)
self.start_recognition_button.pack(pady=10)
def browse_file(self):
self.file_path.set(filedialog.askopenfilename(filetypes=[("Arquivos de Vídeo", "*.mp4")]))
file_path = self.file_path.get()
self.display_text.delete(1.0, tk.END)
self.display_text.insert(tk.END, f"Arquivo de vídeo: {file_path}")
def start_recognition_process(self):
file_path = self.file_path.get()
language = self.language_choice.get()
if not file_path:
self.display_text.delete(1.0, tk.END)
self.display_text.insert(tk.END, "Selecione um arquivo de vídeo.")
return
if not os.path.isfile(file_path):
self.display_text.delete(1.0, tk.END)
self.display_text.insert(tk.END, "O arquivo de vídeo não existe.")
return
# Limpar o texto reconhecido anterior
self.display_text.delete(1.0, tk.END)
# Desabilitar o botão de início para evitar múltiplas execuções
self.start_recognition_button.config(state=tk.DISABLED)
# Iniciar o processo de reconhecimento em uma thread separada
threading.Thread(target=self.perform_recognition, args=(file_path, language)).start()
def save_subtitles(self, output_file, subtitles):
# Cria um arquivo .srt com as legendas geradas
with open(output_file, "w", encoding="utf-8") as f:
for subtitle in subtitles:
f.write(str(subtitle))
f.write('\n')
self.display_text.delete(1.0, tk.END)
self.display_text.insert(tk.END, f"Processo concluído. Legenda gerada em {output_file}")
def perform_recognition(self, file_path, language):
try:
subtitles = pysrt.SubRipFile()
self.display_text.insert(tk.END, "Iniciando o reconhecimento...\n")
self.update_idletasks()
blocks = recognize_speech(file_path, language, self.display_text, subtitles)
# Obter o caminho do arquivo de saída .srt
output_file = os.path.splitext(file_path)[0]
if language == "en":
output_file += "_ing.srt"
elif language == "pt":
output_file += "_por.srt"
elif language == "es":
output_file += "_esp.srt"
# Salvar as legendas em formato .srt
self.save_subtitles(output_file, subtitles)
except Exception as e:
self.display_text.insert(tk.END, f"Erro durante o reconhecimento: {str(e)}\n")
self.update_idletasks()
finally:
# Habilitar o botão de início após o término do reconhecimento
self.start_recognition_button.config(state=tk.NORMAL)
if __name__ == "__main__":
app = SpeechRecognitionApp()
app.mainloop()
- Nesta versão o arquivo de entrada é recebido como parâmetro do script .py e o arquivo de saída será a legenda traduzida e terá o mesmo nome do arquivo de entrada com a extensão .srt .
import os
import subprocess
import vosk
import pysrt
import json
import sys
if len(sys.argv) != 2:
print("Uso: python3 nome_do_script.py arquivo_de_entrada.mp4")
sys.exit(1)
# Caminho do arquivo de vídeo (arquivo de entrada)
video_file = sys.argv[1]
# Verificar se o arquivo de entrada existe
if not os.path.isfile(video_file):
print("O arquivo de entrada não existe.")
sys.exit(1)
# Caminho do arquivo de saída (legendas em pt-BR)
output_file = os.path.splitext(video_file)[0] + ".srt"
# Comando FFmpeg para extrair o áudio e converter para WAV
ffmpeg_command = f"ffmpeg -y -i {video_file} -vn -acodec pcm_s16le -ar 16000 -ac 1 -f wav -"
ffmpeg_process = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
# Carregar o modelo de idioma Vosk
model_path = "vosk-model-small-en-us-0.15"
model = vosk.Model(model_path)
sample_rate = 16000
# Inicializar o reconhecedor de fala Vosk
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
# Realizar o reconhecimento de fala por blocos de áudio
subtitles = pysrt.SubRipFile()
start_time = 0
prev_end_time = 0
while True:
# Ler o próximo bloco de áudio do processo ffmpeg
audio_data = ffmpeg_process.stdout.read(sample_rate * 2 * 10)
if len(audio_data) == 0:
break
# Realizar o reconhecimento de fala no bloco atual
rec.AcceptWaveform(audio_data)
# Extrair o texto reconhecido do resultado
result = json.loads(rec.Result())
if "result" in result:
transcript = " ".join([word["word"] for word in result["result"]])
if transcript.strip(): # Verificar se o texto não está vazio
#print(f"{start_time:.2f}s - {transcript}")
# Traduzir o texto para o português usando o translate-shell
translation_command = ["trans", "-b", "-no-ansi", "-no-warn", "-no-auto", "-no-bidi", "-s", "en", "-t", "pt-br"]
translation_process = subprocess.Popen(translation_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
translation, _ = translation_process.communicate(input=transcript.strip().encode())
translation = translation.decode().strip()
print(f"{start_time:.2f}s - {translation}")
# Adicionar legenda traduzida ao arquivo de legendas
block_duration = result["result"][-1]["end"] - prev_end_time
start_timestamp = pysrt.SubRipTime(seconds=start_time)
end_timestamp = pysrt.SubRipTime(seconds=start_time + block_duration)
subtitles.append(pysrt.SubRipItem(index=len(subtitles) + 1, start=start_timestamp, end=end_timestamp, text=translation))
# Atualizar o tempo de início para o próximo bloco
start_time += block_duration
prev_end_time = result["result"][-1]["end"]
# Fechar o processo ffmpeg
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
# Salvar legendas em pt-BR
subtitles.save(output_file, encoding="utf-8")
print("Processo concluído. Legenda em pt-BR gerada em", output_file)
- Nesta versão o tamanho do bloco a ser lido não é mais fixo, depende das pausas existente no áudio. Parece ter gerado melhores legendas.
import os
import subprocess
import vosk
import pysrt
import json
# Caminho do arquivo de vídeo
video_file = "movie.mp4"
# Caminho do arquivo de saída (legendas em pt-BR)
output_file = "traducaoptbrblocovariavel.srt"
# Comando FFmpeg para extrair o áudio e converter para WAV
ffmpeg_command = f"ffmpeg -y -i {video_file} -vn -acodec pcm_s16le -ar 16000 -ac 1 -f wav -"
ffmpeg_process = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
# Carregar o modelo de idioma Vosk
model_path = "vosk-model-small-en-us-0.15"
model = vosk.Model(model_path)
sample_rate = 16000
# Inicializar o reconhecedor de fala Vosk
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
# Realizar o reconhecimento de fala por blocos de áudio
subtitles = pysrt.SubRipFile()
start_time = 0
prev_end_time = 0
while True:
# Ler o próximo bloco de áudio do processo ffmpeg
audio_data = ffmpeg_process.stdout.read(sample_rate * 2 * 10)
if len(audio_data) == 0:
break
# Realizar o reconhecimento de fala no bloco atual
rec.AcceptWaveform(audio_data)
# Extrair o texto reconhecido do resultado
result = json.loads(rec.Result())
if "result" in result:
transcript = " ".join([word["word"] for word in result["result"]])
if transcript.strip(): # Verificar se o texto não está vazio
print(f"{start_time:.2f}s - {transcript}")
# Traduzir o texto para o português usando o translate-shell
translation_command = ["trans", "-b", "-no-ansi", "-no-warn", "-no-auto", "-no-bidi", "-s", "en", "-t", "pt-br"]
translation_process = subprocess.Popen(translation_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
translation, _ = translation_process.communicate(input=transcript.strip().encode())
translation = translation.decode().strip()
print(f"{start_time:.2f}s - {translation}")
# Adicionar legenda traduzida ao arquivo de legendas
block_duration = result["result"][-1]["end"] - prev_end_time
start_timestamp = pysrt.SubRipTime(seconds=start_time)
end_timestamp = pysrt.SubRipTime(seconds=start_time + block_duration)
subtitles.append(pysrt.SubRipItem(index=len(subtitles) + 1, start=start_timestamp, end=end_timestamp, text=translation))
# Atualizar o tempo de início para o próximo bloco
start_time += block_duration
prev_end_time = result["result"][-1]["end"]
# Fechar o processo ffmpeg
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
# Salvar legendas em pt-BR
subtitles.save(output_file, encoding="utf-8")
print("Processo concluído. Legenda em pt-BR gerada em", output_file)
- Pequena alteração no código para otimização do tempo de resposta. O comando FFmpeg é executado como um subprocesso PIPE, isto evita o carregamento do código do programa para a memória a cada execução em um bloco de áudio.
import os
import subprocess
import vosk
import pysrt
import json
# Caminho do arquivo de vídeo
video_file = "movie.mp4"
# Caminho do arquivo de saída (legendas em pt-BR)
output_file = "legendatraduzidaveloz.srt"
# Comando FFmpeg para extrair o áudio e converter para WAV
ffmpeg_command = f"ffmpeg -y -i {video_file} -vn -acodec pcm_s16le -ar 16000 -ac 1 -f wav -"
ffmpeg_process = subprocess.Popen(ffmpeg_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
# Carregar o modelo de idioma Vosk
model_path = "vosk-model-small-en-us-0.15"
model = vosk.Model(model_path)
sample_rate = 16000
# Inicializar o reconhecedor de fala Vosk
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
# Configurações do bloco de áudio
block_size = 9 # Duração em segundos de cada bloco de áudio
# Realizar o reconhecimento de fala por blocos de áudio
subtitles = pysrt.SubRipFile()
start_time = 0
while True:
# Ler o próximo bloco de áudio do processo ffmpeg
audio_data = ffmpeg_process.stdout.read(sample_rate * 2 * block_size)
if len(audio_data) == 0:
break
# Realizar o reconhecimento de fala no bloco atual
rec.AcceptWaveform(audio_data)
result = rec.Result()
# Extrair o texto reconhecido do resultado
if result:
transcript = json.loads(result)["text"]
if transcript.strip(): # Verificar se o texto não está vazio
print(f"{start_time:.2f}s - {transcript}")
# Traduzir o texto para o português usando o translate-shell
translation_command = ["trans", "-b", "-no-ansi", "-no-warn", "-no-auto", "-no-bidi", "-s", "en", "-t", "pt-br"]
translation_process = subprocess.Popen(translation_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
translation, _ = translation_process.communicate(input=transcript.strip().encode())
translation = translation.decode().strip()
print(f"{start_time:.2f}s - {translation}")
# Adicionar legenda traduzida ao arquivo de legendas
start_timestamp = pysrt.SubRipTime(seconds=start_time)
end_timestamp = pysrt.SubRipTime(seconds=start_time + block_size)
subtitles.append(pysrt.SubRipItem(index=len(subtitles) + 1, start=start_timestamp, end=end_timestamp, text=translation))
# Atualizar o tempo de início para o próximo bloco
start_time += block_size
# Fechar o processo ffmpeg
ffmpeg_process.stdout.close()
ffmpeg_process.wait()
# Salvar legendas em pt-BR
subtitles.save(output_file, encoding="utf-8")
print("Processo concluído. Legenda em pt-BR gerada em", output_file)
# Script em linguagem Python gerador de legendas em português a partir de vídeos em inglês
import os
import subprocess
import vosk
import pysrt
import json
# Caminho do arquivo de vídeo
video_file = "movie.mp4"
# Caminho do arquivo de saída (legendas em pt-BR)
output_file = "traducaoptbr.srt"
# Comando FFmpeg para extrair o áudio e converter para WAV
ffmpeg_command = f"ffmpeg -y -i {video_file} -vn -acodec pcm_s16le -ar 16000 -ac 1 audio.wav > /dev/null 2>&1"
subprocess.call(ffmpeg_command, shell=True)
# Carregar o modelo de idioma Vosk
model_path = "vosk-model-small-en-us-0.15"
model = vosk.Model(model_path)
sample_rate = 16000
# Inicializar o reconhecedor de fala Vosk
rec = vosk.KaldiRecognizer(model, sample_rate)
rec.SetWords(True)
# Configurações do bloco de áudio
block_size = 10 # Duração em segundos de cada bloco de áudio
# Realizar o reconhecimento de fala por blocos de áudio
subtitles = pysrt.SubRipFile()
total_duration = os.path.getsize("audio.wav") / (sample_rate * 2) # Tamanho do arquivo em bytes / taxa de amostragem / bytes por amostra (2 bytes)
start_time = 0
while start_time < total_duration:
end_time = min(start_time + block_size, total_duration)
# Carregar o bloco de áudio atual
audio_file = "audio.wav"
ffmpeg_command = f"ffmpeg -y -ss {start_time} -i {audio_file} -t {block_size} audio_block.wav > /dev/null 2>&1"
subprocess.call(ffmpeg_command, shell=True)
# Realizar o reconhecimento de fala no bloco atual
with open("audio_block.wav", "rb") as f:
audio_data = f.read()
rec.AcceptWaveform(audio_data)
result = rec.Result()
# Extrair o texto reconhecido do resultado
if result:
result_json = json.loads(result)
transcript = result_json["text"]
if transcript.strip(): # Verificar se o texto não está vazio
print(f"{start_time:}s - {transcript}")
# Traduzir o texto para o português usando o translate-shell
input_file = "transcript.txt"
output_file = "translation.txt"
with open(input_file, "w") as f:
f.write(transcript.strip())
command = f"trans -b -no-ansi -no-warn -no-auto -no-bidi -s en -t pt-br -i {input_file} > {output_file}"
subprocess.call(command, shell=True)
with open(output_file, "r") as f:
translation = f.read().strip()
print(f"{start_time:}s - {translation}")
# Adicionar legenda traduzida ao arquivo de legendas
start_timestamp = pysrt.SubRipTime(seconds=start_time)
end_timestamp = pysrt.SubRipTime(seconds=end_time)
subtitles.append(pysrt.SubRipItem(index=len(subtitles) + 1, start=start_timestamp, end=end_timestamp, text=translation))
# Atualizar o tempo de início para o próximo bloco
start_time = end_time
# Salvar legendas em pt-BR
subtitles.save(output_file, encoding="utf-8")
print("Processo concluído. Legenda em pt-BR gerada em", output_file)
1. Dependências:
ffmpeg: É uma ferramenta de linha de comando para manipulação de arquivos de áudio e vídeo.
vosk: É uma biblioteca de reconhecimento de fala offline.
translate-shell: É uma interface de linha de comando para os serviços de tradução online.
pysrt: É uma biblioteca para criar, modificar e extrair informações de arquivos de legendas em formato SubRip.
json: É um módulo nativo do Python para trabalhar com dados JSON.
os: É um módulo que fornece várias funções relacionadas ao sistema operacional.
subprocess: É um módulo usado para executar comandos do sistema operacional a partir do Python.
2. Instalação das dependências:
ffmpeg: Você pode instalar o ffmpeg seguindo as instruções disponíveis em https://ffmpeg.org/download.html.
vosk: Para instalar a biblioteca vosk, você pode usar o gerenciador de pacotes pip com o seguinte comando: pip install vosk.
pysrt: Para instalar a biblioteca pysrt, você pode usar o pip com o seguinte comando: pip install pysrt.
Certifique-se de que todas as dependências estejam corretamente instaladas.
Certifique-se que os caminhos dos arquivos de entrada e saída estejam definidos corretamente no script.
A biblioteca Vosk pode ser encontrada no GitHub, no seguinte repositório: https://github.com/alphacep/vosk-api
Para usar a biblioteca Vosk, siga estas etapas:
Clone o repositório Vosk-API em seu ambiente:
no bash digite: git clone https://github.com/alphacep/vosk-api.git
Navegue até o diretório vosk-api/python: cd vosk-api/python
Instale as dependências necessárias: pip install -r requirements.txt
Instale a biblioteca Vosk: python setup.py install
Baixe os modelos de idioma do Vosk que estão no repositório Vosk-API ou em https://alphacephei.com/vosk/models
3. Arquivos de entrada e saída:
Arquivo de vídeo: O caminho do arquivo de vídeo deve ser definido na variável video_file.
Arquivo de áudio gerado: O script gera um arquivo chamado "audio.wav" que contém o áudio extraído do arquivo de vídeo. O caminho e o nome deste arquivo são definidos na variável audio_file.
Arquivo de saída: O script gera também um arquivo cujo nome é definido na variável output_file. Este arquivo contém as legendas traduzidas do inglês para o português (pt-BR).
4. Funcionamento do script:
O script usa o ffmpeg para extrair o áudio do arquivo de vídeo movie.mp4 e convertê-lo para o formato WAV. O FFmpeg é executado com o seguinte comando: ffmpeg -y -i {video_file} -vn -acodec pcm_s16le -ar 16000 -ac 1 {audio_file} > /dev/null 2>&1.
Em seguida, o script carrega o modelo de idioma do Vosk para realizar o reconhecimento de fala no áudio.
O módulo os é usado para obter informações sobre o arquivo de áudio gerado audio.wav, como o tamanho do arquivo em bytes.
O reconhecimento de fala é feito em blocos de áudio definidos pela variável block_size.
Cada bloco de áudio é processado e o texto reconhecido é traduzido para o português usando o translate-shell.
A tradução utiliza o serviço do Google Translate através do Translate-Shell.
As legendas traduzidas são adicionadas a um arquivo de legendas em formato SubRip (.srt) usando a biblioteca pysrt.
Por fim, o arquivo de legendas traducaoptbr.srt é salvo no caminho definido pela variável output_file.