#!/bin/sh # Copyright © 2012, 2013 Jonas Smedegaard # Description: record most possible video data using least CPU # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Depends: libav-tools, alsa-utils, v4l-utils # # TODO: add --help option # TODO: make inputs overrideable # TODO: optionally limit number of inputs # TODO: make codecs, rates etc. configurable # TODO: auto-limit number of video-inputs per USB channel # TODO: include SMTPE channel # TODO: Check and ask if outfile already exist # TODO: Add --force option to skip asking for overwriting set -e #melt cam_Microsoft_LifeCam_Studio.mlt -consumer avformat:x.avi vcodec=ffv1 an=1 output="${1:-dump.mkv}" # resolve audio inputs: default PCM of all ALSA cards with input devices ainputs="$(arecord -l | perl -anE '/^card/ and say $F[2]')" #ainputs="CARD=Generic_1,DEV=0" # FIXME: detect and avoid more than one device on same USB channel: # [video4linux2 @ 0xed7e00] ioctl(VIDIOC_STREAMON): No space left on device # /dev/video2: No space left on device # maybe with $(v4l2-ctl --list-devices) vinputs="$(ls -1 /dev/video*)" #vinputs="$(ls -1 /dev/video* | grep -v video1)" #vinputs="/dev/video0 /dev/video1 /dev/video3" #vinputs="/dev/video0" # TODO: probe and optimize V4L settings (highest 16/9 size at >= 20fps inrate=20 #inrate=10 outrate=$inrate # seems this ensures fixed rate when input is flaky #vcodec=huffyuv # more common vcodec=ffvhuff # more compact, supports YV12 colorspace #vcodec=ffv1 # most compact, supports RGBA colorspace, too CPU-hungry acodec=pcm_s16le vf="${vf:+$vf }-vf setpts=(RTCTIME-RTCSTART)/(TB*1000000)" # current time vf="${vf:+$vf }-vf hqdn3d" # high-quality denoise (good for webcams) font='/usr/share/fonts/truetype/droid/DroidSans.ttf' #vf="${vf:+$vf }-vf "drawtext=fontfile=$font: timecode='09\:57\:00\:00': r=25: x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1"}" #vf="${vf:+$vf }-vf "drawtext=fontfile=DroidSans.ttf:'timecode=09\:57\:00\:00':r=25:x=\(w-tw\)/2:y=h-\(2*lh\):fontcolor=white:box=1:boxcolor=0x00000000@1"}" parse_v4l2_formats() { v4l2-ctl --list-formats-ext -d "$1" | perl -n \ -e '/^\tIndex\h*:/ and $type=$format=$raw=$size=$speed=undef;'\ -e '/^\tType\h*: (Video Capture)/ and $type=$1;'\ -e '/^\tPixel Format: '\''(\w+)'\''( \(compressed\))?/ and $format=$1 and $raw=int(!($2));'\ -e '/^\t\tSize: Discrete (\d+x\d+)/ and $size=$1;'\ -e 'next unless ($type and $format and $size);'\ -e '/^\t\t\tInterval: .* \((\d+)\.\d+ fps\)/ and $speed=$1;'\ -e 'next unless ($speed >= '$inrate');'\ -E 'say "$raw $size $format"' \ | sort -rV } # expand arguments i=0 ainargs= amaps= for input in $ainputs; do # TODO: handle varying descriptions (not just pick first entry) # TODO: handle more descriptions (not just assume stereo) achannels= achannelsdesc="$(amixer -c $input | grep '^ Capture channels:' | head -n 1)" case $achannelsdesc in *': Mono') achannels=1 ;; esac ainargs="${ainargs:+$ainargs }-f alsa -ar 44100 ${achannels:+-ac $achannels} -i hw:$input" amaps="${amaps:+$amaps }-map $i:a" ((i=i+1)) done vinargs= vmaps= for input in $vinputs; do read raw size format dummy <