Executando verificação de segurança...
7

đŸŽ„ Como montei um editor de vĂ­deo com FFmpeg (corte e merge)

Fala pessoal, tudo certo?

No post anterior, mostrei como criei o Kronos usando APIs nativas do browser para gravar vídeos. Agora vou contar como implementei o editor de vídeo que permite cortar e juntar trechos usando FFmpeg. É uma feature que muita gente pediu e que transforma o Kronos de um simples gravador em uma ferramenta completa de edição!

texto

O que o editor faz? (E por que ele existe)

Sempre que eu gravava vĂ­deos longos, ficava frustrado por ter que usar outro software para cortar as partes desnecessĂĄrias ou juntar trechos interessantes. EntĂŁo pensei: "Por que nĂŁo integrar isso direto no Kronos?".

O resultado foi um editor com dois modos:

  • Modo simples: Corta um pedaço do vĂ­deo (tipo "tesoura digital")
  • Modo avançado: Permite marcar vĂĄrios trechos e juntĂĄ-los em um Ășnico vĂ­deo

A mĂĄgica acontece no backend com FFmpeg, mas a experiĂȘncia no frontend Ă© o que realmente importa. Bora ver como isso funciona!

O fluxo: Da tela do usuårio até o FFmpeg

Imagine que vocĂȘ estĂĄ editando um vĂ­deo no Kronos. O processo Ă© como uma linha de produção:

👆 Clicar no botĂŁo "Edit video" → đŸ“ș Abrir editor → ✂ Cortar/juntar → đŸ’Ÿ Exportar

No frontend, vocĂȘ interage com uma interface React que coleta suas escolhas (onde cortar, quais trechos juntar). Essas informaçÔes viajam por IPC atĂ© o processo principal do Electron, que coordena tudo com o FFmpeg.

// No VideoEditor.tsx - quando clica em export
const segments = editor.segments.map(s => ({ start: s.start, end: s.end }));

await exporter.exportVideo({
  sourcePath: videoUrl,
  mode: editor.editMode, // 'simple' ou 'advanced'
  segments: segments,
  // ... outros parĂąmetros
});

A experiĂȘncia no frontend: Editando como num jogo

As "pinças" do modo simples

O modo simples Ă© como usar uma tesoura digital. VocĂȘ tem duas "pinças" na timeline que definem onde o corte começa e termina.

// Exemplo do que acontece quando move as pinças
const [trimStart, setTrimStart] = useState(0);
const [trimEnd, setTrimEnd] = useState(videoDuration);

// Quando arrasta a pinça de início
const handleSetTrimStart = (time: number) => {
  setTrimStart(Math.max(0, Math.min(time, trimEnd - 0.1)));
};

Na tela, vocĂȘ vĂȘ:

  • A timeline com o vĂ­deo todo
  • Duas linhas verticais (as pinças) que vocĂȘ arrasta
  • Um preview mostrando exatamente o que serĂĄ cortado
  • O tempo total original vs final em tempo real

O modo avançado: Marcando e juntando trechos

Aqui Ă© onde fica divertido! Imagine que vocĂȘ tem um vĂ­deo de 10 minutos, mas sĂł quer as partes legais: do minuto 2:30 atĂ© 3:45, depois do 7:15 atĂ© 8:00.

// Como funciona internamente
const [segments, setSegments] = useState<{start: number, end: number}[]>([]);
const [tempStart, setTempStart] = useState<number | null>(null);

const markStart = (currentTime: number) => {
  setTempStart(currentTime);
};

const markEnd = (currentTime: number) => {
  if (tempStart !== null && currentTime > tempStart) {
    setSegments([...segments, { start: tempStart, end: currentTime }]);
    setTempStart(null);
  }
};

Na interface:

  1. VocĂȘ clica "Mark start" no tempo desejado
  2. Avança o vídeo até onde quer terminar
  3. Clica "Mark end"
  4. O segmento aparece na lista abaixo
  5. Repete para quantos trechos quiser
  6. Os segmentos sĂŁo concatenados na ordem que vocĂȘ marcou

O feedback visual que faz toda diferença

Nada de adivinhação! VocĂȘ vĂȘ em tempo real:

  • Duração original do vĂ­deo
  • Duração final apĂłs cortes
  • Quantidade de segmentos no modo avançado
  • Preview do que serĂĄ exportado
// Mostrando as informaçÔes para o usuårio
<div className="flex items-center gap-4">
  <div>Original: {formatTime(videoDuration)}</div>
  <div>Final: {formatTime(editor.getTotalDuration())}</div>
  {editor.editMode === 'advanced' && (
    <div>{editor.segments.length} segments</div>
  )}
</div>

O pipeline no backend: Onde o FFmpeg faz a mĂĄgica

Agora vamos para a parte tĂ©cnica! No processo principal do Electron, uso o fluent-ffmpeg para orquestrar tudo. É como dar instruçÔes para um chef de cozinha.

Montando o "prato" com filter_complex

O FFmpeg trabalha com um conceito chamado filter_complex, que Ă© como uma receita de edição. Para cada trecho que vocĂȘ marcou, crio uma sĂ©rie de filtros:

// Exemplo simplificado do que acontece no VideoExportService
private buildAdvancedFilters(segments, hasAudio, speed, volume, setpts) {
  const parts = [];
  
  // Para cada segmento, crio filtros de corte
  segments.forEach((segment, i) => {
    // Corta o vĂ­deo no tempo exato
    parts.push(`[0:v]trim=${segment.start}:${segment.end},setpts=PTS-STARTPTS[v${i}]`);
    
    if (hasAudio) {
      // Corta o ĂĄudio sincronizado e ajusta volume/velocidade
      parts.push(`[0:a]atrim=${segment.start}:${segment.end},asetpts=PTS-STARTPTS,volume=${volume}[a${i}]`);
    }
  });
  
  // Junta todos os trechos
  const concatFilter = segments.map((_, i) => `[v${i}][a${i}]`).join('');
  parts.push(`${concatFilter}concat=n=${segments.length}:v=1:a=1[vout][aout]`);
  
  return { filter: parts.join(';'), maps: ['-map', '[vout]', '-map', '[aout]'] };
}

O comando FFmpeg que Ă© executado

Quando vocĂȘ clica em export, o fluent-ffmpeg gera um comando como este:

FFmpeg start: ffmpeg -i ~/Videos/Daily_16-27-20.mp4 -y -filter_complex [0:v]trim=12.983458:32.145252,setpts=PTS-STARTPTS[v0];[0:a]atrim=12.983458:32.145252,asetpts=PTS-STARTPTS,volume=1.00[a0];[0:v]trim=36.622308:48.978979,setpts=PTS-STARTPTS[v1];[0:a]atrim=36.622308:48.978979,asetpts=PTS-STARTPTS,volume=1.00[a1];[0:v]trim=57.127219:71.9015,setpts=PTS-STARTPTS[v2];[0:a]atrim=57.127219:71.9015,asetpts=PTS-STARTPTS,volume=1.00[a2];[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[vout][aout] -b:v 8000k -f mp4 -c:v libx264 -preset ultrafast -pix_fmt yuv420p -threads 2 -c:a aac -b:a 192k -map [vout] -map [aout] -y ~/Videos/edited-Daily_16-27-20-1755890861977.mp4

Traduzindo em humano:

  • Pega o vĂ­deo original
  • Corta 3 trechos especĂ­ficos (12s-32s, 36s-48s, 57s-71s)
  • Ajusta o ĂĄudio de cada trecho para manter sincronismo
  • Junta tudo em um Ășnico vĂ­deo
  • Define qualidade alta e formato MP4
  • Salva com nome Ășnico

Boas prĂĄticas que salvei minha vida

Re-encode vs Stream Copy: A escolha da velocidade

Quando vocĂȘ edita um vĂ­deo, o FFmpeg precisa "re-encodar" o conteĂșdo. Mas hĂĄ um truque: se vocĂȘ nĂŁo alterar velocidade ou qualidade, pode usar stream copy para manter os dados originais.

// No modo simples, quando não hå mudanças complexas
if (noComplexChanges) {
  cmd.outputOptions(['-c', 'copy']); // Muito mais rĂĄpido!
} else {
  cmd.videoBitrate(8000); // Re-encode necessĂĄrio
}

Sincronismo A/V: O maior desafio

VĂ­deo e ĂĄudio precisam estar perfeitamente sincronizados. O segredo estĂĄ nos filtros setpts e asetpts:

// Para cada segmento cortado
`[0:v]trim=${start}:${end},setpts=PTS-STARTPTS[v0]`    // VĂ­deo
`[0:a]atrim=${start}:${end},asetpts=PTS-STARTPTS[a0]`  // Áudio

Isso reinicia a contagem de tempo de cada trecho, garantindo que ĂĄudio e vĂ­deo comecem do zero quando sĂŁo concatenados.

Presets e compatibilidade: O equilĂ­brio perfeito

Usei ultrafast para o modo avançado (vårios cortes) e veryfast para o simples:

// Para concatenação complexa: velocidade é mais importante
preset: 'ultrafast'

// Para corte simples: melhor qualidade
preset: 'veryfast'

E nunca esqueça do pix_fmt yuv420p para compatibilidade com players:

cmd.outputOptions(['-pix_fmt', 'yuv420p']); // Funciona em qualquer player

O resultado: Edição sem sair do app

O que antes levava 30 minutos em outro software agora leva 2 cliques no Kronos:

  1. Abrir o editor no vĂ­deo desejado
  2. Escolher modo, marcar cortes
  3. Exportar e pronto!

A integração com o sistema de pastas do Kronos significa que o vídeo editado vai para a mesma pasta organizada, mantendo tudo no lugar certo.

E o futuro?

Ainda hĂĄ muito para melhorar:

  • Timeline mais visual com thumbnails
  • Efeitos visuais (transiçÔes, filtros)
  • Edição de mĂșltiplos vĂ­deos
  • Correção automĂĄtica de sincronismo A/V

Mas por hoje, Ă© isso! O editor jĂĄ estĂĄ salvando um monte de tempo na minha rotina de criação de conteĂșdo.

Quer experimentar? Baixe o Kronos em kronosrec.com e teste o editor com seus prĂłprios vĂ­deos. Se curtiu, me conta nos comentĂĄrios o que achou!

Abraços e atĂ© a prĂłxima! 🚀

Carregando publicação patrocinada...
1

Que legal, parabĂ©ns. Uma sugestĂŁo de feature que ajudaria muito os criadores de conteĂșdo, acredito eu – recortar automaticamente os espaços demorados entre as falas, selecionando o trecho onde quer aplicar isso, e determinado o tempo mĂĄximo da pausa.