58,6 → 58,8 |
} |
|
# {{{ # TO-DO |
# * Replace 'grep' with bash's '[[ =~ ]]' where possible (no forking => much faster). |
# +Requires bash 3 (3.2 changed semantics) |
# * [[x1]] Find out why the order of ffmpeg arguments breaks some files. |
# * [[x2]] Find out if egrep is safe to use or grep -E is more commonplace. => |
#+ SUS v2: egrep is deprecated, grep -E replaces it |
541,7 → 543,7 |
varname=${por/% *} # Everything up to the first space... |
tmp=${por#* } # Rest of string |
flag=${tmp/% *} |
if [[ $flag == '=' ]]; then |
if [ "$flag" == '=' ]; then |
# No need to override... |
feedback="$varname(=)" |
else |
550,9 → 552,9 |
ov="$ov, $feedback" |
fi |
done <$cfgfile |
[[ -z $ov ]] || inf "$desc from $cfgfile:$NL ${ov:2}" |
[ -z "$ov" ] || inf "$desc from $cfgfile:$NL ${ov:2}" |
# No loaded overrides but errors/warnings to print, do print the file name |
if [[ ( -z $ov ) && $BUFFER ]]; then |
if [ -z "$ov" -a "$BUFFER" ]; then |
inf "In $cfgfile:" |
fi |
flush_buffered ' ' |
584,7 → 586,7 |
local p=$1 prof= |
local -a PATHS=( ~/.vcs/profiles/ /usr/local/share/vcs/profiles/ /usr/share/vcs/profiles/ ) |
|
if [[ ${p:0:1} == ':' ]]; then |
if [ ${p:0:1} == ':' ]; then |
case $p in |
:list) |
# No need to be efficient here... |
1172,10 → 1174,12 |
# the indicated length |
# pad($1 = minimum length, $2 = string) |
pad() { |
# Must allow non-numbers |
local l; (( l = $1 - ${#2} , 1 )) |
[[ $l -le 0 ]] || printf "%0${l}d" '0' |
echo $2 |
# printf "%0${1}d\n" "$2" # [[R1#18]] # Can't be used with non-numbers |
local str=$2 |
while [[ ${#str} -lt $1 ]]; do |
str="0$str" |
done |
echo $str |
} |
|
# Get Image Width |
1227,15 → 1231,15 |
local bytes=$1 |
local size= |
|
if [[ $bytes -gt $(( 1024**3 )) ]]; then |
if [ "$bytes" -gt $(( 1024**3 )) ]; then |
local gibs=$(( $bytes / 1024**3 )) |
local mibs=$(( ( $bytes % 1024**3 ) / 1024**2 )) |
size="${gibs}.${mibs:0:2} GiB" |
elif [[ $bytes -gt $(( 1024**2)) ]]; then |
elif [ "$bytes" -gt $(( 1024**2)) ]; then |
local mibs=$(( $bytes / 1024**2 )) |
local kibs=$(( ( $bytes % 1024**2 ) / 1024 )) |
size="${mibs}.${kibs:0:2} MiB" |
elif [[ $bytes -gt 1024 ]]; then |
elif [ "$bytes" -gt 1024 ]; then |
local kibs=$(( $bytes / 1024 )) |
bytes=$(( $bytes % 1024 )) |
size="${kibs}.${bytes:0:2} KiB" |
1649,12 → 1653,10 |
} |
|
# assertion operator |
# Note: Use single quotes for globals, no need to expand in release |
# assert(... = code) |
# TODO: Limit usage to values that will expand correctly always (i.e. not with quotes) |
assert() { |
[[ $RELEASE -eq 0 ]] || { |
function assert { :; } # Redefine to avoid check |
} |
[[ $RELEASE -eq 1 ]] && return |
local c=$(caller 0) # <num> <func> <file> |
c=${c% *} # <num> <func> |
local LIN=${c% *} FN=${c#* } |
1691,19 → 1693,19 |
create_temp_dir() { |
trace $@ |
|
[[ -z $VCSTEMPDIR ]] || return 0 |
[ "$VCSTEMPDIR" ] && return 0 |
|
# Try to use /dev/shm if available, this provided a very small |
# benefit on my system but me of help for huge files. Or maybe won't. |
# Passing a full path template is more x-platform than using |
# -t / -p |
if [[ ( -d /dev/shm ) && ( -w /dev/shm ) ]]; then |
if [ -d /dev/shm ] && [ -w /dev/shm ]; then |
VCSTEMPDIR=$(mktemp -d /dev/shm/vcs.XXXXXX) |
else |
[[ $TMPDIR ]] || TMPDIR="/tmp" |
[ "$TMPDIR" ] || TMPDIR="/tmp" |
VCSTEMPDIR=$(env TMPDIR="$TMPDIR" mktemp -d "$TMPDIR/vcs.XXXXXX") |
fi |
if [[ ! -d $VCSTEMPDIR ]]; then |
if [ ! -d "$VCSTEMPDIR" ]; then |
error "Error creating temporary directory" |
return $EX_CANTCREAT |
fi |
1721,7 → 1723,7 |
new_temp_file() { |
trace $@ |
local r=$(env TMPDIR="$VCSTEMPDIR" mktemp "$VCSTEMPDIR/vcs-XXXXXX") |
if [[ ! -f $r ]]; then |
if [ ! -f "$r" ]; then |
error "Failed to create temporary file" |
return $EX_CANTCREAT |
fi |
1741,7 → 1743,7 |
trace $@ |
local mode=f lineno |
|
if [[ $mode == 'f' ]]; then # Random mode |
if [ "f" == $mode ]; then # Random mode |
# There're 5 rows of extra info printed |
local ncolours=$(( $(convert -list color | wc -l) - 5 )) |
randcolour() { |
1838,12 → 1840,12 |
fi |
|
local inc= |
if [[ $tcfrom -eq $TC_INTERVAL ]]; then |
if [ "$tcfrom" -eq $TC_INTERVAL ]; then |
inc=$tcint |
elif [[ $tcfrom -eq $TC_NUMCAPS ]]; then |
elif [ "$tcfrom" -eq $TC_NUMCAPS ]; then |
# Numcaps mandates: timecodes are obtained dividing the length |
# by the number of captures |
if [[ $tcnumcaps -eq 1 ]]; then # Special case, just one capture, center it |
if [ $tcnumcaps -eq 1 ]; then # Special case, just one capture, center it |
inc=$(awkexf "(($end-$st)/2 + 1)") |
else |
inc=$(awkexf "(($end-$eo-$st)/$tcnumcaps)") |
1884,11 → 1886,11 |
|
case "$w" in |
352) |
if [[ ( $h -eq 288 ) || ( $h -eq 240 ) ]]; then |
if [ $h -eq 288 ] || [ $h -eq 240 ]; then |
# Ambiguous, could perfectly be 16/9 |
# VCD / DVD @ VCD Res. / Half-D1 / CVD |
ar=4/3 |
elif [[ ( $h -eq 576 ) || ( $h -eq 480 ) ]]; then |
elif [ $h -eq 576 ] || [ $h -eq 480 ]; then |
# Ambiguous, could perfectly be 16/9 |
# Half-D1 / CVD |
ar=4/3 |
1895,25 → 1897,25 |
fi |
;; |
704|720) |
if [[ ( $h -eq 576 ) || ( $h -eq 480 ) ]]; then # DVD / DVB |
if [ $h -eq 576 ] || [ $h -eq 480 ]; then # DVD / DVB |
# Ambiguous, could perfectly be 16/9 |
ar=4/3 |
fi |
;; |
480) |
if [[ ( $h -eq 576 ) || ( $h -eq 480 ) ]]; then # SVCD |
if [ $h -eq 576 ] || [ $h -eq 480 ]; then # SVCD |
ar=4/3 |
fi |
;; |
esac |
|
if [[ -z $ar ]]; then |
if [[ ( $h -eq 720 ) || ( $h -eq 1080 ) ]]; then # HD |
if [ -z "$ar" ]; then |
if [ $h -eq 720 ] || [ $h -eq 1080 ]; then # HD |
ar=16/9 |
fi |
fi |
|
if [[ -z $ar ]]; then |
if [ -z "$ar" ]; then |
warn "Couldn't guess aspect ratio." |
ar="$w/$h" # Don't calculate it yet |
fi |
1952,7 → 1954,7 |
# Capture 5 frames and drop the first 4, fixes a weird bug/feature of mplayer ([M1]) |
|
{ |
if [[ $DVD_MODE -eq 1 ]]; then |
if [ $DVD_MODE -eq 1 ]; then |
"$MPLAYER" -sws 9 -ao null -benchmark -vo "png:z=0" -quiet \ |
-frames 5 -ss "$ts" $shoehorned -dvd-device "$f" \ |
$4 "dvd://$DVD_TITLE" |
1974,9 → 1976,9 |
local VIDCAPFILE=00000005.png |
# globals: $shoehorned $decoder |
|
if [[ $decoder -eq $DEC_MPLAYER ]]; then |
if [ $decoder -eq $DEC_MPLAYER ]; then |
capture_mplayer "$f" 'IGNOREME' "$stamp" |
elif [[ $decoder -eq $DEC_FFMPEG ]]; then |
elif [ $decoder -eq $DEC_FFMPEG ]; then |
# FIXME: ffmpeg can put the temporary file anywhere |
capture_ffmpeg "$f" "$VIDCAPFILE" "$stamp" |
else |
1983,8 → 1985,8 |
error "Internal error!" |
return $EX_SOFTWARE |
fi || true |
if [[ ( ! -f $VIDCAPFILE ) || ( '0' == "$(du "$VIDCAPFILE" | cut -f1)" ) ]]; then |
[[ $decoder -eq $DEC_MPLAYER ]] && stamp=${stamp/%.*} |
if [ ! -f "$VIDCAPFILE" ] || [ "0" == "$(du "$VIDCAPFILE" | cut -f1)" ]; then |
[ $decoder -eq $DEC_MPLAYER ] && stamp=${stamp/%.*} |
error "Failed to capture frame at $(pretty_stamp $stamp) (${stamp}s)" |
return $EX_SOFTWARE |
fi |
2030,16 → 2032,16 |
local filename=$1 timestamp=$2 width=$3 height=$4 context=$5 index=$6 |
|
local pts=$pts_tstamps |
if [[ $height -lt 200 ]]; then |
if [ $height -lt 200 ]; then |
pts=$(( $pts_tstamps / 3 )) |
elif [[ $height -lt 400 ]]; then |
elif [ $height -lt 400 ]; then |
pts=$(( $pts_tstamps * 2 / 3 )) |
fi |
# If the size is too small they won't be readable at all |
# With the original font 8 was the minimum, with DejaVu 7 is readable |
if [[ $pts -le 7 ]]; then |
if [ $pts -le 7 ]; then |
pts=7 |
if [[ ( $index -eq 1 ) && ( $context -ne $CTX_EXT ) ]]; then |
if [ $index -eq 1 ] && [ $context -ne $CTX_EXT ]; then |
warn "Very small timestamps in use. Disabling them with -dt might be preferable" |
fi |
fi |
2062,7 → 2064,7 |
# Should probably be bigger for really big frames |
# Note that only images below 21600px (e.g. 160x120) go below a 6px border |
local border=$(( ($3*$4) / 3600 )) |
[[ $border -lt 7 ]] || border=6 |
[ $border -lt 7 ] || border=6 |
echo -n "-bordercolor white -border $border -bordercolor grey60 -border 1 " |
} |
|
2080,7 → 2082,7 |
trace $@ |
# local file="$1" ts=$2 w=$3 h=$4 |
local border=$(( ($3*$4) / 3600 )) # Read filt_photoframe for details |
[[ $border -lt 7 ]] || border=6 |
[ $border -lt 7 ] || border=6 |
echo -n "-bordercolor white -mattecolor white -frame ${border}x${border} " |
# FIXME: This is rather ugly (double-flipping) there's sure a better way |
echo -n "\( -flip -splice 0x$(( $border*5 )) \) " |
2124,9 → 2126,9 |
# Repeat it until the height is reached and crop to the exact height |
local sh=$(imh "$base_reel") in= |
local repeat=$( ceilmultiply $h/$sh) |
while [[ $repeat -gt 1 ]]; do |
while [ $repeat -gt 1 ]; do |
in="$in '$base_reel' " |
(( repeat-- )); |
let 'repeat--' |
done |
eval convert "$base_reel" $in -append -crop $(imw "$base_reel")x${h}+0+0 \ |
"$reel_strip" |
2238,7 → 2240,7 |
# Step through vidcaps (col=[0..cols-1]) |
for col in $(seqr 0 $(( $cols - 1 ))); do |
# More cols than files in the last iteration (e.g. -n10 -c4) |
if [[ -z $1 ]]; then break; fi |
if [ -z "$1" ]; then break; fi |
w=$(imw "$1") |
|
# Stick the vicap in the canvas |
2300,13 → 2302,13 |
|
# This time a resize filter is applied to the player to produce smaller |
# output |
if [[ $decoder -eq $DEC_MPLAYER ]]; then |
if [ $decoder -eq $DEC_MPLAYER ]; then |
tempfile=00000005.png |
TEMPSTUFF=( "${TEMPSTUFF[@]}" "$tempfile" ) |
if ! capture_mplayer "$f" "IGNOREME" "$ts" "-vf scale=96:96"; then |
ret=1 |
fi |
elif [[ $decoder -eq $DEC_FFMPEG ]]; then |
elif [ $decoder -eq $DEC_FFMPEG ]; then |
tempfile=$(new_temp_file '-safelen.png') |
if ! capture_ffmpeg "$f" "$tempfile" "$ts" "-s 96x96"; then |
ret=1 |
2553,11 → 2555,11 |
# mplayer_identify($1 = file) |
mplayer_identify() { |
trace $@ |
[[ $MPLAYER ]] || return |
[ "$MPLAYER" ] || return |
local f="$1" |
local mi=( ) |
# Note to self: Don't change the -vc as it would affect $vdec |
if [[ $DVD_MODE -eq 0 ]]; then |
if [ $DVD_MODE -eq 0 ]; then |
MPLAYER_CACHE=$("$MPLAYER" -benchmark -ao null -vo null -identify -frames 0 \ |
-quiet "$f" 2>"$stderr" | grep ^ID) |
else |
2614,18 → 2616,18 |
# mplayer_identify($1 = file) |
ffmpeg_identify() { |
trace $@ |
[[ $FFMPEG ]] || return |
[ "$FFMPEG" ] || return |
local f="$1" |
# DVD Devices *MUST* be mounted for the identifying process to even start |
assert '[[ ( $DVD_MODE -eq 0 ) || ( $DVD_MOUNTP ) ]]' |
if [[ $DVD_MODE -eq 1 ]]; then |
assert "[ $DVD_MODE -eq 0 ] || [ '$DVD_MOUNTP' ]" |
[ $DVD_MODE -eq 1 ] && { |
local vfile="$DVD_MOUNTP/VIDEO_TS/VTS_${DVD_VTS}_0.VOB" |
if [[ ! -r $vfile ]]; then |
if [ ! -r "$vfile" ]; then |
error "Failed to locate mounted DVD. Detection will be less accurate." |
return 0 # We can continue anyway |
fi |
f="$vfile" |
fi |
} |
# XXX: FFmpeg detects mpeg1video in DVDs?? |
|
local fi=( ) vs= as= obs= vsid= |
2736,16 → 2738,16 |
trace $@ |
local RET_NOLEN=3 RET_NODIM=4 |
|
[[ $MPLAYER ]] && mplayer_identify "$1" |
[ "$MPLAYER" ] && mplayer_identify "$1" |
# ffmpeg_identify in DVD mode only works when the DVD is mounted: |
[[ ( $DVD_MODE -eq 0 ) && ( $FFMPEG ) ]] && ffmpeg_identify "$1" |
[[ ( $DVD_MODE -eq 1 ) && ( $FFMPEG ) && ( $DVD_MOUNTP ) ]] && ffmpeg_identify "$1" |
[ $DVD_MODE -eq 0 ] && [ "$FFMPEG" ] && ffmpeg_identify "$1" |
[ $DVD_MODE -eq 1 ] && [ "$FFMPEG" ] && [ "$DVD_MOUNTP" ] && ffmpeg_identify "$1" |
|
# Fail early if none detected length |
[[ ( -z ${VID_MPLAYER[$LEN]} ) && ( -z ${VID_FFMPEG[$LEN]} ) ]] && return $RET_NOLEN |
[ -z "${VID_MPLAYER[$LEN]}" ] && [ -z "${VID_FFMPEG[$LEN]}" ] && return $RET_NOLEN |
|
# Classic mode, use both mplayer and ffmpeg when available |
if [[ $MPLAYER && $FFMPEG ]]; then |
if [ "$MPLAYER" ] && [ "$FFMPEG" ]; then |
# By default take mplayer's values |
VID=("${VID_MPLAYER[@]}") |
# FFmpeg seems better at getting the correct number of FPS, specially with |
2754,8 → 2756,8 |
# uses two decimals so 23.976 becomes 23.98. So it is only used when |
# the number of decimals seems right. |
# When a "Seems..." line is printed the correct FPS can be obtained though. |
[[ -z ${VID_MPLAYER[$FPS]} ]] && VID[$FPS]=${VID_FFMPEG[$FPS]} |
[[ ( -n ${VID_MPLAYER[$FPS]} ) && ( -n ${VID_FFMPEG[$FPS]} ) ]] && { |
[ -z "${VID_MPLAYER[$FPS]}" ] && VID[$FPS]=${VID_FFMPEG[$FPS]} |
[ "${VID_MPLAYER[$FPS]}" ] && [ "${VID_FFMPEG[$FPS]}" ] && { |
# Trust ffmpeg if it has three decimals OR if mplayer is probably-wrong |
local ffps=${VID_FFMPEG[$FPS]} |
echo $ffps | grep -q '\.[0-9][0-9][0-9]' && VID[$FPS]=$ffps || { |
2763,15 → 2765,15 |
} |
} |
# It doesn't appear to need any workarounds for num. channels either |
[[ ${VID_FFMPEG[$CHANS]} ]] && VID[$CHANS]=${VID_FFMPEG[$CHANS]} |
[[ ${VID_FFMPEG[$ASPECT]} ]] && VID[$ASPECT]=${VID_FFMPEG[$ASPECT]} |
[ "${VID_FFMPEG[$CHANS]}" ] && VID[$CHANS]=${VID_FFMPEG[$CHANS]} |
[ "${VID_FFMPEG[$ASPECT]}" ] && VID[$ASPECT]=${VID_FFMPEG[$ASPECT]} |
# There's a huge inconsistency with some files, both mplayer vs ffmpeg |
# same application on different OSes |
local fflen=${VID_FFMPEG[$LEN]} mplen=${VID_MPLAYER[$LEN]} # Shorthands |
[[ -z $fflen ]] && fflen=0 |
[ -z "$fflen" ] && fflen=0 |
# If both report 0, there's no good value... |
fptest "$fflen" -eq 0 && fptest "$mplen" -eq 0 && return $RET_NOLEN |
if [[ ( $DVD_MODE -eq 0 ) && ( $QUIRKS -eq 0 ) ]]; then # In DVD mode ffmpeg has no length |
if [ $DVD_MODE -eq 0 ] && [ $QUIRKS -eq 0 ]; then # In DVD mode ffmpeg has no length |
# Quirks disabled, should be enabled? |
local delta=$(abs $(awkexf "($fflen - $mplen)")) |
# If they don't agree, take the shorter as a starting point, |
2789,19 → 2791,19 |
QUIRKS=1 |
fi |
fi |
elif [[ $MPLAYER ]]; then |
elif [ "$MPLAYER" ]; then |
# Must do with mplayer only... |
VID=("${VID_MPLAYER[@]}") |
# Warn if a known pitfall is found |
# See above for 1000 fps |
[[ ${VID[$FPS]} == '1000.00' ]] && \ |
[ "${VID[$FPS]}" == "1000.00" ] && \ |
warn "Possible inaccuracy in FPS detection." && \ |
warn " Install both mplayer and ffmpeg for better detection." |
# Number of channels 0 happened for WMA in non-x86 |
[[ ${VID[$CHANS]} == '0' ]] && \ |
[ "${VID[$CHANS]}" == "0" ] && \ |
warn "Failed to detect number of audio channels." && \ |
warn " Install both mplayer and ffmpeg for better detection." |
elif [[ $FFMPEG ]]; then |
elif [ "$FFMPEG" ]; then |
# Must do with mplayer only... |
VID=("${VID_FFMPEG[@]}") |
# So far I know of no weird results. Yet. |
2813,7 → 2815,7 |
is_float "${VID[$LEN]}" || return $RET_NOLEN |
is_number "${VID[$W]}" && is_number "${VID[$H]}" || return $RET_NODIM |
|
if [[ $FFMPEG ]]; then |
if [ "$FFMPEG" ]; then |
# FPS at least with two decimals |
if [ $(awkex "int(${VID[$FPS]})") == ${VID[$FPS]} ]; then |
VID[$FPS]="${VID[$FPS]}.00" |
2821,7 → 2823,7 |
fi |
|
local mfps="${VID_MPLAYER[$FPS]}" |
if [[ ( $QUIRKS -eq 0 ) && ( -n $MPLAYER ) ]] && fptest "$mfps" -eq 1000 ; then |
if [ $QUIRKS -eq 0 ] && [ "$MPLAYER" ] && fptest "$mfps" -eq 1000 ; then |
warn "Suspect file. Safe measuring enabled." |
QUIRKS=1 |
fi |
2828,7 → 2830,7 |
|
# Last safeguard: Try to reach the detected length, if it fails, trigger |
# quirks mode |
if [[ $QUIRKS -eq 0 ]]; then |
if [ $QUIRKS -eq 0 ]; then |
if ! probe_video "$1" "${VID[$LEN]}" ; then |
warn "Detected video length can't be reached. Safe measuring enabled." |
QUIRKS=1 |
2835,29 → 2837,29 |
fi |
fi |
|
if [[ $QUIRKS -eq 1 ]]; then |
if [ $QUIRKS -eq 1 ]; then |
VID[$LEN]=$(safe_length_measure "$1") |
if [[ -z ${VID[$LEN]} ]]; then |
if [ -z "${VID[$LEN]}" ]; then |
error "Couldn't measure length in a reasonable amount of tries." |
if [[ $INTERNAL_MAXREWIND_REACHED -eq 1 ]]; then |
if [ $INTERNAL_MAXREWIND_REACHED -eq 1 ]; then |
error " Will not be able to capture this file with the current settings." |
else |
local reqs=$(( $INTERNAL_WS_C + 1 )) reqp='' |
[[ $reqs -eq 1 ]] && reqp=" -WP" || reqp=" -WP$reqs" |
[[ $reqs -ge 3 ]] && reqs=" -WS" || { # Third try => Recommend -WS |
[[ $reqs -eq 1 ]] && reqs=" -Ws" || reqs=" -Ws$reqs" |
[ $reqs -eq 1 ] && reqp=" -WP" || reqp=" -WP$reqs" |
[ $reqs -ge 3 ] && reqs=" -WS" || { # Third try => Recommend -WS |
[ $reqs -eq 1 ] && reqs=" -Ws" || reqs=" -Ws$reqs" |
} |
assert 'fptest "$QUIRKS_MAX_REWIND" -gt 0' |
local offby=$(pretty_stamp $QUIRKS_MAX_REWIND) |
warn " Capturing won't work, video is at least $offby shorter than reported." |
local dname='ffmpeg' |
[[ $decoder -eq $DEC_MPLAYER ]] && dname='mplayer' |
[ $decoder -eq $DEC_MPLAYER ] && dname='mplayer' |
warn " Does $dname support ${VID[$VCODEC]}?." |
warn " Try re-running with$reqs$reqp." |
fi |
return 1 |
fi |
elif [[ $QUIRKS -eq -2 ]]; then |
elif [ $QUIRKS -eq -2 ]; then |
warn "Safe mode disabled." |
fi |
|
2868,9 → 2870,9 |
|
dump_idinfo() { |
trace $@ |
[[ $MPLAYER ]] && echo "Mplayer: $MPLAYER" |
[[ $FFMPEG ]] && echo "FFmpeg: $FFMPEG" |
[[ $MPLAYER ]] && cat <<-EODUMP |
[ "$MPLAYER" ] && echo "Mplayer: $MPLAYER" |
[ "$FFMPEG" ] && echo "FFmpeg: $FFMPEG" |
[ "$MPLAYER" ] && cat <<-EODUMP |
=========== Mplayer Identification =========== |
Length: $(pretty_stamp ${VID_MPLAYER[$LEN]}) |
Video |
2885,11 → 2887,11 |
|
EODUMP |
local ffl="${VID_FFMPEG[$LEN]}" |
[[ $ffl ]] && ffl=$(pretty_stamp "$ffl") |
if [[ ( -z $ffl ) && ( $DVD_MODE -eq 1 ) ]]; then |
[ "$ffl" ] && ffl=$(pretty_stamp "$ffl") |
if [ -z "$ffl" -a $DVD_MODE -eq 1 ]; then |
ffl="(unavailable in DVD mode)" |
fi |
[[ $FFMPEG ]] && cat <<-EODUMP |
[ "$FFMPEG" ] && cat <<-EODUMP |
=========== FFmpeg Identification =========== |
Length: $ffl |
Video |
2904,9 → 2906,9 |
|
EODUMP |
local xar= |
if [[ ${VID[$ASPECT]} ]]; then |
if [ "${VID[$ASPECT]}" ]; then |
xar=$(keepdecimals "${VID[$ASPECT]}" 4) |
[[ $xar ]] && xar=" ($xar)" |
[ "$xar" ] && xar=" ($xar)" |
fi |
cat <<-EODUMP |
=========== Combined Identification =========== |
2922,6 → 2924,7 |
============================================= |
EODUMP |
|
|
} |
|
# Try to pick some font capable of handling non-latin text |
2930,11 → 2933,11 |
# This selection includes japanese fonts |
local candidates=$(identify -list font | grep 'Font: ' | \ |
egrep -io '[a-z-]*(kochi|mincho|sazanami|ipafont)[a-z-]*') |
if [[ -z $candidates ]]; then |
if [ -z "$candidates" ]; then |
error "Unable to auto-select filename font, please provide one (see -fullhelp)" |
return 1 |
else |
if [[ $DEBUG -eq 1 ]]; then |
if [ "$DEBUG" -eq 1 ]; then |
local list=$(echo "$candidates" | sed 's/^/ >/g') |
inf "Available non-latin fonts detected:$NL$list" |
fi |
2954,7 → 2957,7 |
coherence_check() { |
trace $@ |
# If -m is used then -S must be used |
if [[ ( $manual_mode -eq 1 ) && ( -z $initial_stamps ) ]]; then |
if [ $manual_mode -eq 1 ] && [ -z $initial_stamps ]; then |
error "You must provide timestamps (-S) when using manual mode (-m)" |
return $EX_USAGE |
fi |
2964,22 → 2967,22 |
extended_factor=0 |
fi |
|
if [[ ( $decoder -eq $DEC_MPLAYER ) && ( -z $MPLAYER ) ]]; then |
if [ $decoder -eq $DEC_MPLAYER ] && [ -z "$MPLAYER" ]; then |
inf "No mplayer available. Using ffmpeg only." |
decoder=$DEC_FFMPEG |
elif [[ ( $decoder -eq $DEC_FFMPEG ) && ( -z $FFMPEG ) ]]; then |
elif [ $decoder -eq $DEC_FFMPEG ] && [ -z "$FFMPEG" ]; then |
inf "No ffmpeg available. Using mplayer only." |
decoder=$DEC_MPLAYER |
fi |
|
if [[ $DVD_MODE -eq 1 ]]; then |
if [ $DVD_MODE -eq 1 ]; then |
# Since 1.12 DVD mode can work with multiple inputs too |
|
# DVD Mode only works with mplayer, the decoder is changed when |
# the DVD mode option is found, so if it's ffmpeg at this point, |
# it's by user request (i.e. -F after -V) |
if [[ $decoder -ne $DEC_MPLAYER ]]; then |
if [[ $MPLAYER ]]; then |
if [ $decoder -ne $DEC_MPLAYER ]; then |
if [ "$MPLAYER" ]; then |
warn "DVD mode requires the use of mplayer, falling back to it" |
decoder=$DEC_MPLAYER |
else |
2990,14 → 2993,14 |
fi |
|
local filter= |
local -a filts=( ) |
if [[ $DISABLE_TIMESTAMPS -eq 0 ]] && |
if [ $DISABLE_TIMESTAMPS -eq 0 ] && |
local -a filts=( ) |
has_filter filt_polaroid && has_filter filt_apply_stamp ; then |
|
for filter in ${FILTERS_IND[@]} ; do |
if [[ $filter == 'filt_polaroid' ]]; then |
if [ "$filter" == "filt_polaroid" ]; then |
filts=( "${filts[@]}" "$filter" filt_apply_stamp ) |
elif [[ $filter == 'filt_apply_stamp' ]]; then |
elif [ "$filter" == "filt_apply_stamp" ]; then |
continue; |
else |
filts=( "${filts[@]}" $filter ) |
3018,12 → 3021,12 |
# differently. On previous versions disabling shadows only affected |
# the montage shadow (but e.g. the polaroid mode preserved them), |
# this is no longer true |
if [[ $DISABLE_SHADOWS -ne 1 ]]; then |
if [ $DISABLE_SHADOWS -ne 1 ]; then |
end_filts[100]="filt_softshadow" |
fi |
;; |
filt_apply_stamp) |
if [[ $DISABLE_TIMESTAMPS -ne 1 ]]; then |
if [ $DISABLE_TIMESTAMPS -ne 1 ]; then |
filts=( "${filts[@]}" "$filter" ) |
fi |
;; |
3038,7 → 3041,7 |
|
# If in non-latin mode and no nonlatin font has been picked try to pick one. |
# Should it fail, fallback to latin font. |
if [[ ( $NONLATIN_FILENAMES -eq 1 ) && ( -z $FONT_MINCHO ) ]]; then |
if [ $NONLATIN_FILENAMES -eq 1 ] && [ -z "$FONT_MINCHO" ]; then |
set_extended_font || { |
# set_extended_font already warns about lack of fonts |
warn " Falling back to latin font" |
3057,32 → 3060,31 |
trace $@ |
|
# Any default font in use? If all of them are overridden, return |
if [[ $USR_font_heading && $USR_font_title && \ |
$USR_font_tstamps && $USR_font_sign ]]; then |
if [ "$USR_font_heading" -a "$USR_font_title" -a "$USR_font_tstamps" -a "$USR_font_sign" ]; then |
return |
fi |
# If the user edits any font in the script, stop messing with this |
[[ ( -z $USR_font_heading ) && ( $font_heading != 'DejaVu-Sans-Book' ) ]] && return |
[[ ( -z $USR_font_title ) && ( $font_title != 'DejaVu-Sans-Book' ) ]] && return |
[[ ( -z $USR_font_tstamps ) && ( $font_tstamps != 'DejaVu-Sans-Book' ) ]] && return |
[[ ( -z $USR_font_sign ) && ( $font_sign != 'DejaVu-Sans-Book' ) ]] && return |
[ -z "$USR_font_heading" ] && [ "$font_heading" != 'DejaVu-Sans-Book' ] && return |
[ -z "$USR_font_title" ] && [ "$font_title" != 'DejaVu-Sans-Book' ] && return |
[ -z "$USR_font_tstamps" ] && [ "$font_tstamps" != 'DejaVu-Sans-Book' ] && return |
[ -z "$USR_font_sign" ] && [ "$font_sign" != 'DejaVu-Sans-Book' ] && return |
# Try to locate DejaVu Sans |
local dvs='' |
if [[ -d /usr/local/share/fonts ]]; then |
if [ -d /usr/local/share/fonts ]; then |
dvs=$(find /usr/local/share/fonts/ -type f -iname 'dejavusans.ttf') |
fi |
if [[ ( -z $dvs ) && ( -d /usr/share/fonts ) ]]; then |
if [ -z "$dvs" -a -d /usr/share/fonts ]; then |
dvs=$(find /usr/share/fonts/ -type f -iname 'dejavusans.ttf') |
fi |
if [[ -z $dvs ]]; then |
if [ -z "$dvs" ]; then |
warn "Unable to locate DejaVu Sans font. Falling back to helvetica." |
dvs=helvetica |
fi |
[[ -z $USR_font_heading ]] && font_heading="$dvs" |
[[ -z $USR_font_title ]] && font_title="$dvs" |
[[ -z $USR_font_tstamps ]] && font_tstamps="$dvs" |
[[ -z $USR_font_sign ]] && font_sign="$dvs" |
[[ $DEBUG -eq 1 ]] || { return 0; } |
[ -z "$USR_font_heading" ] && font_heading="$dvs" |
[ -z "$USR_font_title" ] && font_title="$dvs" |
[ -z "$USR_font_tstamps" ] && font_tstamps="$dvs" |
[ -z "$USR_font_sign" ] && font_sign="$dvs" |
[ $DEBUG -eq 1 ] || { return 0; } |
cat >&2 <<-EOFF |
Font Sanitation: |
font_heading: $font_heading |
3108,7 → 3110,7 |
INTERNAL_MAXREWIND_REACHED=0 # Reset for each file |
|
DVD_MOUNTP= DVD_TITLE= # Re-set for each file |
if [[ $DVD_MODE -eq 1 ]]; then |
if [ $DVD_MODE -eq 1 ]; then |
local dvdn=$(realpathr "$f") |
# Is it an ISO? |
if [[ -f $dvdn ]]; then |
3132,7 → 3134,7 |
DVD_MOUNTP=$(mount | grep -o "^$dvdn *on [^ ]*" | cut -d' ' -f3) |
dvdn="DVD $f" |
fi |
if [[ ! -r $f ]]; then |
if [ ! -r "$f" ]; then |
error "Can't access DVD ($f)" |
return $EX_NOINPUT |
fi |
3141,7 → 3143,7 |
unset dvdn |
DVD_TITLE=${DVD_TITLES[0]} |
DVD_TITLES=( "${DVD_TITLES[@]:1}" ) # shift array |
if [[ ( -z $DVD_TITLE ) || ( $DVD_TITLE == '0' ) ]]; then |
if [ -z "$DVD_TITLE" -o "$DVD_TITLE" == "0" ]; then |
local dt="$(lsdvd "$f" 2>/dev/null | grep 'Longest track:' | \ |
cut -d' ' -f3- | sed 's/^0*//')" |
if ! is_number "$dt" ; then |
3154,7 → 3156,7 |
DVD_VTS=$(lsdvd -t$DVD_TITLE -v "$f" 2>/dev/null | grep -o 'VTS: [0-9]*' | cut -d' ' -f2) |
inf "Using DVD Title #$DVD_TITLE (VTS: $DVD_VTS) for '$f'" |
else # Not DVD Mode: |
if [[ ! -f $f ]]; then |
if [ ! -f "$f" ]; then |
error "File \"$f\" doesn't exist" |
return $EX_NOINPUT |
fi |
3166,7 → 3168,7 |
# {{SET_E}} Beware, set -e will break this |
identify_video "$f" |
local ecode=$? |
[[ $ecode -eq 0 ]] || { |
[ $ecode -eq 0 ] || { |
case $ecode in |
3) error "Unable to find length of file \"$f\". Can't continue." ;; |
4) error "Unable to detect dimensions of file \"$f\". Can't continue." ;; |
3176,7 → 3178,7 |
} |
|
# Identification-only mode? |
[[ $UNDFLAG_IDONLY ]] && dump_idinfo && return 0 |
[ "$UNDFLAG_IDONLY" ] && dump_idinfo && return 0 |
|
# Vidcap/Thumbnail height |
local vidcap_height=$th_height |
3291,12 → 3293,12 |
capfile=$(new_temp_file "-cap-$(pad 6 $n).png") |
mvq "$VIDCAPFILE" "$capfile" |
capfiles=( "${capfiles[@]}" "$capfile" ) |
(( n++ )) |
let 'n++' # $n++ |
done |
#filter_all_vidcaps "${capfiles[@]}" |
|
(( n-- )) # there's an extra inc |
if [[ $n -lt $cols ]]; then |
let 'n--' # there's an extra inc |
if [ "$n" -lt "$cols" ]; then |
numcols=$n |
else |
numcols=$cols |
3308,7 → 3310,7 |
|
# Extended mode |
local extoutput= |
if [[ $extended_factor != 0 ]]; then |
if [ "$extended_factor" != 0 ]; then |
# Number of captures. Always rounded to a multiplier of *double* the |
# number of columns (the extended caps are half width, this way they |
# match approx with the standard caps width) |
3552,18 → 3554,16 |
unset signature meta2 headwidth headheight heading fn_font signheight signlh |
|
local wanted_name=${OUTPUT_FILES[$FILEIDX]} |
if [[ -n $wanted_name ]]; then |
local ERE='\.[^.]+$' |
if [[ $wanted_name =~ $ERE ]]; then |
[[ -n $wanted_name ]] && \ |
if egrep -q '\.[^\.]+$' <<<"$wanted_name" ; then |
output_format=$(filext "$wanted_name") |
inf "Output format set from output filename" |
else # No file extension in wanted_name |
wanted_name="$wanted_name.$output_format" |
fi |
fi |
[[ -n $wanted_name ]] || wanted_name="$(basename "$f").$output_format" |
|
if [[ $output_format != 'png' ]]; then |
if [ $output_format != "png" ]; then |
local newout="$(dirname "$output")/$(basename "$output" .png).$output_format" |
convert -quality $output_quality "$output" "$newout" |
output="$newout" |
3575,7 → 3575,7 |
} |
inf "Done. Output wrote to $output_name" |
|
(( FILEIDX++ ,1 )) #,1 so that it's always ok |
let 'FILEIDX++,1' #,1 so that it's always ok |
[[ $UNDFLAG_HANG ]] && read -p 'Main loop paused, hit Enter key to continue... ' |
cleanup |
|
3600,18 → 3600,18 |
local SEQ=$(type -pf seq) |
local JOT=$(type -pf jot) |
local ex rex |
if [[ $SEQ ]]; then |
if [ "$SEQ" ]; then |
ex=$($SEQ 1 10) |
elif [[ $JOT ]]; then |
elif [ "$JOT" ]; then |
ex=$($JOT 10 1) |
else |
warn "Can't check seqr() correctness, neither seq nor jot found" |
fi |
if [[ $ex ]]; then |
if [ "$ex" ]; then |
exr=$(seqr 1 10) |
if [[ $exr != "$ex" ]]; then |
if [ "$exr" != "$ex" ]; then |
error "Failed test: seqr() not consistent with external result" |
(( retval++ ,1 )) |
let 'retval++,1' |
else |
inf "Passed test (seq replacement): consistent result" |
fi |
3668,14 → 3668,14 |
# Expected value |
val=$(grep -o "[^ ]* #$comm\$"<<<$t | cut -d' ' -f1) |
op=$(sed "s! $val #$comm\$!!g" <<<$t) |
if [[ -z $comm ]]; then |
if [ -z "$comm" ]; then |
comm=unnamed |
fi |
ret=$($op) || true |
|
if [[ $ret != "$val" ]] && fptest "$ret" -ne "$val" ; then |
if [ "$ret" != "$val" ] && fptest "$ret" -ne "$val" ; then |
error "Failed test ($comm): '$op $val'. Got result '$ret'." |
(( retval++ ,1 )) # The ,1 ensures '((...))' doesn't fail |
let 'retval++,1' # The ,1 ensures let doesn't fail |
else |
inf "Passed test ($comm): '$op $val'." |
fi |
3714,17 → 3714,19 |
# Expected value |
val=$(grep -o "[^ ]* #$comm\$"<<<$t | cut -d' ' -f1) |
op=$(sed "s! $val #$comm\$!!g" <<<$t) |
[[ -n $comm ]] || comm=unnamed |
if [ -z "$comm" ]; then |
comm=unnamed |
fi |
ret=0 |
$op || { |
ret=$? |
} |
|
if [[ $val -eq $ret ]]; then |
if [ $val -eq $ret ]; then |
inf "Passed test ($comm): '$op; returns $val'." |
else |
error "Failed test ($comm): '$op; returns $val'. Returned '$ret'" |
(( retval++ ,1 )) |
let 'retval++,1' |
fi |
done |
|
3739,7 → 3741,7 |
# Prints the program identification to stderr |
show_vcs_info() { # Won't be printed in quiet modes |
local inff=inf |
[[ $HAS_COLORS ]] || inff=infplain |
[ "$HAS_COLORS" ] && inff=infplain |
$inff "Video Contact Sheet *NIX v${VERSION}, (c) 2007-2010 Toni Corvera" |
} |
|
3749,12 → 3751,12 |
local P=$(basename $0) |
local showlong=$1 |
local mpchosen= ffchosen= longhelp= funkyex= |
[[ -z $MPLAYER ]] && mpchosen=' [Not available]' |
[[ $MPLAYER ]] && [[ $decoder == $DEC_MPLAYER ]] && mpchosen=' [Selected]' |
[[ -z $FFMPEG ]] && ffchosen=', Not available' |
[[ $FFMPEG ]] && [[ $decoder == $DEC_FFMPEG ]] && ffchosen=', Selected' |
[ -z "$MPLAYER" ] && mpchosen=' [Not available]' |
[ "$MPLAYER" ] && [ $decoder == $DEC_MPLAYER ] && mpchosen=' [Selected]' |
[ -z "$FFMPEG" ] && ffchosen=', Not available' |
[ "$FFMPEG" ] && [ $decoder == $DEC_FFMPEG ] && ffchosen=', Selected' |
# This portion of help is only shown when in full help mode (--fullhelp) |
[[ $showlong ]] && longhelp=\ |
[ "$showlong" ] && longhelp=\ |
" --anonymous Disable the 'Preview created by' line in the footer. |
-Ij|-Ik|-Ij=fontname|-Ik=fontname |
--nonlatin Use an alternate font in the heading for the video file |
3796,7 → 3798,7 |
" |
# The --funky help is really long, so make it shorter by default, |
# only show the complete help when --fullhelp is used |
[[ $showlong ]] && funkyex=" |
[ "$showlong" ] && funkyex=" |
These are toy output modes in which the contact sheet |
gets a more informal look. |
Order *IS IMPORTANT*. A bad order gets a bad result :P |
3822,7 → 3824,7 |
Imitates filmstrip look. |
\"random\": Use '-kx' or '--funky random' |
Randomizes colours and fonts." |
[[ -z $showlong ]] && funkyex=" |
[ -z "$showlong" ] && funkyex=" |
Available: overlap, rotate, photoframe, polaroidframe, |
photos, polaroid, film, random |
Use --fullhelp for more details." |
3943,9 → 3945,9 |
while read ovname ; do |
f=${ovname/:*} |
t=${ovname#*:} |
if [[ ( -z $t ) || ( $t == '=' ) ]]; then t=$f ; fi |
if [ -z "$t" ] || [ "$t" == "=" ]; then t=$f ; fi |
eval v=\$USR_$t |
[[ -z $v ]] || { |
[ -z "$v" ] || { |
# Symbolic values: |
case "$t" in |
timecode_from) |
4054,7 → 4056,7 |
shift |
else # No argument, default handling (try to guess real name) |
user=$(grep ^$(id -un): /etc/passwd | cut -d':' -f5 |sed 's/,.*//g') |
if [[ -z $user ]]; then |
if [ -z "$user" ]; then |
user=$(id -un) |
error "No fullname found, falling back to default ($user)" |
fi |
4196,7 → 4198,7 |
# which convert would understand without giving the full path |
NONLATIN_FILENAMES=1 |
USR_NONLATIN_FILENAMES=1 |
if [[ ${#2} -gt 1 ]]; then |
if [ ${#2} -gt 1 ]; then |
# j=, k= syntax |
FONT_MINCHO="${2:2}" |
USR_FONT_MINCHO="$FONT_MINCHO" |
4203,7 → 4205,7 |
inf "Filename font set to '$FONT_MINCHO'" |
fi |
# If the user didn't pick one, try to select automatically |
if [[ -z $USR_FONT_MINCHO ]]; then |
if [ -z "$USR_FONT_MINCHO" ]; then |
set_extended_font |
inf "Filename font set to '$FONT_MINCHO'" |
fi |
4253,7 → 4255,7 |
# Increase precission of safe length measuring (halve the stepping) |
# Like -Ws can be repeated |
p|p[0-9]|p[0-9][0-9]) |
[[ ${#2} -gt 1 ]] && n=${2:1} || n=1 |
[ ${#2} -gt 1 ] && n=${2:1} || n=1 |
QUIRKS_LEN_STEP=$(awkexf "$QUIRKS_LEN_STEP / (2^$n)") |
(( INTERNAL_WP_C+=n ,1 )) |
;; |
4262,7 → 4264,7 |
# desirable when -Ws or -WS are used. |
# Can also be repeated |
P|P[0-9]|P[0-9][0-9]) |
[[ ${#2} -gt 1 ]] && n=${2:1} || n=1 |
[ ${#2} -gt 1 ] && n=${2:1} || n=1 |
QUIRKS_LEN_STEP=$(awkexf "$QUIRKS_LEN_STEP * (2^$n)") |
(( INTERNAL_WP_C-=n ,1 )) |
;; |
4496,9 → 4498,9 |
while read ovname ; do |
f=${ovname/:*} |
t=${ovname#*:} |
if [[ ( $t ) && ( $t != '=' ) ]]; then f="$t" ; fi |
if [ "$t" -a "$t" != "=" ]; then f="$t" ; fi |
eval v=\$USR_$f |
[[ -z $v ]] || echo "$(tolower $f)=$v" |
[ -z "$v" ] || echo "$(tolower $f)=$v" |
done |
exit 0 |
;; |
4607,8 → 4609,6 |
# * bash2: [*] expands as a string while [@] expands as an array. Both have trouble with spaces |
# in elements though |
# * bash3: |& (inherited from csh?) pipes both stdout and stderr |
# * bash3: [[ STR =~ EREGEX ]] is faster than grep/egrep (no forking) |
# bash 3.2 changed semantics vs bash 3.1 |
# * performance: bash loops are often slower than awk or perl |
# * performance: grep + cut proved faster than an equivalent sed -r s// replacement |
# }}} # Bash syntax notes |