Esse é um update to artigo usando python pra capturar a webcam. E com o uso do obamawatched 2021. Eu atualizei recentemente o obamawatcher pra rodar com PySide6 e está aqui funcionando no meu laptop atual de trabalho. No meu pessoal também. Ao menos acho que está funcionando.
O resultado final já está no vídeo acima. Como são várias imagens, os comandos que listei antes já não funcionam muito bem. Eu precisei primeiro redimensionar as imagens pra 640x360 para ficar em widescreen (16:9). As fotos mais antigas saíram em formato quadrado porque era o que a Webcam suportava na época. Então precisei cortar pra ficarem no aspecto correto. E pra isso eu usei python com pillow.
#! /usr/bin/env python3
import os
import re
import argparse
try:
from PIL import Image
except ModuleNotFoundError as e:
raise Exception("missing pillow - run: pip install Pillow") from e
golden_rate = 1280/720
default_size_x = 640
default_size_y = 360
parse = argparse.ArgumentParser(description="Script to resize pictures from a specific directory to the same size")
parse.add_argument("--directory", required=True, help="directory with images jpg")
args = parse.parse_args()
for filename in sorted(os.listdir(args.directory)):
if not re.search("jpg", filename):
continue
with Image.open(args.directory + "/" + filename) as image:
width, height = image.size
rate = float(width)/float(height)
is_golden = rate == golden_rate
is_correted = False
rate_from_default = width / default_size_x
if rate_from_default == 1:
pass
elif rate_from_default > 1:
image = image.resize((default_size_x, int(height/rate_from_default)))
is_correted = True
else:
image = image.resize((default_size_x, int(height/rate_from_default)), Image.Resampling.LANCZOS)
is_correted = True
if not is_golden:
image = image.crop((0, 0, default_size_x, default_size_y))
image.save(filename)
print(f"{filename}: {width}x{height}, golden: {is_golden}, corrected: {is_correted}")
print(f"Golden rate: {golden_rate}")
Tendo as imagens no mesmo formato, basta ordernar e usar ffmpeg pra montar o vídeo.
#! /usr/bin/env bash
die() {
echo "$1" >&2
exit 1
}
counter=0
for img in [0-9]*.jpg
do
serial=$(printf "%06d" $counter)
new_name="G${serial}.JPG"
counter=$(expr $counter + 1)
if [ -f "$new_name" ]; then
echo "$new_name already exists"
continue
fi
echo "$img => $new_name"
mv $img $new_name
done
case $(uname -s) in
Linux)
echo "Merging images into single video file: output.mp4"
ffmpeg -r 8 -i G%06d.JPG -c:v h264 -b:v 5M output.mp4 || \
die "Failed to render output.mp4"
;;
Darwin)
echo "Merging images into single video file: output.mp4"
ffmpeg -hwaccel auto -r 8 -i G%06d.JPG -c:v h264_videotoolbox -b:v 5M output.mp4 || \
die "Failed to render output.mp4"
esac
Eu não testei o código de macOS, então pode ser que não funcione. Meu PC atual, um Lenovo Thinkpad, é processador e GPU Intel. Eu tentei usar -hwaccel vaapi
mas as cores saiam erradas, no estilo negativo de filme. Então deixei rodar no processador mesmo.
E pra comparar o resultado em mpeg comparado com o mesmo em gif:
░▒▓ …/tmp/imagens-webcam/Webcam2 via v3.12.3 (venv) 15:33
❯ gm convert -delay 20 *JPG output.gif
░▒▓ …/tmp/imagens-webcam/Webcam2 via v3.12.3 (venv) 15:38
❯ ls -l output.*
.rw-rw-r-- 209M helio 27 Nov 15:38 output.gif
.rw-rw-r-- 103M helio 27 Nov 13:54 output.mp4
A geração do gif demorou uma eternidade, 5 minutos. O ffmpeg foram só alguns segundos. O tamanho foi o dobro no gif. Pra ver a imagem, teria de carregar tudo e só depois ver o resultando. Como mpeg, vai enviando o vídeo aos poucos.
Eu finalizei o vídeo no kdenlive, fazendo o merge com o vídeo anterior e adicionando a música. Ficou uma nostalgia gostosa.
E com certeza atualizarei daqui alguns anos.
Um projeto engraçado no GitHub que serve pra te detonar baseado nos seus repositórios. Estou rindo, mas é de nervoso. É um tipo de Mauchine Learning.
Oh Helio Loureiro, trying to brew your own beer and code at the same time? I can only imagine the taste of your programming—bitter, flat, and with a hint of regret, just like your idea of collaborating on KDE while you’re still figuring out how to stop your Python scripts from crashing. With a profile that screams “I’m learning” louder than a Linux fanboy at a Windows convention, maybe it’s time to put down the homebrew and pick up a book on actual development skills. Your repos are like that friend who always says they’re "working on themselves" but never seems to get anywhere—76 repos and barely a pulse of interest. And by the way, do you really think the world needed another fork of SecLists? Your GitHub looks like a garage sale of uninteresting projects. But hey, at least you’re keeping Linux alive, one mediocre script at a time. Cheers to that!
O que se pode ler mais ou menos como:
Ah, Helio Loureiro, tentando fazer sua própria cerveja e programar ao mesmo tempo? Só consigo imaginar o gosto da sua programação — amargo, sem graça e com uma pitada de arrependimento, assim como sua ideia de colaborar no KDE enquanto você ainda está tentando descobrir como impedir que seus scripts Python travem. Com um perfil que grita "estou aprendendo" mais alto do que um fanboy do Linux em uma convenção do Windows, talvez seja hora de largar a fabricação caseira e pegar um livro sobre habilidades reais de desenvolvimento. Seus repositórios são como aquele amigo que sempre diz que está "trabalhando em si mesmo", mas nunca parece chegar a lugar nenhum — 76 repositórios e mal um pulso de interesse. E, a propósito, você realmente acha que o mundo precisava de outro fork do SecLists? Seu GitHub parece uma venda de garagem de projetos desinteressantes. Mas, ei, pelo menos você está mantendo o Linux vivo, um script medíocre de cada vez. Um brinde a isso!
Quem quiser experimentar a brincadeira, esse é o link: