tangetools/vid/vid

159 lines
3.6 KiB
Bash
Executable file

#!/bin/bash
: <<=cut
=pod
=head1 NAME
vid - Play videos matching strings in descending order of size
=head1 SYNOPSIS
B<vid> [[grep options][string]]...
=head1 DESCRIPTION
B<vid> recursively searches for videos and sort them by size. It then
filters out the names matching all the B<grep> expressions.
There can be multiple B<grep> expressions.
The searching is cached in B<.vidlist> in a parent dir or in the
current dir if no parents contain B<.vidlist>.
=head1 EXAMPLE
Play videos matching B<Documentary> but not B<BBC>:
vid Documentary -v BBC
=head1 AUTHOR
Copyright (C) 2018-2019 Ole Tange,
http://ole.tange.dk and Free Software Foundation, Inc.
=head1 LICENSE
Copyright (C) 2012 Free Software Foundation, Inc.
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 of the License, 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 <http://www.gnu.org/licenses/>.
=head1 DEPENDENCIES
B<vid> uses B<G>.
=head1 SEE ALSO
B<G>
=cut
ulimit -u `ulimit -Hu`
find_find_vidlist() {
# find_find_vidlist(start_dir)
# Find the file .vidlist in . .. ../.. ../../.. etc
# If not found: ./.vidlist
dir="$1"
if [ -f "$1"/.vidlist ] ; then
echo "$1"/.vidlist
return 0
else
if [ "/" == $(readlink -f "$dir") ] ; then
echo ./.vidlist
return 0
fi
find_find_vidlist "../$dir"
return $?
fi
}
update_list() {
# update_list(vidlist_file, full_path_vidlist_dir)
# Update vidlist
# Update .vidlist with content from full_path_vidlist_dir
vidlist="$1"
full_path_vidlist_dir="$2"
# Subshell to ignore 'cd'
(cd "$full_path_vidlist_dir" &&
# Find video files, print them with size prepended
ionice -c 3 find . -iregex \
'.*\(webm\|rm\|mkv\|mov\|mpg\|mpeg\|asf\|avi\|wmv\|flv\|mp4\|3gp\)$' \
-type f -printf '%s\t%p\n' ||
# If ionice -c 3 fails, try without
find . -iregex \
'.*\(webm\|rm\|mkv\|mov\|mpg\|mpeg\|asf\|avi\|wmv\|flv\|mp4\|3gp\)$' \
-type f -printf '%s\t%p\n') |
# Sort by size
sort -rn |
# Uniq
uniq |
# Remove size column
perl -pe 's/^\S+\t//' > "$vidlist".$$
# Replace old vidlist with new
mv "$vidlist".$$ "$vidlist"
}
cat_list() {
# cat the vidlist for file names in current dir
vidlist="$(find_find_vidlist .)"
full_path_vidlist_dir="$(dirname $(readlink -f "$vidlist") )"
full_path_thisdir="$(readlink -f .)"
if [ -f "$vidlist" ] ; then
# find background (>/dev/null to detach from tty)
update_list "$vidlist" "$full_path_vidlist_dir" >/dev/null &
else
# find foreground
update_list "$vidlist" "$full_path_vidlist_dir"
fi
subdir="$(echo "$full_path_thisdir" |
perl -pe 's|\Q'"$full_path_vidlist_dir"'\E|.|')/"
# cat "$vidlist" | grep matching this dir + remove dirs
# echo "$vidlist" "$full_path_thisdir" "$full_path_vidlist_dir" = "$subdir" >&2
cat "$vidlist" |
perl -ne 's|^(\./)?\Q'"$subdir"'\E|| and print'
}
stdin() {
if tty -s ; then
# STDIN is terminal
cat_list
else
# STDIN redir'ed - read it
cat
fi
}
stdout() {
if [ -t 1 ] ; then
# STDOUT = terminal
# start $VIDEOPLAYER
VIDEOPLAYER=${VIDEOPLAYER:-vlc --}
shuf | parallel --halt now,done=1 --lb -n100 -Xj1 $VIDEOPLAYER
else
cat
fi
}
stdin | G "$@" | stdout
exit $?