This is a DVD bookmarking attempt for VLC.
Warning: these scripts are nothing more than a proof of concept. Bookmarking
DVDs by title and playing time is unreliable; the correct way would be to save
the state of the DVD engine directly, as the ogle DVD player does. If this can
be done in lua (or at all), somebody should do it. The standard bookmarking
interface of VLC (including the srpos plugin) is inadequate for DVD playback;
we need a separate interface. I'm sure I'm not the only one who wants this
functionality, so please help.
A script to start vlc with fifo input, cli interface and logfile output:
Code:
#!/bin/bash -x
# dvdplayer script using VLC with resume function
# work in progress
# Make a backup copy of your ~/.config/vlc folder. It WILL get corrupted.
# Media folder:
MEDIADIR="$HOME/vlc_data"
if [ ! -d $MEDIADIR ]; then
mkdir -p $MEDIADIR
fi
# Bookmark folder:
BMDIR="$MEDIADIR/bookmarks"
if [ ! -d $BMDIR ]; then
mkdir -p $BMDIR
fi
# Control file (fifo):
if [ ! -p "$MEDIADIR/fifo" ]; then
rm -rf $MEDIADIR/fifo
mkfifo $MEDIADIR/fifo
fi
#DVD device (this is a DVD player only!):
if [ "$1" ]; then
# Drag an iso file or VIDEO_TS folder to the terminal (takes only one
# argument; the $* is for handling filenames with spaces):
DVD_DEVICE="$(echo "$*" | sed "s/^'\|'$//g")"
else
#will find external drive if present:
DVD_DEVICE="$(cat /etc/mtab | grep udf | awk '{print $1}')"
fi
# In the following, disc_id is a program from libdvdread-0.9.7 compiled as an
# executable (./configure --disable-shared --disable-static => make => do not
# install, copy files manually to /usr/local/bin). Alternatively, we might use
# the following shell script, which (mostly) replicates the function of disc_id:
##!/bin/bash
##DVD disc_id
##(almost) a replacement for disc_id of libdvdread-0.9.7
##iso images must be mounted first, so we need fusermount and fuseiso
##On some DVDs the playing order will differ from the sorting order of
##the titlesets; then the output of this script, which does not use
##dvdnav, will differ from disc_id; it should be unique though
#TEMP=`basename $0`
#TMPFILE=`mktemp -q /tmp/${TEMP}.XXXXXXXX`
#if [[ "$(echo `file "$1" | cut -d : -f 2 | grep UDF`)" ]]; then
#TMPDIR=`mktemp -d -q /tmp/${TEMP}.mnt.XXXXXXXX`
#fuseiso -p "$1" "$TMPDIR"
#DISC=$TMPDIR
#else
#DISC="$1"
#fi
#for ifo in `find ${DISC}/* -iname *ifo`; do
#cat $ifo >> $TMPFILE 2>/dev/null
#done
#md5sum $TMPFILE | cut -d \ -f 1
#rm $TMPFILE
#if [[ "$(echo `file "$1" | cut -d : -f 2 | grep UDF`)" ]]; then
#fusermount -u "$TMPDIR"
#fi
# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. The logfile is needed for
# reading command output into variables, unfortunately):
(tail -f $MEDIADIR/fifo | nohup 2>&1 vlc -vv --one-instance --extraintf lua > $MEDIADIR/logfile &) && \
sleep 2
echo "add dvd://$DVD_DEVICE" > $MEDIADIR/fifo
# Inventing extensions for the bookmark and resume files.
# Later we might invent corresponding mimetypes:
touch ${BMDIR}/$(disc_id "${DVD_DEVICE}").vbmk
BOOKMARKFILE="${BMDIR}/$(disc_id "${DVD_DEVICE}")".vbmk
touch ${BMDIR}/$(disc_id "${DVD_DEVICE}").resume
RESUMEFILE="${BMDIR}/$(disc_id "${DVD_DEVICE}")".resume
touch ${BMDIR}/$(disc_id "${DVD_DEVICE}").default
DEFAULTFILE="${BMDIR}/$(disc_id "${DVD_DEVICE}")".default
# Helpful but optional information for editing the data files manually:
DISK_LABEL=`cat $MEDIADIR/logfile | grep 'DVD Title:' | tail -n 1 | cut -d \ -f 4`
if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi
rm -f $MEDIADIR/datafiles
for data in DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval echo $data=\$"$data" >> $MEDIADIR/datafiles
done
# Calling the external resume script. Replace the <placeholder> with the path to
# the script. Issuing the resume commands from within this script did not work.
if [[ -s "$RESUMEFILE" ]]; then
<bookmarkscript> -r
fi
A bookmarking and resuming script (seems to work better as a separate script).
Not finished yet, so the help section is mainly a wish list, but the nontrivial
stuff is already there:
Code:
#!/bin/bash -x
# Bookmark script for use with the dvdplayer script.
# work in progress
# Media folder:
MEDIADIR="$HOME/vlc_data"
if [ ! -d $MEDIADIR ]; then
mkdir -p $MEDIADIR
fi
# Bookmark folder:
BMDIR="$MEDIADIR/bookmarks"
if [ ! -d $BMDIR ]; then
mkdir -p $BMDIR
fi
# Control file (fifo):
#if [ ! -p "$MEDIADIR/fifo" ]; then
#rm -rf $MEDIADIR/fifo
#mkfifo $MEDIADIR/fifo
#fi
# We need a file $MEDIADIR/datafiles to store variables; we cannot write to the
# logfile directly: it will get corrupted
for data in DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval "$data"=`cat $MEDIADIR/datafiles | grep "$data" | cut -d = -f 2`
done
# Functions:
get_var () {
#valid arguments: title get_time chapter (chapter is unreliable though)
#takes only one argument; the for loop is a relic from mplayer, which writes
#additional parsing information into the logfile (But see cli.lua edit below)
for i in "$@"; do
echo "$i" > $MEDIADIR/fifo
sleep 1
#FIXME: the following parsing code needs some attention:
eval "$i"="$(cat $MEDIADIR/logfile | grep -G [[:digit:]] | grep -v '\[' | tail -n 1 | sed "s/[^[:digit:]]//g")"
done
}
get_resume () {
for j in "$@"; do
eval "$j"=`cat $RESUMEFILE | grep "$j" | cut -d = -f 2`
done
}
set_resume () {
for k in "$@"; do
eval echo "$k"=\$"$k" >> $RESUMEFILE
done
}
#get_chapter () {
# not needed for bookmarking, but more reliable for getting the current chapter
# this parses dvdnav debug info, hence the -vv. I should NOT have to do this!
#cat $MEDIADIR/logfile | grep pgN | tail -n 1 | cut -d \= -f 2
#}
#set_bookmark () {
#echo "$1"="$2" >> $BOOKMARKFILE
#}
vlc_command () {
echo "$*" > $MEDIADIR/fifo
}
#TERMINAL=$COLORTERM
case $1 in
-h|--help)
cat << EOF
"`basename $0`" is a bookmarking and resuming script for VLC. It is intended for use with the dvdplayer script. Call it with Alt+F2 while VLC (started with the dvdplayer script) is running or assign a shortcut to it.
Usage:
`basename $0` without arguments will create a resume bookmark and close VLC. The previous resume bookmark will be overwritten.
`basename $0` -l will open a terminal window and list your bookmarks in a select menu; choose one by number.
`basename $0` -c will open a terminal window and prompt for the name of a new bookmark to be created at the current position. If the name is "Start", it will be used as default startup bookmark. An existing bookmark with the chosen name will be overwritten.
`basename $0` -d will open a terminal window and list your bookmarks in a select menu; choose one to delete. Can also be done by opening the bookmark file in an editor, of course.
`basename $0` -D will start playback from the default bookmark, if present.
`basename $0` -r will start playback from the resume bookmark, if present.
EOF
exit
;;
-l|--list)
#TODO
;;
-c|--create)
#TODO
;;
-d|--delete)
#TODO
;;
-D|--default)
#TODO
;;
-r|--resume)
vlc_command title
get_resume title
vlc_command get_time
get_resume get_time
vlc_command title $title
vlc_command seek $get_time
;;
*)
rm -f $RESUMEFILE
get_var title
set_resume title
get_var get_time
set_resume get_time
vlc_command quit
;;
esac
A script to enter vlc commands in fullscreen (via ALT+F2):
Code:
#!/bin/sh
echo "$*" > $HOME/vlc_data/fifo
These scripts seem to work in their present form, but they have many issues:
1. If you think they have a rather mplayery feel to them, you are right; they
were originally intended for mplayer. But mplayer is practically dead, and does
not work correctly any more (and I don't like mpv any better). VLC has much the
same commandline functionality, but it does not seem any more adequate for DVD
playback than mplayer's commandline interface.
2. It is not possible to bookmark the main menu, because there is no title
associated with it. The keyboard shortcut always goes back to the language
menu, if present, and then we have go back through all the nag screens to get
back to the movie. There should be separate keyboard shortcuts for the various
menu levels (or at least the shortcut should find its way back to the menu where
it came from).
3. Bookmarking DVDs by title and time is actually contrary to how DVDs work. I
include an ogle bookmark (which saves the actual state of the DVD engine) as
an example of how it should be done (of course this needs a programmer who
knows what {s,}he is doing, not little me).
A bookmark file of the ogle DVD player with a user created bookmark and the
automatically created resume bookmark:
Code:
<?xml version="1.0"?>
<ogle_bookmarks dvddiscid="4eb3f6d726aee4eb47fe8a22991ca074">
<disccomment>EAT_PRAY_LOVE</disccomment>
<bookmark>
<navstate version="0.0.0">
<sprm>,656e,0,0,1,1,1,1,1,c00,0,0,0,5553,f,c00,0,656e,0,656e,0,2,0,0,0</sprm>
<gprm>,65,0,0,0,65,40,1,3e7,1,1,65,0,0,0,0,1</gprm>
<domain>3</domain>
<vts>1</vts>
<pgc>1</pgc>
<pg>1</pg>
<cell>1</cell>
<block>6930</block>
<mode>1</mode>
<rsmvts>4</rsmvts>
<rsmpgc>29</rsmpgc>
<rsmcell>1</rsmcell>
<rsmblock>0</rsmblock>
<rsmregs>,7fff,0,b010,196,0</rsmregs>
</navstate>
</bookmark>
<bookmark>
<navstate version="0.0.0">
<sprm>,656e,0,0,1,1,1,1,8,c00,0,0,0,5553,f,c00,0,656e,0,656e,0,2,0,0,0</sprm>
<gprm>,65,0,0,0,65,40,1,3e7,1,1,65,0,0,0,0,1</gprm>
<domain>3</domain>
<vts>1</vts>
<pgc>1</pgc>
<pg>8</pg>
<cell>19</cell>
<block>14726</block>
<mode>1</mode>
<rsmvts>4</rsmvts>
<rsmpgc>29</rsmpgc>
<rsmcell>1</rsmcell>
<rsmblock>0</rsmblock>
<rsmregs>,7fff,0,9010,7d,0</rsmregs>
</navstate>
<appinfo appname="common">autobookmark</appinfo>
</bookmark>
</ogle_bookmarks>
The information contained in this bookmark seems to be present in the output
of VLC's logfile - the question is, can I feed it back into VLC? If possible,
by using an existing interface, not by scraping it off the logfile?
If this can be implemented in VLC, would somebody please do it? (Or if it is
already implemented, would somebody please ***DOCUMENT*** it? The documentation
admits to being outdated).
4. Unencrypted bookmarks might be a privacy issue. It should be possible to
encrypt the DVD bookmarks using the dvdnav disc id as an encryption key, so
they cannot possibly be read without the media file (DVD, iso or VIDEO_TS
folder). Of course that's not the problem right now; first DVD bookmarking
would have to actually work
*****
Edit: it seems to be possible to hack the the lua interface to give a more
parsable output, for instance:
Code:
-- lines 429-438 of cli.lua:
function get_time(var)
return function(name,client)
local input = vlc.object.input()
if input then
client:append("ans_time=" .. math.floor(vlc.var.get( input, var )))
else
client:append("")
end
end
end
This is of course cribbed from mplayer, and it should make grepping the logfile
more reliable.