feat: initial commit - Jhonny Editor
- Adicionado estrutura completa do projeto - Configurado MCP server para Premiere Pro - Adicionado documentação e skills - Configurado Gitignore para o projeto
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ParteDeAudio:
|
||||
caminho: Path
|
||||
inicio: float
|
||||
fim: float
|
||||
|
||||
|
||||
class ExtracaoDeAudio:
|
||||
"""Prepara mídia local para providers de transcrição."""
|
||||
|
||||
def __init__(self, ffmpeg: str = "ffmpeg", ffprobe: str = "ffprobe",
|
||||
duracao_da_parte: float = 600.0) -> None:
|
||||
self.ffmpeg = ffmpeg
|
||||
self.ffprobe = ffprobe
|
||||
self.duracao_da_parte = duracao_da_parte
|
||||
|
||||
def duracao(self, arquivo: str | Path) -> float:
|
||||
caminho = self._validar(arquivo)
|
||||
resultado = subprocess.run(
|
||||
[self.ffprobe, "-v", "error", "-show_entries", "format=duration",
|
||||
"-of", "default=noprint_wrappers=1:nokey=1", str(caminho)],
|
||||
check=True, capture_output=True, text=True,
|
||||
)
|
||||
return float(resultado.stdout.strip())
|
||||
|
||||
def extrair(self, arquivo: str | Path, destino: str | Path) -> list[ParteDeAudio]:
|
||||
return self.extrair_intervalo(arquivo, destino, 0.0, None)
|
||||
|
||||
def extrair_intervalo(self, arquivo: str | Path, destino: str | Path,
|
||||
inicio: float = 0.0, fim: float | None = None) -> list[ParteDeAudio]:
|
||||
origem = self._validar(arquivo)
|
||||
pasta = Path(destino)
|
||||
pasta.mkdir(parents=True, exist_ok=True)
|
||||
duracao_total = self.duracao(origem)
|
||||
inicio = max(0.0, inicio)
|
||||
fim = min(fim if fim is not None else duracao_total, duracao_total)
|
||||
total = fim
|
||||
partes: list[ParteDeAudio] = []
|
||||
inicio = 0.0
|
||||
indice = 0
|
||||
while inicio < total:
|
||||
fim_da_parte = min(inicio + self.duracao_da_parte, total)
|
||||
saida = pasta / f"parte-{indice:04d}.wav"
|
||||
subprocess.run([
|
||||
self.ffmpeg, "-y", "-ss", str(inicio), "-i", str(origem),
|
||||
"-t", str(fim_da_parte - inicio), "-vn", "-ac", "1", "-ar", "16000",
|
||||
"-c:a", "pcm_s16le", str(saida),
|
||||
], check=True, capture_output=True, text=True)
|
||||
partes.append(ParteDeAudio(saida, inicio, fim_da_parte))
|
||||
inicio = fim_da_parte
|
||||
indice += 1
|
||||
return partes
|
||||
|
||||
def _validar(self, arquivo: str | Path) -> Path:
|
||||
caminho = Path(arquivo)
|
||||
if not caminho.is_file():
|
||||
raise FileNotFoundError(f"Arquivo de mídia não encontrado: {caminho}")
|
||||
return caminho
|
||||
Reference in New Issue
Block a user