Eida.cz - Digitální VHSky, kamery a archivace

Digitální VHSky, kamery a archivace

11. května 2017, 18:23 Eida

V4L je asi tře­tí ne­bo čtvr­tá nej­lepší věc na svě­tě hned po ve­če­ři a obě­dě. Sa­mozřejmě na svě­tě exis­tuje spous­tu dův­o­dů, ze kte­rých není použi­tí Li­nuxu uži­tečné, ne­bo je dokon­ce škod­livé, ale je­ho kon­cep­ce sjedno­cení prá­ce s vi­de­ovstu­py na ab­s­trakt­ní vrstvě je zrov­na jedním z moc hez­kých příkla­dů, kdy to ce­lé funguje pro au­to­ma­tickou ot­rockou prá­ci bez nutnos­ti se složi­tě v ně­čem šť­ou­rat a na­dávat u to­ho. A au­to­ma­tizovaná digi­ta­liza­ce če­hoko­liv, ať už přes fo­cení mo­bi­lem ne­bo po­mo­cí ob­jek­tové kla­sifika­ce uměl­ou in­te­ligen­cí, je z něj­a­kého dův­o­du po­řád tren­dem.

Osm­de­sát­ková techno­logie VHS v ro­ce 2017.

VHSky jsou techno­logií, kte­rá můj život naš­těs­tí kompletně mi­nu­la a ne­mo­hu si to vy­na­chvá­lit. Před dávný­mi le­ty dost možná leck­do oko­lo pou­žíval tyhle ko­losální analogo­vé kaze­ty a když se to tak vez­me, bylo to do­ce­la k ni­če­mu. Ale na druhou stranu to by­la asi je­di­ná do­stupná techno­logie, na kte­rou bylo možné v té do­bě zazna­menat a ar­chivovat kro­mě te­leviz­ních po­řa­dů i význam­né do­má­cí chvilky, osobní výr­o­čí, svat­by a vůb­ec všechno, co s tím tak něj­ak sou­vi­sí. S techno­logií jde ru­ku v ru­ce i něj­a­ká ta spe­cifika­ce, kte­rá je ta­dy pro nás v Ev­ropě defi­novaná ja­ko PAL, te­dy nápal, kte­rý ur­čuje spous­tu vlastnos­tí ko­lem analogo­vého signálu, te­dy pro vy­síl­ání pře­devším charak­ter a frek­ven­ci nosné vl­ny a po­mocné nosné vl­ny, šíř­ku pás­ma pro ce­lé vi­deo a další vlastnos­ti, nicméně pro zpra­cování na kon­covém za­řízení ta­ké do­bu trvání sním­ků a li­nek, je­jich po­čet a všechno, co zkrátka potře­buje­me vě­dět. Tahle vi­dea si můž­e­me pak před­stavit typicky ja­ko 720x576 v 4:3 aspek­tovém rám­ci, če­muž se říká asi 576i, což je v analogo­vém po­dání 652 li­nek v 50Hz stří­dání po­lí, čímž se do­stává­me na něj­a­kých 25 FPS. Trik je v tom, že oněch 25 bu­de ve sku­tečnos­ti asi 24.978014, ale to je už za­se tro­chu vyšší magie.

