criado repositório jhonny-editor no Gitea adicionado script admin/deploy.command com commit automático atualizado admin/DEV-NOTES.md com template limpo Resumo: - 48 arquivos alterados - 26 novos - 19 modificados - 3 removidos 22 files changed, 658 insertions(+), 568 deletions(-) Arquivos: - AGENTS.md - admin/DEV-NOTES.md - admin/OpenCut.command - admin/commit.command - admin/deploy.command - admin/update.command - code/cep-plugin/index.html - code/cep-plugin/main.js - code/cep-plugin/styles.css - code/engine/ARQUITETURA.md - code/engine/arquitetura/README.md - code/engine/gerar_relatorio_timeline.py - code/engine/integracoes/apple_speech/apple_speech_transcriber.swift - code/engine/integracoes/apple_speech/provider_de_transcricao_apple.py - code/engine/integracoes/midia/__init__.py - code/engine/integracoes/whisper/provider_de_transcricao_local.py - code/engine/scanner/__init__.py - code/engine/scanner/coordenacao/__init__.py - code/engine/scanner/descoberta/__init__.py - code/engine/scanner/modelos.py - code/engine/scanner/transcricao_da_timeline.py - code/src/tools/discovery.ts - :memory:.ses - admin/Jhonny.command - admin/inativos/OpenCut.command - admin/inativos/update.command - code/docs/glossario-analise-emocional.md - code/docs/levantamento-apple-vision-e-apple-intelligence.md - code/docs/levantamento-ferramentas-analise-visual-local.md - code/engine/arquitetura/biblioteca-inteligente-de-videos.md - code/engine/executar_scanner.py - code/engine/integracoes/huggingface/ - code/engine/integracoes/midia/extracao_de_metadados.py - code/engine/integracoes/visual/ - code/engine/requirements-visual.txt - code/engine/scanner/configuracao_visual.py - code/engine/scanner/descoberta/descoberta_de_arquivos.py - code/engine/scanner/metadados.py - code/engine/scanner/relatorio_visual.py - code/engine/scanner/retakes/ - code/engine/scanner/visual.py - code/engine/testes/test_analise_visual_local.py - code/engine/testes/test_arquivos_e_metadados.py - code/engine/testes/test_provider_de_transcricao_apple.py - code/relatorios/analise-brools/ - code/relatorios/analise-visual/ - code/relatorios/audio/arquivos/ - code/relatorios/transcricao-timeline.md
56 lines
3.6 KiB
Python
56 lines
3.6 KiB
Python
import json
|
||
from pathlib import Path
|
||
from engine.integracoes.midia import ExtracaoDeAudio
|
||
from engine.integracoes.whisper import ProviderDeTranscricaoLocal
|
||
from engine.integracoes.huggingface import (ProviderDeDiarizacaoHuggingFace,
|
||
ProviderDeEmocaoHuggingFace)
|
||
from engine.integracoes.premiere.cliente_mcp import ClienteMCPPorStdio
|
||
from engine.integracoes.premiere.conversores import ConversorDeTimeline
|
||
from engine.scanner.transcricao_da_timeline import TranscricaoDaTimeline
|
||
|
||
ARQUIVO = Path('/Volumes/Merongo/PROJETOS/03 - Mastopexia/0E6A8290.MP4')
|
||
CHAVE = json.loads((Path.home()/'.premiere-mcp/config.json').read_text()).get('groqApiKey','')
|
||
SAIDA = Path('/Volumes/Merongo/SISTEMAS/GENIAL SISTEMAS/Jhonny/code/relatorios')
|
||
|
||
cliente = ClienteMCPPorStdio(['node', str(Path(__file__).resolve().parents[1] / 'dist/index.js')])
|
||
cliente.conectar()
|
||
bruta = cliente.chamar('get_active_sequence', {})['structuredContent']['data']
|
||
timeline = ConversorDeTimeline().converter(bruta)
|
||
for faixa in timeline.faixas:
|
||
for clipe in faixa.clipes:
|
||
if clipe.nome == '0E6A8290.MP4': clipe.arquivo = str(ARQUIVO)
|
||
|
||
MODELO = Path('/Volumes/Merongo/SISTEMAS/MODELOSIA/hf-cache/hub/models--mobiuslabsgmbh--faster-whisper-large-v3-turbo/snapshots/0a363e9161cbc7ed1431c9597a8ceaf0c4f78fcf')
|
||
provider = ProviderDeTranscricaoLocal(str(MODELO), idioma='pt')
|
||
MODELO_EMOCAO = Path('/Volumes/Merongo/SISTEMAS/MODELOSIA/models/wav2vec2-xls-r-300m-pt-br-spontaneous-speech-emotion-recognition')
|
||
analisador_de_emocao = ProviderDeEmocaoHuggingFace(str(MODELO_EMOCAO))
|
||
MODELO_DIARIZACAO = Path('/Volumes/Merongo/SISTEMAS/MODELOSIA/models/pyannote-speaker-diarization-community-1')
|
||
diarizador = ProviderDeDiarizacaoHuggingFace(str(MODELO_DIARIZACAO))
|
||
transcricoes = TranscricaoDaTimeline(provider, ExtracaoDeAudio(duracao_da_parte=600), SAIDA/'audio', analisador_de_emocao, diarizador).executar(timeline)
|
||
|
||
linhas = [f'# Relatório de transcrição — {timeline.nome}', '', f'Duração: {bruta["end"]:.3f} s',
|
||
f'Clipes processados: {sum(len(f.clipes) for f in timeline.faixas if f.tipo == "video")}', '']
|
||
for faixa in timeline.faixas:
|
||
if faixa.tipo != 'video': continue
|
||
for clipe in faixa.clipes:
|
||
if clipe.nome != '0E6A8290.MP4': continue
|
||
resultado = next((r for r in transcricoes if r.identificador_do_clipe == clipe.identificador), None)
|
||
intervalo = clipe.intervalo_na_origem
|
||
texto = resultado.texto if resultado else ''
|
||
linhas += [f'## {clipe.identificador} — {clipe.intervalo_na_timeline.inicio:.3f}s–{clipe.intervalo_na_timeline.fim:.3f}s',
|
||
f'Origem: {intervalo.inicio:.3f}s–{intervalo.fim:.3f}s', '', texto or '_Sem fala detectada._', '']
|
||
if resultado and resultado.segmentos:
|
||
linhas.append('Emoções detectadas por segmento:')
|
||
for segmento in resultado.segmentos:
|
||
if segmento.emocao:
|
||
voz = f', voz {segmento.voz_aparente}' if segmento.voz_aparente else ''
|
||
linhas.append(f'- [{segmento.inicio:.3f}s–{segmento.fim:.3f}s] {segmento.falante or "falante_indefinido"}: {segmento.emocao} ({segmento.confianca_emocao:.2f}{voz})')
|
||
linhas.append('')
|
||
for segmento in resultado.segmentos if resultado else []:
|
||
for palavra in segmento.palavras:
|
||
linhas.append(f'- [{palavra.inicio:.3f}s–{palavra.fim:.3f}s] {palavra.texto}')
|
||
if resultado and resultado.segmentos:
|
||
linhas.append('')
|
||
(SAIDA/'transcricao-timeline.md').write_text('\n'.join(linhas), encoding='utf-8')
|
||
print(SAIDA/'transcricao-timeline.md')
|