Convertendo vídeos para texto com ffmpeg e caca-utils

Yep… você leu certo: caca-utils. Não me pergunte o que caca significa. Só sei que os caras chamam de Colour ASCII Art Library. O detalhe interessante é que alguns players conseguem renderizar vídeos usando essa biblioteca. É o caso do VLC e também do ffmpeg.

Então, dá para criar um vídeo usando ASCII art? Well… dá, mas não é direto. O problema desses codecs é que eles renderizam o vídeo em formato texto e, assim, não tem como incorporar cada “quadro” num container MP4, Matroska, AVI ou o raio que o parta… Infelizmente, temos que renderizar os quadros em formato gráfico para poder convertê-los e incorporá-los nos citados containers. Eis uma maneira de fazer:

  • O primeiro passo é converter o vídeo em quadros individuais e de tamanho bem definido. Isso pode ser feito com o ffmpeg da seguinte maneira:
$ ffmpeg -i video.mp4 -s hd720 -r 30 -f image2 %07d.png

Isso ai vai criar um porrilhão de arquivos PNG nomeados como 0000001.png, 0000002.png … até o último quadro do vídeo. Note que pedi, explicitamente, que o framerate seja de 30 quadros por segundo e que a resolução gráfica seja de 1280×720 (HD).

Aliás… esse é o método favorito de “misturar” vídeos, onde um deles (o sobreposto) tenha um canal Alpha, ou seja, transparência… A maioria dos editores de vídeo suporta essa feature. O OpenShot, por exemplo, usa esse recurso quando criamos um “efeito especial” usando Blender, por exemplo.

  • De posse de todos os quadros, temos que convertê-los para texto. É aqui que entra o caca-utils. Nele, temos um programinha chamado img2txt, que converte uma imagem qualquer (JPG, PNG etc) em texto, seja ASCII puro (sem cores), HTML, SVG ou um formato gráfico chamado TARGA. É esse que usarei, já que isso facilita a reconstrução do vídeo:
$ for i in *.png; do \
    img2txt -f tga -b ordered8 -W 160 "$i" > "${i%.*}.tga"; \
  done

A opção -b ordered8 usa subsampling em blocos de 8×8 para realizar uma emulação de dithering, em modo texto. A opção -W 160 informa ao img2txt que usaremos linhas com 160 caracteres… Você pode usar menos, como 80, que é o padrão para o modo terminal em muitas instalações (especialmente Windows), mas, veremos que usar linhas maiores (ou retângulos maiores) nos dará resoluções “textuais” melhores.

O loop acima converterá todos os PNG para TGA.

O padrão TARGA é muito usado por profissionais porque é um padrão lossless, se nenhuma compressão for usada.

  • Tudo o que temos que fazer agora é juntar todos esses arquivos TGA na mesma velocidade (framerate):
$ ffmpeg -r 30 -f image2 -i %07d.tga -s hd720 \
  -b:v 1200k -minrate 1200k -maxrate 1200k -bufsize 1200k \
  -c:v libx264 -an "out.mp4"

Voilà! Temos um arquivo out.mp4 com o vídeo em “ascii”. Para efeitos de comparação, eis um vídeozinho de 13 segundos (já usei ele por aqui antes) e o vídeo convertido logo abaixo:

E, abaixo, está a comparação da conversão dos PNGs com 80, 160 e 240 caracteres por linha:

Anúncios