Mo­derní po­je­tí vi­dea, te­dy to plně digi­tální, se v dnešní do­bě to­čí ko­lem ko­lem ví­ce či méně chyt­rých kon­tejne­rů (vlastně “jen” MPEG-4 ne­bo Ma­t­roška), kte­ré pak teprve za­hrnu­jí v so­bě konkrét­ní da­tové prou­dy vi­dea, au­dia a tře­ba ti­tul­ků. Dá se s tím děl­at oprav­du hodně, pro dnešní vi­dea si pře­j­e­me hlavně prou­dy v ko­de­ku x264 ne­bo x265 a pro zvu­ky po­dobně, větši­nou ztrá­tové AAC ne­bo klidně i MP3. K převo­du analogo­vé kaze­ty je potře­ba vál, co ji vůb­ec umí něj­ak rozjet, a k ně­mu pak in­terní ne­bo USB grabber, kte­rý digi­ta­lizuje ta­kový signál z analogo­vého roz­hraní SCAR­Tu ne­bo kompo­zit­ního vi­dea pod­le spe­cifika­ce V4L2. Dneska je to vlastně jedno, pro­tože mo­derní jád­ra umí pra­covat vlastně se vším, ale důl­eži­té je ne­za­po­menout, že zpra­cováno bu­de oprav­du jen vi­deo a zvuk je potře­ba so­sat za­se z ji­ného za­řízení, totiž ab­s­trakt­ní zvu­kové kar­ty, kte­rou grabber bu­de nej­spíše ob­sahovat. Výpis ta­kových je možné zís­k­at po­mo­cí ak­tuálního správ­ce zvu­ku, tře­ba v přípa­dě Pul­se­Au­dio ja­ko pactl list, ne­bo pří­mo ja­ko AL­SA, aplay -L. Pak už je do­ce­la snadné to­hle všechno zkom­bi­novat a ne­chat za­chytávat kaze­tu z pře­hráva­če. Asi nej­lepší je pou­žít mocný ffmpeg, ve kte­rém se dá uděl­at úplně všechno, jen je potře­ba si dát po­zor právě na fra­me­ra­te, pro­tože pří­má konverze je­di­ným průc­ho­dem může roz­ho­dit syn­chro­niza­ci zvu­kové a au­dio stopy v řá­d­ech pro­cent, což se pak vel­mi těžko až ne­možně na­pravuje. Ja­ko výh­o­da pak může sloužit dup­lika­ce výstu­pu na síť, což je příj­em­ný bo­nus.

ffmpeg -rtbufsize 2.14748e+09 -probesize 128k -isync -standard pal -to 01:30:00.0 -f v4l2 -thread_queue_size 4096 -framerate pal -i /dev/video0 -f alsa -thread_queue_size 2048 -ac 2 -ar 48000 -strict -2 -i hw:1,0 -c:a aac -af aresample=async=1000 -c:v libx264 -preset medium -tune grain -g 10 -b:v 4200k video-01.mp4 -f flv -c:v libx264 -preset ultrafast -b:v 1000k rtmp://videoserver:1935/live/video

Sa­mozřejmě to ne­mu­sí kaž­d­é­mu vy­hovovat a dá se to děl­at i po­sta­ru dvouprůc­ho­dovou ces­tou spo­lu s přímým zob­razením živého výstu­pu na mo­ni­tor to­ho daného stro­je, k če­mu zle s výh­o­dou vy­u­žít pře­hrávač VLC, kte­rý má tuhle vlastnos­ti vy­loženě v malíčku. Je­ho ne­výh­o­dou je ale právě po­měrně roz­sáh­lá sa­da komp­lika­cí sou­vi­se­jí­cích s přímým kó­dováním do x264, pro­to je ta­kový hrubý záznam větši­nou lepší uložit tak, jak z grabbe­ru te­če - a výsle­dek si spolkne tře­ba i ně­co ko­lem jedno­ho gigabaj­tu za mi­nu­tu zázna­mu, s čímž je potře­ba po­čít­at. Na druhou stranu se záznam uloží, pak se začne zpra­covávat, kaze­ta sa­ma do­je­de do kon­ce, pře­t­o­čí se a vše je zna­meni­tě ukon­čeno.

vlc v4l:///dev/video0 :v4l-standard=PAL :v4l-norm=0 :input-slave=alsa://hw:1,0 :live-caching=300 '--sout=#transcode{vcodec=HFYU,acodec=s16l,channels=2,samplerate=48000}:duplicate{dst=display,dst=std{access-file{no-overwrite},mux=avi,dst=RAW_video-01.avi}}' --stop-time 5400 vlc://quit && ffmpeg -i RAW_video-01.avi -c:a aac -c:v libx264 -preset slow -tune grain -v:b 4200k -crf 22 video-01.mp4

Na po­ma­lých stro­jích s GUI, kde je potře­ba pri­o­ri­tizovat ten­to pro­ces před vším ostat­ním, se obvykle ješ­tě vy­pla­tí ho­dit ni­ce o ně­co výše směr­em k re­álné­mu ča­su, aby se to náh­o­dou ce­lé ne­pokazi­lo a ne­pro­padlo do za­tra­cení. Druhý hrubý výstup už ale není potře­ba ni­jak složi­tě re­kó­dovat, střih se dá zvlád­nout celkem po­ho­dlně bez něj a pro­tože do­ba je stre­a­mova­cí, ne­mu­sí být od vě­ci ho­dit mov ato­my do­pře­du.

