npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xnkee/n8n-nodes-ffmpeg

v0.4.2

Published

n8n community node for the ffmpeg-api service — probe, yt-dlp fetch, cookies management, vertical/reel normalization, trim, concat, burned-in subtitles, raw ffmpeg render and media file management, with binary or URL input.

Downloads

91

Readme

@xnkee/n8n-nodes-ffmpeg

n8n community node para o serviço ffmpeg_api — a API HTTP fina na frente do ffmpeg que faz o render que o n8n não consegue fazer sozinho (o Code node roda num runner sandboxed e a imagem n8nio/n8n não traz ffmpeg).

O serviço em si (main.py) mora no repositório da API, buildado no host como ffmpeg-api:1.0. Este repositório é só o node.

Instalação

npm install
npm run build

Para publicar: npm publish (após npm login).

Pré-requisito da API: POST /files

As operações que aceitam binário (File → Upload, Video → Burn Subtitles e qualquer Input vindo de um campo binário) precisam de uma rota de upload no serviço. Ela não existia até a v0.3.0 — o código pronto está em api-snippets/files_upload.py, é só colar no main.py e rebuildar a imagem.

Sem ela, essas operações falham com The upload did not return a file name. Todo o resto do node continua funcionando normalmente.

Credencial — FFmpeg API

| Campo | Padrão | Para quê | |---|---|---| | Base URL | http://ffmpeg_api:8080 | Só resolve dentro da rede Docker do serviço (VagasNet) | | Request Timeout (Ms) | 900000 | Precisa ser ≥ RENDER_TIMEOUT do serviço, senão o n8n desiste antes do ffmpeg terminar | | Media Directory | /data/media | Precisa bater com o MEDIA_DIR do serviço. Só é usado para montar caminho absoluto em filtros que abrem arquivo por conta própria, como o subtitles=. |

O teste da credencial bate em GET /health. Não há autenticação — o serviço não é exposto publicamente de propósito, já que /render executa argumentos ffmpeg arbitrários.

Resources e operations

Video

| Operation | Rota | Notas | |---|---|---| | Burn Subtitles | POST /render | Queima a legenda na imagem. Subtitle Source: Text (cola o SRT direto), Binary Field ou File Name. Estilo (fonte, tamanho, cor, contorno, posição) nas Options. | | Probe | POST /probe | duration_s, width, height, has_audio e o raw do ffprobe. Útil num IF antes de decidir o preset. | | Fetch | POST /fetch | Baixa de sites com extração (YouTube, Instagram, TikTok, X...) via yt-dlp. URL é a página, não o arquivo direto. Mode: Video (padrão, mescla melhor vídeo+áudio em mp4) ou Audio (extrai mp3). Option Format sobrescreve o seletor -f do yt-dlp. | | To Reel | POST /preset/reel | Normaliza para vertical. Mode: blur (padrão), crop, pad. Options: Width 1080, Height 1920, FPS 30, CRF 23, Preset veryfast. | | Trim | POST /preset/trim | Start + Cut Until (End Time / Duration / End of Video). Option Re-Encode (padrão ligado) dá corte exato; desligado é instantâneo mas corta no keyframe. | | Concatenate | POST /preset/concat | Mínimo 2 inputs. Mode padrão pad. Options: Width, Height, FPS. | | Custom Render | POST /render | Arguments entram entre os -i e o output: [0:v] é o primeiro input, [1:v] o segundo. Output Extension define o container. |

File

| Operation | Rota | |---|---| | Get Many | GET /files — tudo que está no volume ffmpeg_media | | Upload | POST /files — manda um campo binário do item, ou texto puro, para o volume. Devolve { file, url, bytes }. | | Download | GET /files/{name} — devolve binário no campo escolhido em Put Output File in Field | | Delete | DELETE /files/{name} — apaga antes da retenção automática de 24h |

Service

