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,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>apple-speech-transcriber</string>
<key>CFBundleIdentifier</key>
<string>com.genialsistemas.apple-speech-transcriber</string>
<key>CFBundleName</key>
<string>Apple Speech Transcriber</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>12.0</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>O scanner precisa reconhecer a fala dos clipes da timeline para gerar a transcrição.</string>
</dict>
</plist>
@@ -0,0 +1,3 @@
from .provider_de_transcricao_apple import ProviderDeTranscricaoApple
__all__ = ["ProviderDeTranscricaoApple"]
@@ -0,0 +1,44 @@
import AppKit
import Foundation
import Speech
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
guard CommandLine.arguments.count >= 3 else { finalizar("uso: arquivo locale [somente_no_dispositivo]", 2); return }
let url = URL(fileURLWithPath: CommandLine.arguments[1])
let locale = Locale(identifier: CommandLine.arguments[2])
let somenteNoDispositivo = CommandLine.arguments.count > 3 && CommandLine.arguments[3] == "true"
guard let recognizer = SFSpeechRecognizer(locale: locale), recognizer.isAvailable else {
finalizar("Apple Speech indisponível para o locale solicitado", 3); return
}
SFSpeechRecognizer.requestAuthorization { status in
guard status == .authorized else { self.finalizar("Permissão do Apple Speech não concedida", 4); return }
let request = SFSpeechURLRecognitionRequest(url: url)
request.shouldReportPartialResults = false
if somenteNoDispositivo && recognizer.supportsOnDeviceRecognition { request.requiresOnDeviceRecognition = true }
recognizer.recognitionTask(with: request) { result, error in
if let result = result, result.isFinal {
let segmentos = result.bestTranscription.segments.map {
["inicio": $0.timestamp, "fim": $0.timestamp + $0.duration,
"texto": $0.substring, "confianca": $0.confidence] as [String: Any]
}
let data = try! JSONSerialization.data(withJSONObject: ["segmentos": segmentos])
print(String(data: data, encoding: .utf8)!)
}
if error != nil || result?.isFinal == true { self.finalizar(nil, 0) }
}
}
}
private func finalizar(_ mensagem: String?, _ codigo: Int32) {
if let mensagem { fputs(mensagem + "\n", stderr) }
NSApplication.shared.terminate(nil)
exit(codigo)
}
}
let app = NSApplication.shared
let delegate = AppDelegate()
app.delegate = delegate
app.setActivationPolicy(.accessory)
app.run()
@@ -0,0 +1,28 @@
import json
from pathlib import Path
import subprocess
from typing import Any
from ...scanner.modelos import SegmentoDeTranscricao
class ProviderDeTranscricaoApple:
"""Provider nativo macOS Speech; o áudio não passa por API Groq."""
def __init__(self, executavel: str = "/private/tmp/AppleSpeechTranscriber.app/Contents/MacOS/apple-speech-transcriber", locale: str = "pt-BR",
somente_no_dispositivo: bool = False) -> None:
self.executavel = executavel
self.locale = locale
self.somente_no_dispositivo = somente_no_dispositivo
def transcrever(self, clipe: Any) -> list[SegmentoDeTranscricao]:
arquivo = Path(clipe.arquivo)
if not arquivo.is_file():
raise FileNotFoundError(f"Arquivo de áudio não encontrado: {arquivo}")
resultado = subprocess.run(
[self.executavel, str(arquivo), self.locale, str(self.somente_no_dispositivo).lower()],
check=True, capture_output=True, text=True,
)
dados = json.loads(resultado.stdout)
return [SegmentoDeTranscricao(float(s["inicio"]), float(s["fim"]), str(s["texto"]), s.get("confianca"))
for s in dados.get("segmentos", [])]