ffmpeg -i video-01.mp4 -ss 00:00:05.30 -to 01:28:31.50 -c:v copy -c:a copy -movflags faststart video-01-final.mp4

A to už tak tro­chu sou­vi­sí s ar­chiva­cí, pro­tože kam ji­nam digi­ta­lizované vi­deo ho­dit, než do něj­a­kého to­ho clou­du? DVDčka a všech­ny ostat­ní možnos­ti jsou stejně zasta­ra­lé a už jen mál­ok­do je pou­žívá, takže tře­ba YouTu­be může být do­ce­la jas­ná vol­ba, ačk­o­liv to tře­ba kvů­li pův­odní ve­likos­ti výsledného sou­bo­ru ne­bu­de ze za­čátku tak vy­pa­dat. Ale od to­ho je pře­ci ne­in­ter­ak­tivní workflow, žáno.

S tím sou­vi­sí tak tro­chu druhé té­ma po­sledních be­zesných no­cí, ve kte­rých běž­e­lo mno­ho poku­sů o opravu au­to­ma­tického zpra­cování zázna­mů z bez­pečnost­ních ka­mer. Už něj­a­kou do­bu slou­ží ke střežení růz­ných místnos­tí ne­jen v budníku V4L ka­me­ry, kte­ré jsou na­po­jené na mo­ti­on a další tajné analyzá­to­ry, ovšem mo­ti­ond z nich v první řa­dě stre­a­muje živě a za další ta­ké uklá­dá v něj­a­kých 4 sním­cích za se­kun­du sta­tické ob­ráz­ky pro poz­dější zpra­cování. Proč je to­mu tak, to je za­se ji­ná věc, důl­eži­té je ovšem to, že v pravi­delných in­tervalech, obvykle jednou denně nad ránem, je potře­ba z růz­ných míst přenést ty­to ob­ráz­ky ke zpra­cování na jedno cen­t­rální mís­to, což může vy­pa­dat na­příklad něj­ak tak­to:

fetch-cam.sh 397 bajtů
#!/bin/bash

BASEDIR="/security"
cd $BASEDIR/sh
CAMERA=${1:-"cam0"}
YDAY=$(date -d "yesterday 13:00 " '+%Y-%m-%d')

DATEARR=(`echo $YDAY | sed -e 's/[:-]/ /g'`)
YR=${DATEARR[0]}
MO=${DATEARR[1]}
DA=${DATEARR[2]}

CURRENT=$BASEDIR/$CAMERA/$YR/$MO

mkdir -p $CURRENT
rsync --ignore-existing -az security@security.eida.cz:/security/$YR/$CAMERA/$MO/$DA $CURRENT

# VIDEO
./month.sh ../$CAMERA/$YR/$MO
Zís­k­ání zázna­mů ze vz­dál­ených sys­té­mů.

Ne­děje se tam vlastně nic ji­ného, než že se ob­ráz­ky přes rsync celkem bez­pečně a spo­leh­livě do­stanou do svého po­sledního umís­tění a pak s ni­mi za­číná za­jí­mavá magie. Když už je totiž vše ho­tové, sestříhá se z daného mě­sí­ce pro kaž­dý den živý ča­sosběr, kte­rý byl lif­rován na YouTu­be, ale osud to­mu pak něj­ak ne­přál.

month.sh 416 bajtů
#!/bin/bash

for m in "$@"
do
	for d in $(ls "$PWD/$m" | grep -v "^\.")
        do
	  		
		for e in $(ls -1 "$m/$d" | grep event | grep -v mp4 | sort -t- -n -k2)
		do
			if [ -d "$m/$d/$e" ]; then
				echo "timelapse $m/$d/$e"
	  			./timelapse.sh "$m/$d/$e"
			fi
		done

		if [ -d "$m/$d" ]; then
			echo "day $m/$d"
			#if [ ! -f "$m/$d.mp4" ]; then
				./day.sh "$m/$d"
			#fi
			rm -r "$m/$d"
		fi
	done

done

Zpra­cování jedno­ho mě­sí­ce.