| Operation | Rota | Notas | |---|---|---| | Health Check | GET /health | | | Cookies Status | GET /cookies/status | Se há cookies ativos e de onde vieram (writable ou secret) — nunca o conteúdo. | | Update Cookies | PUT /cookies | Cookies File Content é o cookies.txt (formato Netscape) completo, exportado de uma sessão logada. Usado pelo Video → Fetch em sites que exigem login (ex.: bot-check do YouTube). Sem redeploy: repete a operação quando os cookies expirarem. | | Clear Cookies | DELETE /cookies | Remove o cookies.txt gravável. |

Encadeamento sem trafegar bytes

Input / Inputs aceitam URL http(s) (o serviço baixa) ou o file devolvido por uma chamada anterior. É assim que se encadeia trim → reel → concat sem os bytes passarem pelo n8n:

FFmpeg (Trim)    → {{ $json.file }}
FFmpeg (To Reel) → {{ $json.file }}
FFmpeg (Concatenate)

Toda operação de render devolve o mesmo formato:

{
  "file": "out_a1b2c3.mp4",
  "url": "http://ffmpeg_api:8080/files/out_a1b2c3.mp4",
  "bytes": 4821004,
  "elapsed_s": 12.4
}

Para publicar o resultado, o node de destino pode receber a url direto (se estiver na mesma rede) ou usar File → Download para trazer os bytes como binário.

Entrada binária

Quando o arquivo já está como binário dentro do n8n (veio de um HTTP Request, de um Convert to File, do Google Drive...), não há URL para dar ao serviço. Nesses casos o node sobe os bytes para o volume antes de renderizar e passa adiante só o nome.

  • Probe, To Reel, Trim, Burn Subtitles — o campo Input Source alterna entre URL or File Name e Binary Field.
  • Concatenate, Custom Render — as listas continuam sendo de strings, então uma entrada que comece com binary: é lida como campo binário do item: binary:data. Isso permite misturar as duas coisas na mesma lista.
Inputs:
  {{ $json.url }}     ← o serviço baixa
  binary:data         ← o node sobe antes de renderizar

Prefira URL ou nome de arquivo sempre que possível: o upload faz os bytes atravessarem o n8n duas vezes, e é justamente isso que o encadeamento por nome evita.

Legenda queimada

Video → Burn Subtitles monta o filtergraph sozinho, sem precisar escrever -vf subtitles=... na mão:

| Subtitle Source | Quando usar | |---|---| | Text | O SRT está em texto, numa variável ou expressão. Cole ou mapeie direto — o node grava o arquivo no volume. | | Binary Field | O SRT veio como arquivo binário (ex.: um Convert to File antes). | | File Name | A legenda já está no volume, de um File → Upload anterior. |

O subtitles= não é um -i: o filtro abre o arquivo por caminho, então passar o SRT como input não funciona. É por isso que existe o campo Media Directory na credencial — o node monta <Media Directory>/<arquivo> para o filtro.

Dois detalhes que costumam morder:

  • Fonte. Font Name precisa estar instalada no container do serviço. Se não estiver, o libass cai numa fonte padrão sem avisar. Uma imagem enxuta muitas vezes não tem fonte nenhuma além da do fontconfig.
  • Acento. Character Encoding é UTF-8 por padrão. Legenda gerada em Windows às vezes vem em latin1, e o sintoma é acento virando caractere estranho no vídeo.

Cores são informadas em #RRGGBB normal — o node converte para o &HBBGGRR que o ASS usa, que é a razão clássica de "pedi vermelho e saiu azul" quando se escreve o force_style na mão.

Listas dinâmicas (Concatenate / Custom Render)

Inputs e Arguments têm dois modos:

  • List — uma entrada por item, montada na UI.
  • Array or Comma-Separated — um único campo que aceita um array vindo de expressão ({{ $json.clips }}), uma string de array JSON ou uma lista separada por vírgula.

Erros

Erro 422 do serviço traz o stderr do ffmpeg no detail — o node propaga isso na description do erro, que é onde está a causa real quando um filtergraph está errado.

Retenção

Os arquivos são apagados após RETENTION_HOURS (24h por padrão). Não guarde nada definitivo no volume — baixe ou publique dentro da janela.

Licença

MIT