Miesięczne archiwum: Grudzień 2011

Nagrywanie pulpitu

Od dłuższego czasu wykorzystuję ffmpeg do konwersji filmów, dźwięku i wszelkiej maści mediów cyfrowych. Przed paroma dniami natknąłem  się na niesamowite zastosowanie jakim jest zgrywanie pełnoekranowego pulpitu pod X-ami. Otóż wykonuje się je na przykład tak:

ffmpeg -f x11grab -s 1600x900 -i :0.0+,224 -acodec mp3 -ac 1 -vcodec libx264 -threads 4 -f matroska capture.mkv

nie dość że obraz jest w wybranej rozdzielczości (tu 1600×900) to jeszcze stosujemy kompresję H264 i pakujemy wszystko do formatu Matroska
Dla mnie bomba!

Aktualizacja: Nowsza wersja łapiąca oprócz obrazu również dźwięk. Jest mały problem z brakiem synchronizacji ale ogólne wrażenie nadal świetne:

#!/bin/bash
#
NAME=$(basename $0)
SNDFILE=$(mktemp /tmp/$NAME.XXXXXX) || exit 1

arecord -f S16_LE -c1 -r44100 -t wav $SNDFILE & PIDaudio=$!

ffmpeg -y -i $SNDFILE -f x11grab -s 1600x900 -r 25 -i :0.0+,224 -vcodec libx264 -threads 0 -f matroska -acodec ac3 "$1" & PIDvideo=$!

read -p "Press enter to stop recording"
kill $PIDvideo $PIDaudio
rm -f $SNDFILE

Monitorowanie web-cam’em

Dawno dawno temu w odległej galaktyce… kupiłem kamerkę 😉

Była to VF0420 Live! Cam Vista IM
Szybko znudziła mi się jako zabawka do „pogaduch sieciowych” i postanowiłem zrobić z niej użytek do monitorowania obiektu czy też posesji.
Dlatego też, wystawiłem ją przez okno aby obserwowała wejście na teren działki, podpiąłem pod maszynę Linuksową (Gentoo).

Użyłem „kernelowych” sterowników gspca(model ov519) oraz zainstalowałem soft do robienia zrzutów, MJPG-Streamer.
MJPG-Streamer udostępnia stream w formacie MJPG (który na dobrą sprawę generuje sama kamera) z bardzo małym narzutem na CPU.
Oprócz streamu można też łapać pojedyncze klatki obrazu JPG co właśnie najbardziej mnie interesowało.
Skrypt bash podpięty do cron’a co 10 minut pobiera klatkę obrazu z kamerki i wrzuca ją do katalogu przy użyciu mechanizmu rotacyjnego.
Inny skrypt PHP przeszukuje katalog i wyświetla wszystkie obrazy JPG pasujące do wzorca nazwy w formacie tabelki obrazków. Dodatkowo codziennie o 22:00 inny skrypt używając mencoder’a łączy te JPG-i i tworzy wideo, niejako tworząc przyspieszony obraz wydarzeń z całego dnia rejestrowania kamery.

Skrypt wyciągający JPG-i z deamona MJPG-streamer:

#!/bin/bash

#gets image from webcam served and saves it into first param
function shot()
{
        /usr/bin/curl "http://localhost:3000/?action=snapshot" -o $1 2>/dev/null;
}

#check if webcam server(mjpg-stream) is running; quit if not
pgrep mjpg_streamer 1>/dev/null; [ $? != 0 ] && exit 1;

#maximum number of pictures to take, if exceed - start from 0
pic_num=144;
#where the pics are stored
cd /var/www/localhost/htdocs/webcamgallery/
#set permissions accordingly
umask -S o+r 1>/dev/null;

#set current picture name accordingly
line=`/bin/ls *current* 2>/dev/null | /usr/bin/gawk 'BEGIN { FS="-";} /current/ { printf("%s %i out-current-%i-.jpg out-%i.jpg out-%i.jpg", $0, $3, ($3 + 1) > '$pic_num' ? 0 : ($3 + 1), $3, ($3 + 1) > '$pic_num' ? 0 : ($3 + 1) ); }' -`;

#make screenshot
if [ "$line" == "" ]; then
        #echo bummer!
        shot "out-current-0-.jpg";
fi

#format variables
set -- ${line#*:}; current=$1 num=$2 new_current=$3 old_current=$4 kwas=$5;

#move current image to old current and new pic shot to current
mv -f $current $old_current 2>/dev/null;
mv -f $kwas $new_current 2>/dev/null;

shot $new_current;

To natomiast jest skrypt robiący film(y) z obrazków JPG:

#!/bin/bash

#go to images location
cd /var/www/localhost/htdocs/webcamgallery;
j=0;

#make poster from 1st image and change other out*jpg images names to new*.jpg
for file in `ls -tr out*jpg`; do
if [ "$j" == "0" ]; then
/bin/cp -f $file poster.jpeg;
fi
/bin/cp -f $file `printf "new-%03d.jpg" $j`; j=$((j+1));
done;

#make WebM video from new* images
mencoder mf://new*.jpg -mf w=640:h=480:fps=15:type=jpg -really-quiet -nosound -ovc lavc -ffourcc VP80 -of lavf -lavfopts format=webm -lavcopts vcodec=libvpx -o video.webm

#make video.mp4 video fro flash from new*images
ffmpeg -y -i new-%03d.jpg -vcodec libx264 -level 41 -crf 25 -bufsize 20000k -maxrate 25000k -g 250 -r 20 -s 640x480 -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 7 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -rc_eq 'blurCplx^(1-qComp)' -bf 16 -b_strategy 1 -bidir_refine 1 -refs 6 -deblockalpha 0 -deblockbeta 0 -v 0 -loglevel quiet video.mp4 2> /dev/null

#set permissions
chmod 644 video.webm video.mp4 poster.jpeg
#remove unneccessary new images - cleanup
rm -f new*jpg

Dodatkowo jest jeszcze trochę kodu PHP który wyświetla zrzuty JPGów z całego dnia w tabelaryczny i uporządkowany sposób ale nie ma sensu tego pokazywać.

Końcowy efekt można podziwiać tu: http://haos.hopto.org/webcamgallery/