Tvor­ba ča­sosbě­ru pro­bíhá opět po­mo­cí ffmpeg ja­ko sek­ven­ce ob­ráz­ků po­slaná do MPEG-4 kon­tejne­ru s x264 ko­de­kem v po­sta­ču­jí­cím for­má­tu ja­ko jednot­livé udá­l­os­ti zazna­menané v daném dni

timelapse.sh 287 bajtů
#!/bin/bash


for d in "$@"
do
	if [ -d "$d" ]; then
		if [ ! -f "$d"/../$(basename "$d").mp4 ]; then
			ffmpeg -y -framerate 10 -pattern_type glob -i "$d"/'*.jpg' -c:v libx264 -movflags faststart -acodec none -vf "format=yuv420p" "$d"/../$(basename "$d").mp4
		fi
		rm -r "$d"
	fi
done
Zpra­cování udá­l­os­tí z ob­ráz­ků do vi­dea.

a následně ja­ko ce­lý den oby­čejným spo­jova­cím pro­toko­lem.

day.sh 231 bajtů
#!/bin/bash

for d in "$@"
do
	if [ -d "$d" ]; then
		ffmpeg -y -f concat -safe 0 -i <(for f in $(ls -1 "$d" | grep event-.*\.mp4 | sort -t- -n -k2); do echo "file '$PWD/$d/$f'"; done) -c copy "$d"/../$(basename "$d").mp4
	fi
done
Zpra­cování jedno­ho dne.

To­hle sa­mo o so­bě by­la vý­b­orná myšl­enka, kte­rá ale gene­rova­la pří­l­iš velkou zá­těž pro serve­ry YouTu­be, kte­ré to na špatně ověř­ených úč­tech okamži­tě za­hazovaly kvů­li dup­li­cit­ní­mu ob­sahu a nešlo to vydržet. Druhá myšl­enka pak by­la vy­u­žít vlastnos­ti ce­lého mě­sí­ce. V první řa­dě jsou sou­bo­ry uspo­řá­d­á­ny tak, jak přišly, a vy­tvo­ří se z nich ISO ob­raz pro poz­dější uchování na něj­a­kém DVD, kte­ré stejně za­padne v ar­chivech hlu­boko v podze­mí a nik­do ho číst ne­bu­de.

Myšl­enka zpra­cování právě pro použi­tí v ar­chiva­ci on­li­ne pak tkví ve spo­jení jednot­livých dnů v mě­sí­ci ta­kovým způ­s­o­bem, že jsou do po­pisku k na­hrávané­mu vi­deu při­dá­ny ča­sové značky v kli­ka­telném for­má­tu, te­dy (hh:mm:ss). Ukázalo se, že tak­to zhuš­těný záznam z jen­do­ho mě­sí­ce zba­re ně­co přes dvanáct ho­din, což je bo­hu­žel pří­l­iš mno­ho pro jedno vi­deo, nicméně už jen charak­ter názvu sou­bo­rů umožňuje roz­dě­l­it mě­síc na vi­dea o ví­ce čás­tech za­čína­jí­cích 0, 1, a 2|3. Ty­to čás­ti jsou vy­tvo­ře­ny re­kó­dováním, ne­boť v něk­te­rých přípa­dech slu­čova­cí pro­tokol, kte­rý je použi­tý ffmpegem, z něj­a­kého dův­o­du na YouTu­be nefunguje tak, jak by asi úplně mo­hl a měl. Tak­to získ­ané tře­ti­nové čás­ti po­tom už pří­mo pře­bírá skript youtu­be-uplo­ad a organizuje výsledky v konkrét­ních play­lis­tech.

pack-month.sh 2.31 KiB
#!/bin/bash

if [ -z "$*" ] ; then
	echo "Usage: $0 [ camera [\"0 1 23\"]]"
	exit 0
fi

BASEDIR="/security"
cd $BASEDIR/sh
CAMERA=${1:-"cam0"}

YDAY=$(date -d "yesterday 13:00 " '+%Y-%m-%d')

DATEARR=(`echo $YDAY | sed -e 's/[:-]/ /g'`)
YR=${DATEARR[0]}
MO=${DATEARR[1]}
DA=${DATEARR[2]}

CURRENT=$BASEDIR/$CAMERA/$YR

