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:
João Henrique
2026-09-08 09:59:31 -04:00
commit b541f502ba
1507 changed files with 387650 additions and 0 deletions
@@ -0,0 +1,66 @@
import json
import mimetypes
import ssl
import uuid
from pathlib import Path
from typing import Any, Callable
from urllib import request
from ...scanner.modelos import SegmentoDeTranscricao
class ProviderDeTranscricaoGroq:
"""Provider Groq compatível com o contrato de transcrição do scanner."""
endpoint = "https://api.groq.com/openai/v1/audio/transcriptions"
def __init__(self, api_key: str, modelo: str = "whisper-large-v3-turbo",
idioma: str = "pt", tempo_limite: float = 120.0,
requisicao: Callable[..., Any] | None = None) -> None:
if not api_key.strip():
raise ValueError("A chave da API Groq é obrigatória.")
self.api_key = api_key.strip()
self.modelo = modelo
self.idioma = idioma
self.tempo_limite = tempo_limite
self._requisicao = requisicao or request.urlopen
try:
import certifi
self._contexto_ssl = ssl.create_default_context(cafile=certifi.where())
except ImportError:
self._contexto_ssl = ssl.create_default_context()
def transcrever(self, clipe: Any) -> list[SegmentoDeTranscricao]:
arquivo = getattr(clipe, "arquivo", None)
if not arquivo:
raise ValueError("O clipe não possui arquivo de origem para transcrição.")
caminho = Path(arquivo)
if not caminho.is_file():
raise FileNotFoundError(f"Arquivo do clipe não encontrado: {caminho}")
corpo, tipo = self._multipart(caminho)
req = request.Request(self.endpoint, data=corpo, method="POST", headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": tipo,
})
argumentos = {"timeout": self.tempo_limite}
if self._requisicao is request.urlopen:
argumentos["context"] = self._contexto_ssl
with self._requisicao(req, **argumentos) as resposta:
dados = json.loads(resposta.read().decode("utf-8"))
return [SegmentoDeTranscricao(float(item["start"]), float(item["end"]),
str(item.get("text", "")).strip(),
None)
for item in dados.get("segments", [])]
def _multipart(self, caminho: Path) -> tuple[bytes, str]:
limite = "----engine-groq-" + uuid.uuid4().hex
mime = mimetypes.guess_type(caminho.name)[0] or "application/octet-stream"
partes: list[bytes] = []
campos = {"model": self.modelo, "language": self.idioma,
"response_format": "verbose_json", "timestamp_granularities[]": "segment"}
for nome, valor in campos.items():
partes.append(f"--{limite}\r\nContent-Disposition: form-data; name=\"{nome}\"\r\n\r\n{valor}\r\n".encode())
partes.append(f"--{limite}\r\nContent-Disposition: form-data; name=\"file\"; filename=\"{caminho.name}\"\r\nContent-Type: {mime}\r\n\r\n".encode())
partes.append(caminho.read_bytes())
partes.append(f"\r\n--{limite}--\r\n".encode())
return b"".join(partes), f"multipart/form-data; boundary={limite}"