# make ISO image
if [ ! -f "$CURRENT/$YR-$MO.iso" ]; then
	genisoimage -V "$YR-$MO $CAMERA" -lJR -o "$CURRENT/$YR-$MO.iso" "$CURRENT/$MO"
fi

# split prepare
SPL=${2:-"0 1 23"}

# split
for s in $SPL
do
	TOTAL_DURATION=0
        DESCRIPTION=""

        # read and fetch
        for fc in $( ls -1 "$CURRENT/$MO" | grep [${s}].\.mp4 | sort );
        do
                FORMAT_DURATION=$( date -d@"$TOTAL_DURATION" -u +%H:%M:%S )

                DESCRIPTION=$( echo "$DESCRIPTION"_\("$FORMAT_DURATION"\): "$fc" )
                DURATION=$(ffmpeg -i "$CURRENT/$MO/${fc}" 2>&1 | grep Duration | egrep -o "[0-9]{2,}\:[0-9]{2}\:[0-9]{2}\.[0-9]{2}")
                TIME=$(echo $DURATION | awk -F : '{ print (($1*3600)+($2*60)+($3))}')
                SPLIT_SEC=$(echo $DURATION | awk -F . '{print $2}')

                TOTAL_DURATION=$( echo ${TOTAL_DURATION}+${TIME}+${SPLIT_SEC}/100 | bc -l )
        done

        DESC=$( echo "$DESCRIPTION" | sed 's/_\+/\n/g' )

	if [ ! -f "$CURRENT/upload/$YR-$MO.$s.mp4" ]; then

		mkdir -p "$CURRENT/upload"

        	# concatenate
        	if [ -d "$CURRENT/$MO" ]; then
                	ffmpeg -y -f concat -safe 0 \
                	-i <(for f in $( ls -1 "$CURRENT/$MO" | grep [${s}].\.mp4 | sort ); do echo "file '$CURRENT/$MO/$f'"; done) \
			-vf "scale=-1:480,pad=640:480:(640-iw)/2:(480-ih)/2,setsar=1" \
			-movflags faststart \
			"$CURRENT/upload/$YR-$MO.$s".mp4
        	fi

	fi

	# upload
        if [ -f "$CURRENT/upload/$YR-$MO.$s.mp4" ]; then
                /usr/local/bin/youtube-upload \
                --title="${YR}-${MO} [${s}] ${CAMERA}" \
                --description="SECURITY ${YR}/${CAMERA}/${MO} ${DESC}" \
                --credentials-file="${BASEDIR}/credentials.json" \
                --client-secrets="/usr/local/share/youtube_upload/client_secrets.json" \
                --privacy="unlisted" \
                --playlist="Security ${YR} ${CAMERA}" \
                --tags="cz.eida.security.${CAMERA}" "$CURRENT/upload/$YR-$MO.$s.mp4"
        fi

# /for
done

exit 0
Zpra­cování ce­lého mě­sí­ce a uplo­ad na YouTu­be.

To­hle je v ten­to okamžik asi vr­chol au­to­ma­tizované ar­chiva­ce bez­pečnost­ních zázna­mů z ka­mer a vy­pa­dá to, že to takhle vydrží i něj­a­kou do­bu do bu­douc­na. Je prav­da, že Go­ogle, kte­rý je vy­loženě pro­ti open­sour­ce, čas od ča­su sa­movolně a zlovolně mění YouTu­be API, aby to vývo­jář­ům za kaž­d­ou cenu zne­příj­emnil, takže je tře­ba skript youtu­be-uplo­ad a s ním sou­vi­se­jí­cí pytho­nové balíčky udržovat ak­tuální, při­čemž je pak nutné ne­za­po­menout ak­tua­lizovat i sa­motný přístu­po­vý token, ji­nak na­hrávání ko­likrát skon­čí s něj­a­kou ne­smy­slnou chy­bou a je hned vy­malováno. Ale to už je ta ne­pa­trná ce­na za dlouhé dny ne­bo i mě­sí­ce, kdy to všechno naš­těs­tí je­de sa­mo a bez chyb. A tak by to mělo ta­ké být - jsou-li něk­de opa­ku­jí­cí se úlo­hy, nechť jsou plně au­to­ma­tizované a my má­me čas si užívat hez­ké dny bez stre­su.

Eida
Tento článek přečetlo již 10 čtenářů (0 dnes).

Komentáře

Nový komentář