LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 03-17-2014, 09:39 PM   #1
nokangaroo
Member
 
Registered: Nov 2009
Posts: 141

Rep: Reputation: 25
Bookmarking and resuming scripts for VLC - a working solution


Here are improved versions of the dvdplayer and bookmark scripts. I am marking
this thread a solved, because in principle it is, though there remains work to
do. Somebody should write a dvd playback interface for VLC in clean C or lua
(perhaps taking ogle as their model. ogle is very elementary but uses the
correct way of saving the dvd player state). I'm using the shell because I'm
familiar with it (and somebody else should help me complete the bookmarking
script!).

The limitations mentioned above still apply though:

1. It is not possible to bookmark the menu.
2. It is still not the way dvd bookmarking should be done. The correct way
would be to save the navigation state of the dvdplayer directly, as the
ogle dvdplayer did. See example ogle bookmark here: http://www.linuxquestions.org/questi...ck-4175495616/
But with the present VLC interface this script is probably the best
that can be done.

The script now uses a shell implementation of disc_id by default, for testing
purposes, and it depends on a modified version of cli.lua which makes logfile
parsing a lot more reliable (logfile parsing seems to be a necessity, alas).

These scripts will also work in ubuntu precise if you don't forget to install
lua-5.1, fuseiso, fuseiso9660 and fuse-utils and recompile cli-mod.lua.

Compile the modified cli.lua with luac <path/to/cli-mod.lua> and copy it to your
home folder:
Code:
mkdir -p $HOME/.local/share/vlc/lua/intf
cp $HOME/luac.out $HOME/.local/share/vlc/lua/intf/cli.luac
Here are the changes to cli.lua:
Code:
-- ll 429 ff:
function get_time(var)
    return function(name,client)
        local input = vlc.object.input()
	if input then
	    client:append("ans_" .. tostring(name) .. "=" .. math.floor(vlc.var.get( input, var )) .. '\n')
	else
	    client:append("")
	end
    end
end

-- not needed for bookmarking but might come in handy:
function get_remaining(name,client)
	local input = vlc.object.input()
	local var = math.floor((vlc.var.get( input, "length") - (vlc.var.get(input, "time"))))
	if input then
		client:append("ans_remaining=" .. var .. '\n')
		else
		client:append("")
	end
end

function titlechap(name,client,value)
    local input = vlc.object.input()
    local var = string.gsub( name, "_.*$", "" )
    if value then
        vlc.var.set( input, var, value )
    end
    local item = vlc.var.get( input, var )
    client:append("ans_" .. tostring(var) .. "=" .. item .. '\n')
end

-- add this to commands_ordered if you want to use get_remaining:
    { "get_remaining"; {func = get_remaining; help = "the remaining time in the current stream" } };
The standalone version of discid:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.

# If called without arguments will search dvd drive

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

DISK_LABEL="$(cat /etc/mtab | grep udf | awk '{print $2}')"
if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi

TEMP=`basename $0`
TMPFILE=`mktemp -q /tmp/${TEMP}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${TEMP}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s "$TMPFILE" ]]; then
echo `md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi
The improved dvdplayer script. Later the DEFAULTFILE might be merged with the
BOOKMARKFILE; right now it is a quick implementation while I think about the
best way of parsing bookmark lists:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# dvdplayer script using VLC with resume function
# needs modified cli.lua
# work in progress



# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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

# Logfile:
PROG=`basename $0`
rm -f /tmp/${PROG}.*
LOGFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`

case $1 in
-h|--help)
cat << EOF
"$PROG" is a dvd player wrapper script for VLC. It is intended for use with the resuming script, which at present can create two user-defined bookmarks for every DVD you play, a default bookmark to start playback from (usually the beginning of the movie) and a resume bookmark.

This script creates a folder $MEDIADIR and a folder $BMDIR inside it, where your bookmarks are. They are identified by a function that concatenates the IFO files in the VIDEO_TS folder and calculates the md5sum of the resulting file, which should be reasonably unique. Iso images must be mounted before this calculation can be performed, therefore this script requires fusermount and fuseiso.

You can create a desktop icon or an "open with" right-click menu entry to open this script; it will exit automatically when you close VLC.

Menus cannot be bookmarked, because there is no title associated with them.

Usage:
$PROG without arguments will play a DVD in your drive. External drives will be detected.
$PROG /path/to/image/or/VIDEO_TS will play an iso image or VIDEO_TS folder on your harddisk. The filenames can have spaces in them.
$PROG -h or $PROG --help will print this help text and exit.
No other arguments are accepted.

EOF
exit
;;
*)
#DVD device (this is a DVD player only!):
if [ "$*" ]; 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}')"
# Helpful information for editing the data files manually; also needed for
# DVD disc_id:
DISK_LABEL="$(cat /etc/mtab | grep udf | awk '{print $2}')"
fi
;;
esac

if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi



# Functions:
get_resume () {
if [ -s "$RESUMEFILE" ]; then #swap $DEFAULTFILE and $RESUMEFILE if you like;
#may be more reliable on some DVDs. The default bookmark for instance will work
#with TOYSTORY (the lamp stomping on the pixar logo) but the resume bookmark
#won't. This is not the fault of my script though; seeking does not seem to
#work well with some DVDs. The VLC developers promised to fix the chapter
#seeking with VLC 2.2 though
FILE="$RESUMEFILE"
else
FILE="$DEFAULTFILE"
fi
for j in "$@"; do
eval "$j"=`cat "$FILE" | grep "$j" | sed "s/[^[:digit:]]//g"`
done
}

#I'm afraid we have no use for this here:
#vlc_command () {
#echo "$*" > $MEDIADIR/fifo
#}



# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.
TMPFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${PROG}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s "$TMPFILE" ]]; then
DISC_ID=`md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi

wait



# Inventing extensions for the bookmark and resume files.
# Later we might invent corresponding mimetypes.
# For disc_id of libdvdread-0.9.7 replace ${DISC_ID} with 
# $(disc_id "$DVD_DEVICE")
touch "${BMDIR}/${DISC_ID}".vlcbmk
BOOKMARKFILE="${BMDIR}/${DISC_ID}".vlcbmk
touch "${BMDIR}/${DISC_ID}".resume
RESUMEFILE="${BMDIR}/${DISC_ID}".resume
touch "${BMDIR}/${DISC_ID}".default
DEFAULTFILE="${BMDIR}/${DISC_ID}".default

rm -f $MEDIADIR/data
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE; do
eval echo $data=\$"$data" >> $MEDIADIR/data
done



# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. $title and $get_time can be
# empty, so these commands will work with empty bookmark and resume files. Using
# nohup is unreliable and unnecessary. The logfile is needed for reading VLC's
# output into variables, unfortunately):

get_resume title get_time
wait

# The following command will kill the correct instance of tail after VLC exits,
# so we don't have to start this script from the commandline; we can use the
# "open with" menu and desktop icons:
tail -f $MEDIADIR/fifo | (PID=`pidof -s tail`; vlc dvd://"$DVD_DEVICE"\#"$title" --start-time=$get_time --playlist-autostart --one-instance --extraintf "luaintf{intf=cli}" >> $LOGFILE 2>&1; kill $PID)

The bookmarking script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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/data to store variables:
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval "$data"=`cat $MEDIADIR/data | grep "$data" | cut -d \= -f 2`
done



# Functions:

get_var () {
#valid arguments: title get_time get_length get_remaining chapter (chapter is unreliable though)
for i in "$@"; do
echo "$i" > $MEDIADIR/fifo
wait
#the following commented line is for the original cli.lua; it does not work well:
#eval "$i"="$(cat $LOGFILE | grep -G [[:digit:]] | grep -v '\[' | tail -n 1 | sed "s/[^[:digit:]]//g")"
eval "$i"="$(cat $LOGFILE | grep 'ans_'$i | tail -n 1 | sed "s/[^[:digit:]]//g")"
wait
done
}

get_resume () {
for j in "$@"; do
eval "$j"=`cat $RESUMEFILE | grep "$j" | sed "s/[^[:digit:]]//g"`
done
}

get_default () {
for k in "$@"; do
eval "$k"=`cat $DEFAULTFILE | grep "$k" | sed "s/[^[:digit:]]//g"`
done
}

set_resume () {
for l in "$@"; do
eval echo "$l"=\$"$l" >> $RESUMEFILE
done
}

set_default () {
for m in "$@"; do
eval echo "$m"=\$"$m" >> $DEFAULTFILE
done
}

#get_chapter () {
# not needed for bookmarking, but more reliable for getting the current chapter
# this parses dvdnav debug info and requires starting VLC with -vv option
# I should NOT have to do this!
#cat $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)
PROG=`basename $0`
cat << EOF
"$PROG" 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:
$PROG without arguments will create a resume bookmark and close VLC. The previous resume bookmark will be overwritten.

$PROG -b or $PROG --create-default will create a default bookmark at the current position to start the playback from. Unlike the resume bookmark this will not be overwritten unless you create a new default bookmark.

$PROG -s or $PROG --start will start playback from the default bookmark, if present.

$PROG -r or $PROG --resume will start playback from the resume bookmark, if present.

$PROG -l (not yet implemented) will open a terminal window and list your bookmarks in a select menu; choose one by number.

$PROG -c (not yet implemented) will open a terminal window and prompt for the name of a new bookmark to be created at the current position.

$PROG -d (not yet implemented) will open a terminal window and list your bookmarks in a select menu; choose one to delete. Can also be done by opening \$BOOKMARKFILE in an editor, of course.

EOF
exit
;;
-l|--list)
#TODO
;;
-c|--create)
#TODO
;;
-d|--delete)
#TODO
;;
-b|--create-default)
rm -f $DEFAULTFILE
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
wait
;;
-s|--start)
if [ -s "$DEFAULTFILE" ]; then
get_default title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
fi
;;
-r|--resume)
if [ -s "$RESUMEFILE" ]; then
get_resume title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
fi
;;
*)
rm -f $RESUMEFILE
get_var title get_time
wait
set_resume title get_time
wait
vlc_command quit
wait
;;
esac
Edit: I have added an implementation of named bookmarks. Seems to work:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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/data to store variables:
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval "$data"=`cat $MEDIADIR/data | grep "$data" | cut -d \= -f 2`
done



# Functions:

get_var () {
#valid arguments: title get_time get_length get_remaining chapter (chapter is unreliable though)
for i in "$@"; do
echo "$i" > $MEDIADIR/fifo
wait
#the following commented line is for the original cli.lua; it does not work well:
#eval "$i"="$(cat $LOGFILE | grep -G [[:digit:]] | grep -v '\[' | tail -n 1 | sed "s/[^[:digit:]]//g")"
eval "$i"="$(cat $LOGFILE | grep 'ans_'$i | tail -n 1 | sed "s/[^[:digit:]]//g")"
wait
done
}

get_resume () {
for j in "$@"; do
eval "$j"=`cat $RESUMEFILE | grep "$j" | sed "s/[^[:digit:]]//g"`
done
}

get_default () {
for k in "$@"; do
eval "$k"=`cat $DEFAULTFILE | grep "$k" | sed "s/[^[:digit:]]//g"`
done
}

set_resume () {
for m in "$@"; do
eval echo "$m"=\$"$m" >> $RESUMEFILE
done
}

set_default () {
for n in "$@"; do
eval echo "$n"=\$"$n" >> $DEFAULTFILE
done
}

set_bookmark () {
echo -e $(expr `grep -o ^[[:digit:]]* $BOOKMARKFILE | tail -n 1` + 1)'\t'"$BMK" >> $BOOKMARKFILE
for o in "$@"; do
eval echo "$o"=\$"$o" >> $BOOKMARKFILE
done
}

#get_chapter () {
# not needed for bookmarking, but more reliable for getting the current chapter
# this parses dvdnav debug info and requires starting VLC with -vv option
# I should NOT have to do this!
#cat $LOGFILE | grep  pgN | tail -n 1 | cut -d \= -f 2
#}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}



case $1 in
-h|--help)
PROG=`basename $0`
cat << EOF
"$PROG" 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:
$PROG without arguments will create a resume bookmark and close VLC. The previous resume bookmark will be overwritten.

$PROG -b or $PROG --create-default will create a default bookmark at the current position to start the playback from. Unlike the resume bookmark this will not be overwritten unless you create a new default bookmark.

$PROG -s or $PROG --start will start playback from the default bookmark, if present.

$PROG -r or $PROG --resume will start playback from the resume bookmark, if present.

$PROG -l or $PROG --list will open a bookmark menu; choose one by number. The numbers will not be consecutive if you deleted bookmarks.

$PROG -c or $PROG --create will prompt for the name of a new bookmark to be created at the current position.

$PROG -d (not yet implemented) will open a bookmark menu; choose one to delete. Can also be done by opening \$BOOKMARKFILE in an editor, of course.
EOF
exit
;;
-l|--list)
SELECTION=$(zenity --entry --title="Bookmark List" --text "$(grep ^[[:digit:]] $BOOKMARKFILE)\n\nEnter the number of the selected bookmark:")
wait
if [ "$SELECTION" ]; then
#Should be extendable for audio and subtitle track:
title=$(cat $BOOKMARKFILE | grep -w -A 1 ^$SELECTION | tail -n 1 | cut -d \= -f 2)
time=$(cat $BOOKMARKFILE | grep -w -A 2 ^$SELECTION | tail -n 1 | cut -d \= -f 2)
wait
vlc_command title $title
wait
vlc_command seek $time
wait
fi
;;
-c|--create)
BMK=$(zenity --entry --title="New Bookmark" --text="A new bookmark will be created at the present position. Choose a name for it:")
wait
if [ "$BMK" ]; then
get_var title get_time
wait
set_bookmark title get_time
wait
vlc_command play
fi
;;
-d|--delete)
#TODO
;;
-b|--create-default)
rm -f $DEFAULTFILE
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
wait
;;
-s|--start)
if [ -s "$DEFAULTFILE" ]; then
get_default title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
fi
;;
-r|--resume)
if [ -s "$RESUMEFILE" ]; then
get_resume title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
fi
;;
*)
rm -f $RESUMEFILE
get_var title get_time
wait
set_resume title get_time
wait
vlc_command quit
wait
;;
esac
Will also work with mate-dialogs instead of zenity. Just replace "zenity" with "matedialog".


Edit:
An example for custom audio tracks if autodetection is not working:


DVD: Mr. & Mrs. Smith Region 2 (with starts by default with German audio track)

With a handcrafted default file
$HOME/vlc-DVDdata/bookmarks/d895cec01ef197ce5bf402f7b7c9b40f.default:
Code:
title=12
get_time=25
strack=2
atrack=2
and the following lines at the end of the dvdplayer script:
Code:
get_resume title get_time atrack strack
wait
tail -f $MEDIADIR/fifo | (PID=`pidof -s tail`; vlc dvdsimple://"$DVD_DEVICE"\#"$title" --start-time=$get_time --audio-track=$atrack --sub-track=$strack --playlist-autostart --one-instance --extraintf "luaintf{intf=cli}" >> $LOGFILE 2>&1; kill $PID)
the DVD will start with the correct audio and subtitle tracks. However the cli
output of the atrack and strack commands is different, so at present I don't
know how to automate this. Besides, the output of atrack is different for dvd://
and dvdsimple://. How is anyone supposed to work with such an interface?



Edit:
It is theoretically possible to insert something like this:
Code:
get_resume title get_time
wait
(sleep $RIDICULOUSLY_LONG_TIME
vlc_command atrack $atrack
wait
vlc_command strack $strack
) &
tail -f $MEDIADIR/fifo | (PID=`pidof -s tail`; vlc dvd://"$DVD_DEVICE"\#"$title" --start-time=$get_time --playlist-autostart --one-instance --extraintf "luaintf{intf=cli}" >> $LOGFILE 2>&1; kill $PID)
but this is monstrous.

Edit:
Scratch the "monstrous". The following seems to work:
Code:
get_resume title get_time atrack strack
wait

(if [ "$atrack" ]; then
while :; do
if [ -s "$LOGFILE" ]; then #polling for vlc pid will fail (not a child of this shell)
sleep 0.6
vlc_command atrack $atrack
wait
vlc_command strack $strack
wait
break
fi
done
fi) &
Next I'll edit the bookmarking script so that the default and resume files are
edited in place (instead of overwritten), and information added manually will
be preserved.

The defaultfile in this case looks like this:
Code:
title=12
get_time=25
atrack=10
strack=5
which looks more like the output of the lua command.

Last edited by nokangaroo; 03-21-2014 at 07:30 PM.
 
Old 03-21-2014, 11:24 PM   #2
nokangaroo
Member
 
Registered: Nov 2009
Posts: 141

Original Poster
Rep: Reputation: 25
Edit:
Here are preliminary versions of the dvdplayer and bookmarking scripts (not
well tested yet, but they show up the problems that have to be solved)

The dvdplayer script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# dvdplayer script using VLC with resume function
# needs modified cli.lua
# work in progress



# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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

# Logfile:
PROG=`basename $0`
rm -f /tmp/${PROG}.*
LOGFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`

case $1 in
-h|--help)
cat << EOF
"$PROG" is a dvd player wrapper script for VLC. It is intended for use with the resuming script, which can create user-defined bookmarks for every DVD you play: a default bookmark to start playback from (usually the beginning of the movie), a resume bookmark, and named bookmarks.

This script creates a folder $MEDIADIR and a folder $BMDIR inside it, where your bookmarks are. They are identified by a function that concatenates the IFO files in the VIDEO_TS folder and calculates the md5sum of the resulting file, which should be reasonably unique. Iso images must be mounted before this calculation can be performed, therefore this script requires fusermount and fuseiso.

You can create a desktop icon or an "open with" right-click menu entry to open this script; it will exit automatically when you close VLC.

Menus cannot be bookmarked, because there is no title associated with them.

Usage:
$PROG without arguments will play a DVD in your drive. External drives will be detected.
$PROG /path/to/image/or/VIDEO_TS will play an iso image or VIDEO_TS folder on your harddisk. The filenames can have spaces in them.
$PROG -h or $PROG --help will print this help text and exit.
No other arguments are accepted.

EOF
exit
;;
*)
# DVD device (this is a DVD player only!):
if [ "$*" ]; 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="$(grep "udf" /etc/mtab | awk '{print $1}')"
# Helpful information for editing the data files manually; also needed for
# DVD disc_id:
DISK_LABEL="$(grep "udf" /etc/mtab | awk '{print $2}')"
fi
;;
esac

if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi



# Functions:
get_resume () {
if [ -s "$RESUMEFILE" ]; then #swap $DEFAULTFILE and $RESUMEFILE if you like;
#may be more reliable on some DVDs. The default bookmark for instance will work
#with TOYSTORY (the lamp stomping on the pixar logo) but the resume bookmark
#won't. This is not the fault of my script though; seeking does not seem to
#work well with some DVDs. The VLC developers promised to fix the chapter
#seeking with VLC 2.2 though
FILE="$RESUMEFILE"
else
FILE="$DEFAULTFILE"
fi
for j in "$@"; do
eval "$j"=`grep "$j" "$FILE" | sed "s/[^[:digit:]]//g"`
done
}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}

# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.
TMPFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${PROG}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s "$TMPFILE" ]]; then
DISC_ID=`md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi

wait



# Inventing extensions for the bookmark and resume files.
# Later we might invent corresponding mimetypes.
# For disc_id of libdvdread-0.9.7 replace ${DISC_ID} with 
# $(disc_id "$DVD_DEVICE")
touch "${BMDIR}/${DISC_ID}".vlcbmk
BOOKMARKFILE="${BMDIR}/${DISC_ID}".vlcbmk
touch "${BMDIR}/${DISC_ID}".resume
RESUMEFILE="${BMDIR}/${DISC_ID}".resume
touch "${BMDIR}/${DISC_ID}".default
DEFAULTFILE="${BMDIR}/${DISC_ID}".default
echo "$DISK_LABEL" > "${BMDIR}/${DISC_ID}".disklabel

rm -f $MEDIADIR/data
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE; do
eval echo $data=\$"$data" >> $MEDIADIR/data
done

# Get data:
get_resume title get_time atrack strack
wait



# The following will wait for VLC to start and then switch to the correct audio
# and subtitle tracks if autodetection fails. Polling for logfile size > 0 is
# necessary because "wait `pidof vlc`" or synonyms will fail with a "not a child
# of this shell" error:
(if [ "$atrack" ]; then
while :; do
if [ -s "$LOGFILE" ]; then
sleep 0.6
vlc_command atrack $atrack
wait
vlc_command strack $strack
wait
break
fi
done
fi) &

# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. $title and $get_time can be
# empty, so these commands will work with empty bookmark and resume files. Using
# nohup is unreliable and unnecessary. The logfile is needed for reading VLC's
# output into variables, unfortunately).
# The following command will kill the correct instance of tail after VLC exits,
# so we don't have to start this script from the commandline; we can use the
# "open with" menu and desktop icons:
tail -f $MEDIADIR/fifo | (PID=`pidof -s tail`; vlc dvd://"$DVD_DEVICE"\#"$title" --start-time=$get_time --playlist-autostart --one-instance --extraintf "luaintf{intf=cli}" >> $LOGFILE 2>&1; kill $PID)
The bookmarking script:
Code:
#!/bin/bash -x
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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/data to store variables:
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval "$data"="$(cat "$MEDIADIR/data" | grep "$data" | cut -d \= -f 2)"
done



# Functions:

get_var () {
#valid arguments: title get_time get_length get_remaining chapter (chapter is unreliable though)
for i in "$@"; do
echo "$i" > $MEDIADIR/fifo
wait
#the following commented line is for the original cli.lua; it does not work well:
#eval "$i"="$(cat $LOGFILE | grep -G [[:digit:]] | grep -v '\[' | tail -n 1 | sed "s/[^[:digit:]]//g")"
eval "$i"="$(grep 'ans_'"$i" $LOGFILE | tail -n 1 | sed "s/[^[:digit:]]//g")"
wait
done
}

get_resume () {
for j in "$@"; do
eval "$j"="$(grep "$j" $RESUMEFILE | sed "s/[^[:digit:]]//g")"
done
}

get_default () {
for k in "$@"; do
eval "$k"="$(grep "$k" $DEFAULTFILE | sed "s/[^[:digit:]]//g")"
done
}

# The point of the following function is that we don't have to introduce atrack
# and strack variables on the majority of DVDs that don't need them. Audio
# tracks seem to be randomized on some DVDs when switching between titles, so
# the function is more complex than I'd like:
check_default () {
if [[ $(grep 'audio_id' $DEFAULTFILE) ]] && [[ $title == $(grep 'title' $DEFAULTFILE | cut -d \= -f 2) ]]; then
get_default audio_id sub_id
wait
vlc_command atrack
wait
audio=`cat $LOGFILE | grep "Track $audio_id" | tail -n 1 | cut -d \  -f 2`
wait
vlc_command atrack $audio
wait
sleep 0.3
wait
vlc_command strack
wait
sub=`cat $LOGFILE | grep "Track $sub_id" | tail -n 1 | cut -d \  -f 2`
wait
vlc_command strack $sub
wait
sleep 0.3
fi
}

set_resume () {
for m in "$@"; do
sed -i /$m/d $RESUMEFILE
eval echo "$m"=\$"$m" >> $RESUMEFILE
done
}

set_default () {
for n in "$@"; do
sed -i /$n/d $DEFAULTFILE
eval echo "$n"=\$"$n" >> $DEFAULTFILE
done
}

set_bookmark () {
echo -e $(expr `grep -o ^[[:digit:]]* $BOOKMARKFILE | tail -n 1` + 1)'\t'"$BMK" >> $BOOKMARKFILE
for o in "$@"; do
eval echo "$o"=\$"$o" >> $BOOKMARKFILE
done
}

#get_chapter () {
# not needed for bookmarking, but more reliable for getting the current chapter
# this parses dvdnav debug info and requires starting VLC with -vv option
# I should NOT have to do this!
#cat $LOGFILE | grep  pgN | tail -n 1 | cut -d \= -f 2
#}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}



case $1 in
-h|--help)
PROG=`basename $0`
cat << EOF
"$PROG" 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:
$PROG without arguments will create a resume bookmark and close VLC. The previous resume bookmark will be overwritten.

$PROG -b or $PROG --create-default will create a default bookmark at the current position to start the playback from. Unlike the resume bookmark this will not be overwritten unless you create a new default bookmark.

$PROG -s or $PROG --start will start playback from the default bookmark, if present.

$PROG -r or $PROG --resume will start playback from the resume bookmark, if present.

$PROG -l or $PROG --list will open a bookmark menu; choose one by number. The numbers will not be consecutive if you deleted bookmarks.

$PROG -c or $PROG --create will prompt for the name of a new bookmark to be created at the current position.

EOF
exit
;;
-l|--list)
SELECTION=$(zenity --entry --title="Bookmark List" --text "$(grep ^[[:digit:]] $BOOKMARKFILE)\n\nEnter the number of the selected bookmark:")
wait
if [ "$SELECTION" ]; then
title=$(grep -w -A 1 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
time=$(grep -w -A 2 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
wait
vlc_command title $title
wait
vlc_command seek $time
wait
sleep 0.3
check_default
fi
;;
-a|--set-atrack)
#TODO
;;
-u|--set-strack)
#TODO
;;
-c|--create)
BMK=$(zenity --entry --title="New Bookmark" --text="A new bookmark will be created at the present position. Choose a name for it:")
wait
if [ "$BMK" ]; then
get_var title get_time
wait
set_bookmark title get_time
wait
vlc_command play
fi
;;
-b|--create-default)
#$DEFAULTFILE will be edited in place; atrack and strack info will be preserved
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
wait
;;
-s|--start)
if [ -s "$DEFAULTFILE" ]; then
get_default title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
sleep 0.3
check_default
wait
fi
;;
-r|--resume)
if [ -s "$RESUMEFILE" ]; then
get_resume title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
sleep 0.3
check_default
wait
fi
;;
*)
#$RESUMEFILE will be edited in place; atrack and strack info will be preserved
get_var title get_time
wait
set_resume title get_time
wait
vlc_command quit
wait
;;
esac
Default and resume files for the test DVD (Mr & Mrs Smith Region 2):
Code:
#default
title=12
get_time=25
atrack=10
strack=5
audio_id=3
sub_id=5

#resume (example)
atrack=10
strack=5
audio_id=3
sub_id=5
title=12
get_time=2154

#sample bookmark file
1	Bogota, 5 or 6 years ago
title=12
get_time=121
2	Beginner's luck
title=12
get_time=360
3	In the elevator
title=11
get_time=0
It should be possible to automate this, so the default and resume files don't
need to be edited by hand.

Last edited by nokangaroo; 03-21-2014 at 11:31 PM.
 
Old 03-22-2014, 11:30 PM   #3
nokangaroo
Member
 
Registered: Nov 2009
Posts: 141

Original Poster
Rep: Reputation: 25
To avoid exceeding the maximum post length again, here's another reply:

Here are finished but untested versions of the dvdplayer and resuming scripts.
These scripts will probably break at any update, but at least they show what can
be done. If smoke comes from your box, or if you blow the power for five blocks,
I am not responsible :-)

Modified cli.lua as before.



The dvdplayer script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# dvdplayer script using VLC with resume function
# needs modified cli.lua
# work in progress



# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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

# Logfile:
PROG=`basename $0`
rm -f /tmp/${PROG}.*
LOGFILE=`mktemp -q /tmp/${PROG}.XXXXXXXXXX`

case $1 in
-h|--help)
cat << EOF
"$PROG" is a dvd player wrapper script for VLC. It is intended for use with the resuming script, which can create user-defined bookmarks for every DVD you play: a default bookmark to start playback from (usually the beginning of the movie), a resume bookmark, and named bookmarks.

This script creates a folder $MEDIADIR and a folder $BMDIR inside it, where your bookmarks are. They are identified by a function that concatenates the IFO files in the VIDEO_TS folder and calculates the md5sum of the resulting file, which should be reasonably unique. Iso images must be mounted before this calculation can be performed, therefore this script requires fusermount and fuseiso.

You can create a desktop icon or an "open with" right-click menu entry to open this script; it will exit automatically when you close VLC.

Menus cannot be bookmarked, because there is no title associated with them.

Usage:
$PROG without arguments will play a DVD in your drive. External drives will be detected.
$PROG /path/to/image/or/VIDEO_TS will play an iso image or VIDEO_TS folder on your harddisk. The filenames can have spaces in them.
$PROG -h or $PROG --help will print this help text and exit.
No other arguments are accepted.

EOF
exit
;;
*)
# DVD device (this is a DVD player only!):
if [ "$*" ]; 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="$(grep "udf" /etc/mtab | awk '{print $1}')"
# Helpful information for editing the data files manually; also needed for
# DVD disc_id:
DISK_LABEL="$(grep "udf" /etc/mtab | awk '{print $2}')"
fi
;;
esac

if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi



# Functions:
get_resume () {
if [[ `grep {title,get_time} $RESUMEFILE` ]]; then
FILE="$RESUMEFILE"
else
FILE="$DEFAULTFILE"
fi
for j in "$@"; do
eval "$j"=`grep "$j" "$FILE" | sed "s/[^[:digit:]]//g"`
done
}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}

# The point of the following function is that we don't have to introduce
# audio_id and sub_id variables on the majority of DVDs that don't need them.
# Audio tracks seem to be randomized on some DVDs when switching between titles,
# so the function is more complex than I'd like:
check_default () {
if [[ $(grep {audio_id,sub_id} $FILE) ]] && [[ $title == $(grep 'title' $DEFAULTFILE | cut -d \= -f 2) ]]; then
get_resume audio_id sub_id
wait
vlc_command atrack
wait
audio=`cat $LOGFILE | grep "Track $audio_id" | tail -n 1 | cut -d \  -f 2`
wait
if [ "$audio" ]; then
vlc_command atrack $audio
wait
fi
vlc_command strack
wait
sub=`cat $LOGFILE | grep "Track $sub_id" | tail -n 1 | cut -d \  -f 2`
wait
if [ "$sub" ]; then
vlc_command strack $sub
wait
fi
fi
}
# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.
TMPFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${PROG}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d : -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s "$TMPFILE" ]]; then
DISC_ID=`md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi

wait



# Inventing extensions for the bookmark and resume files.
# Later we might invent corresponding mimetypes.
# For disc_id of libdvdread-0.9.7 replace ${DISC_ID} with 
# $(disc_id "$DVD_DEVICE")
touch "${BMDIR}/${DISC_ID}".vlcbmk
BOOKMARKFILE="${BMDIR}/${DISC_ID}".vlcbmk
touch "${BMDIR}/${DISC_ID}".resume
RESUMEFILE="${BMDIR}/${DISC_ID}".resume
touch "${BMDIR}/${DISC_ID}".default
DEFAULTFILE="${BMDIR}/${DISC_ID}".default
echo "$DISK_LABEL" > "${BMDIR}/${DISC_ID}".disklabel

rm -f $MEDIADIR/data
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE; do
eval echo $data=\$"$data" >> $MEDIADIR/data
done

# Get data:
get_resume title get_time audio_id sub_id
wait



# The following will wait for VLC to start and then switch to the correct audio
# and subtitle tracks if autodetection fails. Polling for logfile size > 0 is
# necessary because "wait `pidof vlc`" or synonyms will fail with a "not a child
# of this shell" error:
(if [ "$audio_id" ] || [ "$sub_id" ]; then
while :; do
if [ -s "$LOGFILE" ]; then
sleep 0.5        #tune for performance; depends on the DVD drive and on the DVD
check_default
break
fi
done
fi) &

# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. $title and $get_time can be
# empty, so these commands will work with empty bookmark and resume files. Using
# nohup is unreliable and unnecessary. The logfile is needed for reading VLC's
# output into variables, unfortunately).
# The following command will kill the correct instance of tail after VLC exits,
# so we don't have to start this script from the commandline; we can use the
# "open with" menu and desktop icons:
tail -f $MEDIADIR/fifo | (PID=`pidof -s tail`; vlc dvd://"$DVD_DEVICE"\#"$title" --start-time=$get_time --playlist-autostart --one-instance --extraintf "luaintf{intf=cli}" >> $LOGFILE 2>&1; kill $PID)


The resuming script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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/data to store variables:
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval "$data"="$(cat "$MEDIADIR/data" | grep "$data" | cut -d \= -f 2)"
done



# Functions:

get_var () {
#valid arguments: title get_time get_length get_remaining chapter (chapter is unreliable though)
for i in "$@"; do
echo "$i" > $MEDIADIR/fifo
wait
#the following commented line is for the original cli.lua; it does not work well:
#eval "$i"="$(cat $LOGFILE | grep -G [[:digit:]] | grep -v '\[' | tail -n 1 | sed "s/[^[:digit:]]//g")"
eval "$i"="$(grep 'ans_'"$i" $LOGFILE | tail -n 1 | sed "s/[^[:digit:]]//g")"
wait
done
}

get_resume () {
for j in "$@"; do
eval "$j"="$(grep "$j" $RESUMEFILE | sed "s/[^[:digit:]]//g")"
done
}

get_default () {
for k in "$@"; do
eval "$k"="$(grep "$k" $DEFAULTFILE | sed "s/[^[:digit:]]//g")"
done
}

# The point of the following function is that we don't have to introduce
# audio_id and sub_id variables on the majority of DVDs that don't need them.
# Audio tracks seem to be randomized on some DVDs when switching between titles,
# so the function is more complex than I'd like:
check_default () {
if [[ $(grep {audio_id,sub_id} $DEFAULTFILE) ]] && [[ $title == $(grep 'title' $DEFAULTFILE | cut -d \= -f 2) ]]; then
get_default audio_id sub_id
wait
vlc_command atrack
wait
audio=`cat $LOGFILE | grep "Track $audio_id" | tail -n 1 | cut -d \  -f 2`
wait
if [ "$audio" ]; then
vlc_command atrack $audio
wait
fi
vlc_command strack
wait
sub=`cat $LOGFILE | grep "Track $sub_id" | tail -n 1 | cut -d \  -f 2`
wait
if [ "$sub" ]; then
vlc_command strack $sub
wait
fi
fi
}

set_resume () {
for m in "$@"; do
sed -i /$m/d $RESUMEFILE
eval echo "$m"=\$"$m" >> $RESUMEFILE
done
}

set_default () {
for n in "$@"; do
sed -i /$n/d $DEFAULTFILE
eval echo "$n"=\$"$n" >> $DEFAULTFILE
done
}

set_bookmark () {
echo -e $(expr `grep -o ^[[:digit:]]* $BOOKMARKFILE | tail -n 1` + 1)'\t'"$BMK" >> $BOOKMARKFILE
for o in "$@"; do
eval echo "$o"=\$"$o" >> $BOOKMARKFILE
done
}

#get_chapter () {
# not needed for bookmarking, but more reliable for getting the current chapter
# this parses dvdnav debug info and requires starting VLC with -vv option
# I should NOT have to do this!
#cat $LOGFILE | grep  pgN | tail -n 1 | cut -d \= -f 2
#}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}



case $1 in
-h|--help)
PROG=`basename $0`
cat << EOF
"$PROG" 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:
$PROG without arguments will create a resume bookmark and close VLC. The previous resume bookmark will be overwritten.

$PROG -b or $PROG --create-default will create a default bookmark at the current position to start the playback from. Unlike the resume bookmark this will not be overwritten unless you create a new default bookmark.

$PROG -s or $PROG --start will start playback from the default bookmark, if present.

$PROG -r or $PROG --resume will start playback from the resume bookmark, if present.

$PROG -l or $PROG --list will open a bookmark menu; choose one by number. The numbers will not be consecutive if you deleted bookmarks.

$PROG -c or $PROG --create will prompt for the name of a new bookmark to be created at the current position.

$PROG -U or $PROG --unset-resume will unset the resume bookmark. No functions for editing named bookmarks are provided; this is best done by editing the files manually.

$PROG -A or $PROG --set-atrack will write the current audio track into the default and resume files.

$PROG -S or $PROG --set-strack will write the current subtitle track into the default and resume files. The last two options are useful if autodetection fails. Use them only if necessary.

EOF
exit
;;
-l|--list)
SELECTION=$(zenity --entry --title="Bookmark List" --text "$(grep ^[[:digit:]] $BOOKMARKFILE)\n\nEnter the number of the selected bookmark:")
wait
if [ "$SELECTION" ]; then
title=$(grep -w -A 1 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
time=$(grep -w -A 2 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
wait
vlc_command title $title
wait
vlc_command seek $time
wait
sleep 0.4
check_default
fi
;;
-A|--set-atrack)
vlc_command atrack
wait
audio_id=`cat $LOGFILE | grep -E 'Track.*\*' | tail -n 1 | cut -d \  -f 5`
wait
set_default audio_id
wait
set_resume audio_id
wait
;;
-S|--set-strack)
vlc_command strack
wait
if [[ `cat $LOGFILE | grep -E 'Disable\ \*' | tail -n 1` ]]; then
sub_id=0
else
sub_id=`cat $LOGFILE | grep -E 'Track.*\*' | tail -n 1 | cut -d \  -f 5`
fi
wait
set_default sub_id
wait
set_resume sub_id
wait
;;
-U|--unset-resume)
sed -i /title/d $RESUMEFILE
sed -i /get_time/d $RESUMEFILE
;;
-c|--create)
BMK=$(zenity --entry --title="New Bookmark" --text="A new bookmark will be created at the present position. Choose a name for it:")
wait
if [ "$BMK" ]; then
get_var title get_time
wait
set_bookmark title get_time
wait
vlc_command play
fi
;;
-b|--create-default)
#$DEFAULTFILE will be edited in place; atrack and strack info will be preserved
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
wait
;;
-s|--start)
if [[ `grep {title,get_time} $DEFAULTFILE` ]]; then
get_default title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
sleep 0.4
check_default
wait
fi
;;
-r|--resume)
if [[ `grep {title,get_time} $RESUMEFILE` ]]; then
get_resume title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
sleep 0.4
check_default
wait
fi
;;
*)
#$RESUMEFILE will be edited in place; atrack and strack info will be preserved
get_var title get_time
wait
set_resume title get_time
wait
vlc_command quit
wait
;;
esac
If audio autodetection fails, the default audio will be heard for a split second
before the script kicks in. That could be fixed of course (silence the audio for
0.5 seconds), but first I'll do some serious testing.
 
Old 03-28-2014, 03:09 AM   #4
nokangaroo
Member
 
Registered: Nov 2009
Posts: 141

Original Poster
Rep: Reputation: 25
Here are again improved, and already somewhat tested, versions of the scripts:

The DVD player:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# swiss-army sledgehammer for DVD playback and bookmarking using VLC
# needs modified cli.lua
# work in progress



# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
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

# Logfile:
PROG=`basename $0`
rm -f /tmp/${PROG}.*
LOGFILE=`mktemp -q /tmp/${PROG}.XXXXXXXXXX`



case $1 in
-h|--help)
cat << EOF
"$PROG" is a dvd player wrapper script for VLC. It is intended for use with the resuming script, which can create user-defined bookmarks for every DVD you play: a default bookmark to start playback from (usually the beginning of the movie), a resume bookmark, and named bookmarks.

This script creates a folder $MEDIADIR and a folder $BMDIR inside it, where your bookmarks are. They are identified by a function that concatenates the IFO files in the VIDEO_TS folder and calculates the md5sum of the resulting file, which should be reasonably unique. Iso images must be mounted before this calculation can be performed, therefore this script requires fusermount and fuseiso.

You can create a desktop icon or an "open with" right-click menu entry to open this script; it will exit automatically when you close VLC.

Menus cannot be bookmarked, because there is no title associated with them.

Usage:
$PROG without arguments will play a DVD in your drive. External drives will be detected.
$PROG /path/to/image/or/VIDEO_TS will play an iso image or VIDEO_TS folder on your harddisk. The filenames can have spaces in them.
$PROG -h or $PROG --help will print this help text and exit.
No other arguments are accepted.

EOF
exit
;;
*)
# DVD device (this is a DVD player only!):
if [ "$*" ]; 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="$(grep "udf" /etc/mtab | awk '{print $1}')"
# Helpful information for editing the data files manually; also needed for
# DVD disc_id:
DISK_LABEL="$(grep "udf" /etc/mtab | awk '{print $2}')"
fi
;;
esac

if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi



# Functions:
get_data () {
if [[ `grep -E 'title|get_time' $RESUMEFILE` ]]; then
FILE="$RESUMEFILE"
else
FILE="$DEFAULTFILE"
fi
for j in "$@"; do
eval "$j"=`grep "$j" $FILE | sed 's/[^[:digit:]]//g'`
done
}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}

# The point of the following function is that we don't have to introduce
# audio_id and sub_id variables on the majority of DVDs that don't need them.
# Audio tracks seem to be randomized on some DVDs when switching between titles,
# so the function is more complex than I'd like:
check_default () {
get_data audio_id sub_id
wait
if [[ $audio_id ]]; then
counter=0
until [[ $counter == 20 ]]; do #this is the sledgehammer part. Feel free to find
#a better solution. The point of the loop is to beat the crap out of sluggish
#DVD drives for not cooperating.
vlc_command atrack
wait
audio=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command atrack $audio
wait
vlc_command atrack
wait
audio1=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $audio1 ]] && [[ $audio == $audio1 ]]; then
break
fi
counter=`expr $counter + 1`
sleep 0.2
done
fi

if [[ $sub_id ]]; then
counter=0
if [[ $sub_id == 0 ]]; then
string='Disable'
else
string="Track $sub_id"
fi
until [[ $counter == 20 ]]; do
vlc_command strack
wait
sub=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command strack $sub
wait
vlc_command strack
sub1=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $sub1 ]] && [[ $sub == $sub1 ]]; then
#if [[ $sub = $sub1 ]]; then #safer
break
fi
counter=`expr $counter + 1`
sleep 0.2
done
fi
}

# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.
TMPFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d \: -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${PROG}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d \: -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s $TMPFILE ]]; then
DISC_ID=`md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi

wait



# Inventing extensions for the bookmark and resume files.
# Later we might invent corresponding mimetypes.
# For disc_id of libdvdread-0.9.7 replace ${DISC_ID} with 
# $(disc_id "$DVD_DEVICE")
touch "${BMDIR}/${DISC_ID}".vlcbmk
BOOKMARKFILE="${BMDIR}/${DISC_ID}".vlcbmk
touch "${BMDIR}/${DISC_ID}".resume
RESUMEFILE="${BMDIR}/${DISC_ID}".resume
touch "${BMDIR}/${DISC_ID}".default
DEFAULTFILE="${BMDIR}/${DISC_ID}".default
#echo "$DISK_LABEL" > "${BMDIR}/${DISC_ID}".disklabel

rm -f $MEDIADIR/data
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE RESUMEFILE DEFAULTFILE; do
eval echo $data=\$"$data" >> $MEDIADIR/data
done

# Get data:
get_data title get_time 
wait

# The following will wait for VLC to start and then switch to the correct audio
# and subtitle tracks if autodetection fails. Polling for logfile entries is
# necessary because "wait `pidof vlc`" or synonyms will fail with a "not a child
# of this shell" error:
(if [[ `grep -E 'audio_id|sub_id' $FILE` ]]; then
counter=0
until [[ $counter == 20 ]]; do
if [[ `grep -E 'libdvdread: Found|libdvdread: Couldn' $LOGFILE` ]]; then
#Could somebody please find a better search string?
check_default
break
fi
counter=`expr $counter + 1`
sleep 0.2
done
fi) &

# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. $title and $get_time can be
# empty, so these commands will work with empty bookmark and resume files. Using
# nohup is unreliable and unnecessary. The logfile is needed for reading VLC's
# output into variables, unfortunately).
# The following command will kill the correct instance of tail after VLC exits,
# so we don't have to start this script from the commandline; we can use the
# "open with" menu and desktop icons:
tail -f $MEDIADIR/fifo | (PID=`pidof -s tail` && vlc dvd://"$DVD_DEVICE"\#"$title" --start-time=$get_time --playlist-autostart --one-instance --extraintf "luaintf{intf=cli}" >> $LOGFILE 2>&1; kill $PID)
The bookmarking script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
if [ ! -d $MEDIADIR ]; then
mkdir -p $MEDIADIR
fi

# We need a file $MEDIADIR/data to store variables:
for data in LOGFILE BOOKMARKFILE RESUMEFILE DEFAULTFILE ; do
eval "$data"="$(grep "$data" "$MEDIADIR/data" | cut -d \= -f 2)"
done



# Functions:
get_var () {
#valid arguments: title get_time get_length get_remaining chapter (chapter is unreliable though)
for i in "$@"; do
echo "$i" > $MEDIADIR/fifo
wait
#the following commented line is for the original cli.lua; it does not work well:
#eval "$i"="$(cat $LOGFILE | grep -G [[:digit:]] | grep -v '\[' | tail -n 1 | sed "s/[^[:digit:]]//g")"
eval "$i"=`grep "ans_$i" $LOGFILE | tail -n 1 | sed 's/[^[:digit:]]//g'`
wait
done
}

get_resume () {
for j in "$@"; do
eval "$j"=`grep "$j" $RESUMEFILE | sed 's/[^[:digit:]]//g'`
done
}

get_default () {
for k in "$@"; do
eval "$k"=`grep "$k" $DEFAULTFILE | sed 's/[^[:digit:]]//g'`
done
}

# The point of the following function is that we don't have to introduce
# audio_id and sub_id variables on the majority of DVDs that don't need them.
# Audio tracks seem to be randomized on some DVDs when switching between titles,
# so the function is more complex than I'd like:
check_default () {
#sledgehammer
if [[ $audio_id ]]; then
counter=0
until [[ $counter == 20 ]]; do
vlc_command atrack
wait
audio=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command atrack $audio
wait
vlc_command atrack
wait
audio1=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $audio1 ]] && [[ $audio == $audio1 ]]; then
break
fi
counter=`expr $counter + 1`
sleep 0.2
done
fi

if [[ $sub_id ]]; then
counter=0
if [[ $sub_id == 0 ]]; then
string='Disable'
else
string="Track $sub_id"
fi
until [[ $counter == 20 ]]; do
vlc_command strack
wait
sub=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command strack $sub
wait
vlc_command strack
sub1=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $sub1 ]] && [[ $sub == $sub1 ]]; then
#if [[ $sub == $sub1 ]]; then #safer
break
fi
counter=`expr $counter + 1`
sleep 0.2
done
fi
}

set_resume () {
for m in "$@"; do
sed -i /$m/d $RESUMEFILE
eval echo "$m"=\$"$m" >> $RESUMEFILE
done
}

set_default () {
for n in "$@"; do
sed -i /$n/d $DEFAULTFILE
eval echo "$n"=\$"$n" >> $DEFAULTFILE
done
}

set_bookmark () {
echo -e $(expr `grep -o ^[[:digit:]]* $BOOKMARKFILE | tail -n 1` + 1)'\t'"$BMK" >> $BOOKMARKFILE
for o in "$@"; do
eval echo "$o"=\$"$o" >> $BOOKMARKFILE
done
}

vlc_command () {
echo "$*" > $MEDIADIR/fifo
}



case $1 in
-h|--help)
PROG=`basename $0`
cat << EOF
"$PROG" 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:
$PROG without arguments will create a resume bookmark and close VLC. The previous resume bookmark will be overwritten.

$PROG -b or $PROG --create-default will create a default bookmark at the current position to start the playback from. Unlike the resume bookmark this will not be overwritten unless you create a new default bookmark.

$PROG -c or $PROG --create will prompt for the name of a new bookmark to be created at the current position.

$PROG -l or $PROG --list will open a bookmark menu; choose one by number. The numbers will not be consecutive if you deleted bookmarks.

$PROG -r or $PROG --resume will start playback from the resume bookmark, if present.

$PROG -s or $PROG --start will start playback from the default bookmark, if present.

$PROG -u or $PROG --unset-resume will unset the resume bookmark. No functions for editing named bookmarks are provided; this is best done by editing the files manually.

$PROG -A or $PROG --set-atrack will set the current audio track on the current title as default.

$PROG -S or $PROG --set-strack will set the current subtitle track on the current title as default.

$PROG -T or $PROG --add-title will add the current title to the default bookmark, so audio and subtitle default settings will be applied to it. Multiple titles can be added. This has no effect on the default playback position.

$PROG -Z or $PROG --reload will reload audio and subtitle defaults from the default file, if present.

The last four options are useful if autodetection fails. Use them only if necessary. Especially, don't use the -S option on a title that has no subtitle tracks!

EOF
exit
;;
-l|--list)
SELECTION=$(zenity --entry --title="Bookmark List" --text "$(grep ^[[:digit:]] $BOOKMARKFILE)\n\nEnter the number of the selected bookmark:")
wait
if [ "$SELECTION" ]; then
title=$(grep -w -A 1 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
time=$(grep -w -A 2 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
wait
vlc_command title $title
wait
vlc_command seek $time
wait
if [[ `grep -E 'audio_id|sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "title=$title|preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
fi
;;
-A|--set-atrack)
vlc_command atrack
wait
vlc_command title
wait
get_var title
wait
audio_id=`grep -E 'Track.*\*' $LOGFILE | tail -n 1 | cut -d \  -f 5`
wait
#the resume bookmark may be on a different track
if [[ `grep -w -E "title=$title|preserve=$title" $DEFAULTFILE` ]]; then
set_default audio_id
else
set_resume audio_id
wait
fi
;;
-S|--set-strack)
vlc_command strack
wait
vlc_command title
wait
get_var title
wait
if [[ `grep -E 'Disable\ \*' $LOGFILE | tail -n 1` ]]; then
sub_id=0
else
sub_id=`grep -E 'Track.*\*' $LOGFILE | tail -n 1 | cut -d \  -f 5`
fi
wait
if [[ `grep -w -E "title=$title|preserve=$title" $DEFAULTFILE` ]]; then
set_default sub_id
wait
else
rm -f $RESUMEFILE
set_resume sub_id
wait
fi
;;
-u|--unset-resume)
rm -f $RESUMEFILE
;;
-T|--add-title)
get_var title
wait
echo "preserve=$title" >> $DEFAULTFILE
wait
;;
-Z|--reload)
if [[ `grep -E 'audio_id|sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "title=$title|preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
;;
-c|--create)
BMK=$(zenity --entry --title="New Bookmark" --text="A new bookmark will be created at the present position. Choose a name for it:")
if [ "$BMK" ]; then
get_var title get_time
wait
set_bookmark title get_time
wait
vlc_command play
wait
fi
;;
-b|--create-default)
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
wait
;;
-s|--start)
if [[ `grep -E 'title|get_time' $DEFAULTFILE` ]]; then
get_default title get_time
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
if [[ `grep -E 'audio_id|sub_id' $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
fi
;;
-r|--resume)
if [[ `grep -E 'title|get_time' $RESUMEFILE` ]]; then
get_resume title get_time 
wait
vlc_command title $title
wait
vlc_command seek $get_time
wait
if [[ `grep -E 'audio_id|sub_id' $RESUMEFILE` ]]; then
get_resume audio_id sub_id
wait
check_default
fi
fi
;;
*)
#audio_id and sub_id can be set manually with the -A and -S options
get_var title get_time
wait
set_resume title get_time
wait
if [[ `grep -E 'audio_id|sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "title=$title|preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
set_resume audio_id sub_id
wait
fi
vlc_command quit
wait
;;
esac
I can't understand why somebody didn't do this 10 years ago, when it would have
been of more use.

Last edited by nokangaroo; 03-28-2014 at 03:11 AM.
 
Old 05-09-2014, 04:27 AM   #5
nokangaroo
Member
 
Registered: Nov 2009
Posts: 141

Original Poster
Rep: Reputation: 25
Here is the final (probably; I have crammed in as much functionality as will go)
version of the dvdplayer script, which works very well by now (except that
scraping variables off the logfile is still bullshit). I decided to lose the
resumefile; about half my DVDs are indexed by now, and I already have major
clutter in my $BMDIR.



The dvdplayer script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# swiss-army sledgehammer for DVD playback and bookmarking using VLC
# needs modified cli.lua
# work in progress

PROG=`basename $0`
rm -f /tmp/${PROG}.${UID}.*

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"

# Bookmark folder:
BMDIR="$MEDIADIR/bookmarks"
if [ ! -d $BMDIR ]; then
mkdir -p $BMDIR
fi

# Logfile (needed for reading lua output into variables):
LOGFILE=`mktemp -q /tmp/${PROG}.${UID}.XXXXXXXXXX`

# Control file (fifo):
FIFO=`mktemp -u /tmp/${PROG}.${UID}.fifo.XXXXXXXXXX`
mkfifo -m 600 $FIFO

# Audio map for toggling audio tracks is created by the resuming script:
MAPFILE=/tmp/${PROG}.${UID}.audiomap

# These flagfiles can be used for per-bookmark commands (especially for book-
# marking alternate audio tracks with the resuming script's alt_audio function.
# As VLC's ordering of audio tracks can change when the DVD is started from a
# resume bookmark, hardcoded audio track commands won't work):
FLAG=/tmp/${PROG}.${UID}.flag



case $1 in
-h|--help)
cat << EOF
"$PROG" is a dvd player wrapper script for VLC. It is intended for use with the
resuming script, which can create user-defined bookmarks for every DVD you play:
a default bookmark to start playback from (usually the beginning of the movie),
a resume bookmark, and named bookmarks.

This script creates a folder $MEDIADIR and a folder $BMDIR inside it, where your
bookmarks are. They are identified by a function that concatenates the IFO files
in the VIDEO_TS folder and calculates the md5sum of the resulting file, which
should be reasonably unique. Iso images must be mounted before this calculation
can be performed, therefore this script requires fusermount and fuseiso.

You can create a desktop icon or an "open with" right-click menu entry to open
this script; it will exit automatically when you close VLC.

Menus cannot be bookmarked, because there is no title associated with them.


Usage:
$PROG without arguments will play a DVD in your drive. External drives will be
detected.

$PROG /path/to/image/or/VIDEO_TS will play an iso image or VIDEO_TS folder on
your harddisk. The filenames can have spaces in them.

$PROG -h or $PROG --help will print this help text and exit.

No other arguments are accepted.

EOF
exit
;;
*)
# DVD device (this is a DVD player only!):
if [ "$*" ]; 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="$(grep "udf" /etc/mtab | awk '{print $1}')"
# Helpful information for editing the data files manually; also needed for
# DVD disc_id:
DISK_LABEL="$(grep "udf" /etc/mtab | awk '{print $2}')"
fi
;;
esac

if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi



# Functions:
get_data () {
for j in "$@"; do
if [[ `grep "resume\@$j" $DEFAULTFILE` ]]; then
eval "$j"=`grep "resume\@$j" $DEFAULTFILE | sed -r 's/[^[:digit:]]//g'`
else 
eval "$j"=`grep -E "^$j" $DEFAULTFILE | sed -r 's/[^[:digit:]]//g'`
fi
done
}

vlc_command () {
echo "$*" > $FIFO
}

# The point of the following function is that we don't have to introduce
# audio_id and sub_id variables on the majority of DVDs that don't need them.
# This is the sledgehammer part. VLC's ordering and numbering of audio tracks
# cannot be relied on, and hardcoded audio track commands won't work if auto-
# detection of the correct language track fails.
check_default () {
vlc_command atrack -1
get_data audio_id sub_id
wait
if [[ $audio_id ]]; then
vlc_command atrack
wait
audio=`grep -B 8 'end of audio-es' $LOGFILE | tail -n 9 | grep "Track $audio_id" | tail -n 1 | cut -d \  -f 2`
wait
vlc_command atrack $audio
wait
fi
if [[ $sub_id ]]; then
if [[ $sub_id == 0 ]]; then
sub="-1"
else
vlc_command strack
wait
sub=`grep -B 32 'end of spu-es' $LOGFILE | tail -n 33 | grep "Track $sub_id" | tail -n 1 | cut -d \  -f 2`
wait
fi
vlc_command strack $sub
wait
fi
}

# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.
TMPFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d \: -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${PROG}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d \: -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s $TMPFILE ]]; then
DISC_ID=`md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi

wait



# Inventing extensions for the bookmark and default files.
# Later we might invent corresponding mimetypes.
# For disc_id of libdvdread-0.9.7 replace ${DISC_ID} with 
# $(disc_id "$DVD_DEVICE")
touch "${BMDIR}/${DISC_ID}".vlcbmk
BOOKMARKFILE="${BMDIR}/${DISC_ID}".vlcbmk
touch "${BMDIR}/${DISC_ID}".vlcdef
DEFAULTFILE="${BMDIR}/${DISC_ID}".vlcdef
#echo "$DISK_LABEL" > "${BMDIR}/${DISC_ID}".disklabel

rm -f $MEDIADIR/data
for data in LOGFILE DVD_DEVICE DISK_LABEL BOOKMARKFILE DEFAULTFILE MAPFILE FLAG FIFO; do
eval echo $data=\$"$data" >> $MEDIADIR/data
done

# Get data:
get_data title get_time 
wait
if [[ $title ]]; then
device="$DVD_DEVICE"\#"$title"
else
device="$DVD_DEVICE"
fi
if [[ $get_time ]]; then
starttime="--start-time=$get_time"
else
starttime=""
fi

# Miscellaneous settings that I found to be useful (more could be added):

# Adjust cache values to avoid jerky playback at chapter marks:
if [[ `grep 'file-caching' $DEFAULTFILE` ]]; then
fcache="--file-caching=`grep file-caching $DEFAULTFILE | cut -d \= -f 2`"
else
fcache=""
fi
if [[ `grep 'disc-caching' $DEFAULTFILE` ]]; then
dcache="--disc-caching=`grep disc-caching $DEFAULTFILE | cut -d \= -f 2`"
else
dcache=""
fi

# Some DVDs contain incorrect aspect ratio information:
if [[ `grep 'aspect' $DEFAULTFILE` ]]; then
aspect="--aspect-ratio=`grep aspect $DEFAULTFILE | cut -d \= -f 2`"
else
aspect=""
fi

# Custom video cropping:
if [[ `grep 'crop' $DEFAULTFILE` ]]; then
crop="--crop=`grep crop $DEFAULTFILE | cut -d \= -f 2`"
else
crop=""
fi

# Correct monitor pixel aspect ratio (Buffy Season 2! Try mpar=0.96):
if [[ `grep 'mpar' $DEFAULTFILE` ]]; then
stretch="--monitor-par=`grep mpar $DEFAULTFILE | cut -d \= -f 2`"
else
stretch=""
fi

# Custom video zoom:
if [[ `grep 'zoom' $DEFAULTFILE` ]]; then
zoom="--zoom=`grep zoom $DEFAULTFILE | cut -d \= -f 2` --no-autoscale"
else
zoom=""
fi

# Debugging:
if [[ `grep 'debug' $DEFAULTFILE` ]]; then
debug="--verbose=2"
else
debug=""
fi


# The following will wait for VLC to start and then switch to the correct audio
# and subtitle tracks if autodetection fails. Polling for logfile entries is
# necessary because "wait `pidof vlc`" or synonyms will fail with a "not a child
# of this shell" error:
(if [[ `grep -E '^audio_id|^sub_id' $DEFAULTFILE` ]] && [[ `grep -E "^title=$title|^preserve=$title" $DEFAULTFILE` ]]; then
counter0=0
until [[ $counter0 -eq 20 ]]; do
if [[ `grep -E 'libdvdread: Found|libdvdread: Could' $LOGFILE` ]]; then
if [[ "$*" ]]; then
sleep 0.3
else
sleep 1.5 #or revert to the loopy form of check_default which is ugly but faster
fi
check_default
break
fi
sleep 0.3
counter0=`expr $counter0 + 1`
done
fi) &



# Executing global commands in the bookmarkfile, such as switching the aspect
# ratio or disabling subtitles for certain titles:
(if [[ `grep -E '^global_commands@' $BOOKMARKFILE` ]]; then
counter1=0
until [[ $counter1 -eq 20 ]]; do
if [[ `grep -E 'libdvdread: Found|libdvdread: Could' $LOGFILE` ]]; then
if [[ "$*" ]]; then
sleep 0.3
else
sleep 1.5
fi
global_commands="$(grep -E '^global_commands@' $BOOKMARKFILE | cut -d \@ -f 2)"
wait
eval $global_commands
break
fi
sleep 0.3
counter1=`expr $counter1 + 1`
done
fi) &



# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. $title and $get_time can be
# empty, so these commands will work with empty bookmark and resume files. Using
# nohup is unreliable and unnecessary. The logfile is needed for reading VLC's
# output into variables, unfortunately).
# The following command will kill the correct instance of tail after VLC exits,
# so we don't have to start this script from the commandline; we can use the
# "open with" menu and desktop icons:
tail -f $FIFO | (PID=`pidof -s tail`; vlc dvd://"$device" $starttime $fcache $dcache $aspect $crop $stretch $zoom $debug --one-instance --extraintf "luaintf{intf=cli}" > $LOGFILE 2>&1; kill $PID)


The resuming script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"
if [ ! -d $MEDIADIR ]; then
mkdir -p $MEDIADIR
fi

# We need a file $MEDIADIR/data to store variables:
for data in LOGFILE BOOKMARKFILE DEFAULTFILE MAPFILE FLAG FIFO; do
eval "$data"="$(grep "$data" "$MEDIADIR/data" | cut -d \= -f 2)"
done



# Functions:
get_var () {
#valid arguments: title get_time get_length get_remaining chapter (chapter is unreliable though)
for i in "$@"; do
echo "$i" > $FIFO
wait
eval "$i"=`grep "ans_$i" $LOGFILE | tail -n 1 | sed -r 's/[^[:digit:]]//g'`
wait
done
}

get_resume () {
for j in "$@"; do
eval "$j"=`grep "resume\@$j" $DEFAULTFILE | sed -r 's/[^[:digit:]]//g'`
done
}

get_default () {
for k in "$@"; do
eval "$k"=`grep -E "^$k" $DEFAULTFILE | sed -r 's/[^[:digit:]]//g'`
done
}

check_default () {
#sledgehammer
vlc_command atrack -1
sleep 0.3
if [[ $audio_id ]]; then
vlc_command atrack
wait
audio=`grep -B 8 'end of audio-es' $LOGFILE | tail -n 9 | grep "Track $audio_id" | tail -n 1 | cut -d \  -f 2`
vlc_command atrack $audio
wait
fi
if [[ $sub_id ]]; then
if [[ $sub_id == 0 ]]; then
sub='-1'
else
vlc_command strack
wait
sub=`grep -B 32 'end of spu-es' $LOGFILE | tail -n 33 | grep "Track $sub_id" | tail -n 1 | cut -d \  -f 2`
fi
vlc_command strack $sub
wait
fi
}

set_resume () {
for m in "$@"; do
sed -i /"resume\@$m"/d $DEFAULTFILE
eval echo "resume\@$m"=\$"$m" >> $DEFAULTFILE
done
}

set_default () {
for n in "$@"; do
sed -i -r /"^$n"/d $DEFAULTFILE
eval echo "$n"=\$"$n" >> $DEFAULTFILE
done
}

set_bookmark () {
echo -e "$(expr `grep -o ^[[:digit:]]* $BOOKMARKFILE | tail -n 1` + 1)"'\t'"$BMK" >> $BOOKMARKFILE
wait
for o in "$@"; do
eval echo "$o"=\$"$o" >> $BOOKMARKFILE
done
}

vlc_command () {
echo "$*" > $FIFO
}

run_global () {
if [[ `grep -E '^global_commands@' $BOOKMARKFILE` ]]; then
global_commands="$(grep -E '^global_commands@' $BOOKMARKFILE | cut -d \@ -f 2)"
eval $global_commands
fi
}

alt_audio () {
#cycle through audio and commentary track(s)
#sledgehammer
if [[ `grep 'lang' $DEFAULTFILE` ]]; then
lang=`grep 'lang' $DEFAULTFILE | cut -d \= -f 2`
else
lang='English'
fi
if [[ ! -e $MAPFILE ]]; then
vlc_command atrack
wait
current=`grep -B 8 'end of audio-es' $LOGFILE | tail -n 9 | grep '*' | grep -v 'Disable' | cut -d \  -f 2`
other=`grep -B 8 'end of audio-es' $LOGFILE | tail -n 9 | grep "$lang" | grep -v '*' | grep -v 'Disable' | cut -d \  -f 2`
echo "$other" | tr ' ' '\n' > $MAPFILE
echo "$current" >> $MAPFILE
chmod 600 $MAPFILE
fi
audio=`cat $MAPFILE | head -n 1`
vlc_command atrack $audio
sed -i /"$audio"/d $MAPFILE
echo "$audio" >> $MAPFILE
}

case $1 in
-e|--edit)
gedit $BOOKMARKFILE $DEFAULTFILE #insert your favorite graphical editor here
;;
-h|--help)
PROG=`basename $0`
cat << EOF
"$PROG" 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:
$PROG without arguments will create a resume bookmark and close VLC. The
previous resume bookmark will be overwritten.

$PROG -b or $PROG --create-default will create a default bookmark at the
current position to start the playback from. Unlike the resume bookmark
this will not be overwritten unless you create a new default bookmark.

$PROG -c or $PROG --create will prompt for the name of a new bookmark to be
created at the current position.

$PROG -e or $PROG --edit will open the bookmark and default files in a graphical
editor.

$PROG -l or $PROG --list will open a bookmark menu; choose one by number. The
numbers will not be consecutive if you deleted bookmarks (it is of course
possible to edit them to be consecutive).

$PROG -r or $PROG --resume will start playback from the resume bookmark, if
present.

$PROG -s or $PROG --start will start playback from the default bookmark, if
present.

$PROG -u or $PROG --unset-resume will unset the resume bookmark.

$PROG -A or $PROG --set-atrack will set the current audio track on the
current title as default.

$PROG -S or $PROG --set-strack will set the current subtitle track on the
current title as default.

$PROG -C or $PROG --crop <crop ratio> will force display cropping.

$PROG -D or $PROG --disc-caching <disc-caching value in ms> will set a custom
disc caching value to override the VLC config setting.

$PROG -F or $PROG --file-caching <file-caching value in ms> will set a custom
file caching value to override the VLC config setting.

$PROG -M or $PROG --monitor-par <monitor pixel aspect ratio> will stretch or
pinch the display if necessary.

$PROG -R or $PROG --aspect <aspect ratio> will force the display aspect ratio.

$PROG -T or $PROG --add-title will add the current title to the default
bookmark, so audio and subtitle default settings will be applied to it.
Multiple titles can be added. This has no effect on the default playback
position.

$PROG -X or $PROG --alt-audio will switch between audio tracks of the language
specified in the script (useful for switching to the commentary track(s) and
back).

$PROG -Z or $PROG --reload will reload audio and subtitle defaults from the
default file, if present.

The capitalized options are useful if default settings fail. Use them only
if necessary.

For many of these options, see also the VLC documentation.

EOF
exit
;;
-l|--list)
TEXT="$(grep -E ^[[:digit:]] $BOOKMARKFILE)"
if [[ -n "$TEXT" ]]; then
#The width and height functions in the following are empirical and unscientific,
#and, as usual, I shouldn't have to do it that way anyway. Why the hell does the
#dialog window not resize automatically?
SELECTION=$(echo -e "$TEXT" | zenity --list --width="$(echo "(`echo -e "$TEXT" | wc -L` * 7) + 40" | bc)" --height="$(echo "(`echo -e "$TEXT" | wc -l` * 21) + 90" | bc)" --title="Bookmarks" --text="Select a bookmark:" --column="" --hide-header --timeout=30)
wait
else
zenity --info --text='No bookmarks yet.' --timeout=2
fi
if [ "$SELECTION" ]; then
vlc_command pause
get_var title
wait
oldtitle=$title
title=$(grep -w -A 1 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
if [[ $title != $oldtitle ]]; then
vlc_command title $title
if [[ `grep -E '^audio_id|^sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "^title=$title|^preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
fi
run_global
if [[ `echo $(grep -w -A 3 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \@ -f 1)` == 'commands' ]]; then
commands="$(grep -w -A 3 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \@ -f 2)"
eval $commands
fi
get_time=$(grep -w -A 2 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
vlc_command seek $get_time
vlc_command play
fi
;;
-A|--set-atrack)
vlc_command title
wait
get_var title
wait
vlc_command atrack
wait
audio_id=`grep -E 'Track.*\*' $LOGFILE | tail -n 1 | cut -d \  -f 5`
wait
set_default audio_id
wait
;;
-S|--set-strack)
vlc_command title
wait
get_var title
wait
vlc_command strack
wait
if [[ `grep -E 'Disable\ \*' $LOGFILE | tail -n 1` ]]; then
sub_id=0
else
sub_id=`grep -E 'Track.*\*' $LOGFILE | tail -n 1 | cut -d \  -f 5`
fi
wait
set_default sub_id
;;
-u|--unset-resume)
for x in title get_time audio_id sub_id ; do
sed -i /"resume\@$x"/d $DEFAULTFILE
done
;;
-M|--monitor-par)
sed -i /mpar/d $DEFAULTFILE
echo "mpar=$2" >> $DEFAULTFILE
wait
vlc_command atrack -1
sleep 0.2
vlc_command quit
;;
-T|--add-title)
get_var title
wait
echo "preserve=$title" >> $DEFAULTFILE
wait
;;
-D|--disc-caching)
sed -i /disc-caching/d $DEFAULTFILE
echo "disc-caching=$2" >> $DEFAULTFILE
wait
vlc_command atrack -1
sleep 0.2
vlc_command quit
;;
-F|--file-caching)
sed -i /file-caching/d $DEFAULTFILE
echo "file-caching=$2" >> $DEFAULTFILE
wait
vlc_command atrack -1
sleep 0.2
vlc_command quit
;;
-C|--crop)
sed -i /crop/d $DEFAULTFILE
echo "crop=$2" >> $DEFAULTFILE
wait
;;
-R|--aspect)
sed -i /aspect/d $DEFAULTFILE
echo "aspect=$2" >> $DEFAULTFILE
wait
;;
-X|--alt-audio)
alt_audio
;;
-Z|--reload)
#if [[ `grep -E '^audio_id|^sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "^title=$title|^preserve=$title" $DEFAULTFILE` ]]; then
#run_global
if [[ `grep -E '^audio_id|^sub_id' $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
;;
-c|--create)
BMK=$(zenity --entry --title="New Bookmark" --text="A new bookmark will be created at the present position. Choose a name for it:")
if [[ $BMK ]]; then
get_var title get_time
wait
set_bookmark title get_time
wait
vlc_command play
wait
fi
;;
-b|--create-default)
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
wait
;;
-s|--start)
if [[ `grep -E '^title|^get_time' $DEFAULTFILE` ]]; then
get_var title
wait
oldtitle=$title
get_default title get_time
wait
if [[ $title != $oldtitle ]]; then
vlc_command title $title
wait
if [[ `grep -E '^audio_id|^sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "^title=$title|^preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
fi
vlc_command seek $get_time
wait
run_global
fi
;;
-r|--resume)
if [[ `grep "resume\@" $DEFAULTFILE` ]]; then
get_var title
wait
oldtitle=$title
get_resume title get_time 
wait
if [[ $title != $oldtitle ]]; then
vlc_command title $title
wait
if [[ `grep -E '^audio_id|^sub_id' $DEFAULTFILE` ]] && [[ `grep -w -E "^title=$title|^preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
fi
vlc_command seek $get_time
wait
run_global
fi
;;
*)
get_var title get_time
wait
set_resume title get_time
wait
vlc_command atrack -1
sleep 0.2
vlc_command quit
;;
esac


A sample bookmark file, illustrating the commands@ function (The global commands
are executed with every bookmark and at startup, the per-bookmark commands only
with the associated bookmark):
Code:
The bookmarkfiles can contain commentaries; anything before the first bookmark
or between bookmarks (not between lines belonging to the same bookmark, of
course) that does not start with "global_commands@" or a digit is ignored.

The following global command is a workaround for messed-up DVD authoring (or is
it a VLC bug? The audio track order depends on the setting of the resumefile,
that is, the entry point of the DVD, therefore hardcoded audio track commands
won't work). The "sledgehammer" function can also be used with some DVDs,
defining a new audio_id and running check_default.

This command is too complicated for comfort; but if one does not insist on
bookmarking alternate audio tracks things will be much easier. The point is it
can be done.

Commands like "global_commands@if [[ $SELECTION -eq 3 ]] && [[ $get_time -gt 1000 ]]; then vlc_command crop 4:3; else vlc_command crop 16:9; fi"
are possible (though that one was a fantasy). All resumer script variables and
functions can be used.

(End of commentary)

global_commands@if [[ $title -le 3 ]] && [[ -e $FLAG ]]; then sleep 0.4; alt_audio; fi; rm -f $FLAG; if [[ $title -gt 3 ]]; then rm -f $MAPFILE; fi
1	Touched
title=1
get_time=74
2	End Of Days
title=2
get_time=55
3	Chosen
title=3
get_time=37
4	Chosen (Director's Comments)
title=3
get_time=36
commands@if [[ ! -e $FLAG ]]; then sleep 0.4; alt_audio; touch $FLAG; fi
5	Featurette: Season 7 Overview
title=7
get_time=60
6	Featurette: Buffy 101
title=8
get_time=24
7	Featurette: Generation S
title=9
get_time=38
8	Featurette: The Last Sundown
title=10
get_time=0
9	Featurette: Outtakes
title=5
get_time=7
10	Featurette: Buffy Wraps
title=6
get_time=0


The patch for cli.lua (the get_remaining function is optional; I included it
because it was easy to do without actually knowing any lua, but it is not used
in the scripts)

lua.diff:
Code:
--- cli.lua	2013-06-24 20:00:39.000000000 +0200
+++ cli-modified.lua	2014-04-03 20:12:13.115317408 +0200
@@ -430,23 +430,31 @@
     return function(name,client)
         local input = vlc.object.input()
 	if input then
-	    client:append(math.floor(vlc.var.get( input, var )))
+	    client:append("ans_" .. tostring(name) .. "=" .. math.floor(vlc.var.get( input, var )) .. '\n')
 	else
 	    client:append("")
 	end
     end
 end
 
+function get_remaining(name,client)
+	local input = vlc.object.input()
+	local var = math.floor((vlc.var.get( input, "length") - (vlc.var.get(input, "time"))))
+	if input then
+		client:append("ans_get_remaining=" .. var .. '\n')
+		else
+		client:append("")
+	end
+end
+
 function titlechap(name,client,value)
     local input = vlc.object.input()
     local var = string.gsub( name, "_.*$", "" )
     if value then
         vlc.var.set( input, var, value )
-    else
-        local item = vlc.var.get( input, var )
-        -- Todo: add item name conversion
-        client:append(item)
     end
+    local item = vlc.var.get( input, var )
+    client:append("ans_" .. tostring(var) .. "=" .. item .. '\n')
 end
 
 function titlechap_offset(var,offset)
@@ -578,6 +586,7 @@
     { "is_playing"; { func = is_playing; help = "1 if a stream plays, 0 otherwise" } };
     { "get_title"; { func = get_title; help = "the title of the current stream" } };
     { "get_length"; { func = get_time("length"); help = "the length of the current stream" } };
+    { "get_remaining"; {func = get_remaining; help = "the remaining time in the current stream" } };
     { "" };
     { "volume"; { func = volume; args = "[X]"; help = "set/get audio volume" } };
     { "volup"; { func = ret_print(vlc.volume.up,"( audio volume: "," )"); args = "[X]"; help = "raise audio volume X steps" } };


The loopy version of check_default (only makes sense at startup; not needed in
the resuming script):
Code:
check_default () {
get_data audio_id sub_id
wait
if [[ $audio_id ]]; then
counter=0
until [[ $counter == 20 ]]; do #this is the sledgehammer part. Feel free to find
#a better solution. The point of the loop is to beat the crap out of sluggish
#DVD drives for not cooperating.
sleep 0.2
vlc_command atrack
wait
audio=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command atrack $audio
wait
vlc_command atrack
wait
audio1=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $audio1 ]] && [[ $audio == $audio1 ]]; then
break
fi
counter=`expr $counter + 1`
done
fi

if [[ $sub_id ]]; then
counter=0
if [[ $sub_id == 0 ]]; then
string='Disable'
else
string="Track $sub_id"
fi
until [[ $counter == 20 ]]; do
sleep 0.2
vlc_command strack
wait
sub=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command strack $sub
wait
vlc_command strack
sub1=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $sub1 ]] && [[ $sub == $sub1 ]]; then
#if [[ $sub == $sub1 ]]; then #safer
break
fi
counter=`expr $counter + 1`
done
fi
}
 
Old 07-31-2014, 10:50 AM   #6
nokangaroo
Member
 
Registered: Nov 2009
Posts: 141

Original Poster
Rep: Reputation: 25
Here is another update for the dvdplayer scripts:

The dvdplayer script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


# needs modified cli.lua


#VLC=/usr/bin/vlc
VLC=/usr/local/bin/vlc

# Media folder:
MEDIADIR="$HOME/vlc-DVDdata"

# Bookmark folder:
BMDIR="$MEDIADIR/bookmarks"
if [ ! -d $BMDIR ]; then
mkdir -p $BMDIR
fi

PROG=`basename $0`
rm -f /tmp/${PROG}.${UID}.*
rm -f $MEDIADIR/{audiomap,data,flag,tmp,list}

# Logfile (needed for reading lua output into variables):
LOGFILE=`mktemp -q /tmp/${PROG}.${UID}.log.XXXXXXXXXX`

# Put dvdread output into a different file (only needed at startup):
LOGFILE0=`mktemp -q /tmp/${PROG}.${UID}.status.XXXXXXXXXX`

# Control file (fifo):
FIFO=`mktemp -u /tmp/${PROG}.${UID}.fifo.XXXXXXXXXX`
mkfifo -m 600 $FIFO


case $1 in
-h|--help)
cat << EOF
This is a dvd player wrapper script for VLC. It is intended for use with the
resuming script, which can create user-defined bookmarks for every DVD you play:
a default bookmark to start playback from (usually the beginning of the movie),
a resume bookmark, and named bookmarks.

This script creates a folder
$MEDIADIR
and a folder
$BMDIR
inside it, where your bookmarks are. They are identified by a function that
concatenates the IFO files in the VIDEO_TS folder and calculates the md5sum
of the resulting file, which should be reasonably unique. ISO images must
be mounted before this calculation can be performed, therefore this script
requires fusermount and fuseiso.

You can create a desktop icon or an "open with" right-click menu entry to
open this script; it will exit automatically when you close VLC.

Menus cannot be bookmarked, because there is no title associated with them.

Usage:
Calling this script without arguments will play a DVD in your drive.
External drives will be detected.

$PROG /path/to/image/or/VIDEO_TS
will play an iso image or VIDEO_TS folder on your harddisk.
The filenames can have spaces in them.

$PROG -h or $PROG --help
will print this help text and exit.

No other arguments are accepted.

EOF
exit
;;
*)
# DVD device (this is a DVD player only!):
if [ "$*" ]; 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="$(grep "udf" /etc/mtab | awk '{print $1}')"
# Helpful information for editing the data files manually; also needed for
# DVD disc_id:
DISK_LABEL="$(grep "udf" /etc/mtab | awk '{print $2}')"
fi
;;
esac

if [ -z "$DISK_LABEL" ]; then
DISK_LABEL="$DVD_DEVICE"
fi



# Functions:
get_data () {
local j
for j in "$@"; do
if [[ `grep "resume@$j" $DEFAULTFILE` ]]; then
eval "$j"=`grep -w -o "^resume@$j=[0-9]\+" $DEFAULTFILE | cut -d \= -f 2`
else
eval "$j"=`grep -w -o "^$j=[0-9]\+" $DEFAULTFILE | cut -d \= -f 2`
fi
done
}

vlc_command () {
echo "$*" > $FIFO
}

# The point of the following function is that we don't have to introduce
# audio_id and sub_id variables on the majority of DVDs that don't need them.
# This is the sledgehammer part. VLC's ordering and numbering of audio tracks
# cannot be relied on, and hardcoded audio track commands won't work if auto-
# detection of the correct language track fails.
check_default () {
local audio
local sub
local audio1
local sub1
local x
local y
get_data audio_id sub_id
#wait
if [[ $audio_id ]]; then
x=0
until [[ $x == 20 ]]; do #this is the sledgehammer part. Feel free to find
#a better solution. The point of the loop is to beat the crap out of sluggish
#DVD drives for not cooperating.
sleep 0.2
vlc_command atrack
#wait
audio=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command atrack $audio
#wait
vlc_command atrack
#wait
audio1=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $audio1 ]] && [[ $audio == $audio1 ]]; then
break
fi
x=`expr $x + 1`
done
fi

if [[ $sub_id ]]; then
y=0
if [[ $sub_id == 0 ]]; then
string='Disable'
else
string="Track $sub_id"
fi
until [[ $y == 20 ]]; do
sleep 0.2
vlc_command strack
#wait
sub=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command strack $sub
#wait
vlc_command strack
sub1=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $sub1 ]] && [[ $sub == $sub1 ]]; then
#if [[ $sub == $sub1 ]]; then #safer
break
fi
y=`expr $y + 1`
done
fi
}

# 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 function, which does not use
# dvdnav, will differ from disc_id; it should be unique though.
TMPFILE=`mktemp -q /tmp/${PROG}.XXXXXXXX`
if [[ "$(echo `file "$DVD_DEVICE" | cut -d \: -f 2 | grep UDF`)" ]]; then
TMPDIR=`mktemp -d -q /tmp/${PROG}.mnt.XXXXXXXX`
fuseiso -p "$DVD_DEVICE" "$TMPDIR"
DISC="$TMPDIR"
else
DISC="$DISK_LABEL"
fi
cat "$DISC"/{VIDEO_TS,video_ts}/*{IFO,ifo} >> $TMPFILE 2>/dev/null
wait
if [[ "$(echo `file "$DVD_DEVICE" | cut -d \: -f 2 | grep UDF`)" ]]; then
fusermount -u "$TMPDIR"
fi
if [[ -s $TMPFILE ]]; then
DISC_ID=`md5sum "$TMPFILE" | cut -d \  -f 1`
rm "$TMPFILE"
else
rm "$TMPFILE"
exit 1
fi

wait



# The bookmark and defaults files (for disc_id of libdvdread-0.9.7 replace
# ${DISC_ID} with $(disc_id "$DVD_DEVICE"):
BOOKMARKFILE=${BMDIR}/${DISC_ID}.vlcbmk
touch -c $BOOKMARKFILE #don't create any empty files
DEFAULTFILE=${BMDIR}/${DISC_ID}.vlcdef
touch -c $DEFAULTFILE
if [[ -f $DEFAULTFILE ]] && [[ -z `grep "$DISK_LABEL" $DEFAULTFILE` ]]; then
sed -i /device/d $DEFAULTFILE
echo 'device='"$DISK_LABEL" >> $DEFAULTFILE
fi

# Workaround for matedialog, which does not work reliably with piped input.
# Anyway, it seems more efficient to run sed over the bookmark file only when
# it changes, and not every time you open it:
LISTFILE=${MEDIADIR}/list
if [[ -f $BOOKMARKFILE ]]; then
sed -n '/^[0-9]\+\t.*$/ P' $BOOKMARKFILE > $LISTFILE
# These values will be dependent on the gtk theme used (and probably on the
# screen resolution) and have to be found out by experiment:
DISPLAY_WIDTH="$(echo "(`wc -L < $LISTFILE` * 7) + 44" | bc)"
DISPLAY_HEIGHT="$(echo "(`wc -l < $LISTFILE` * 23) + 86" | bc)"
fi

# Data for the bookmarking script to source. This will handle spaces in file
# names:
for data in LOGFILE FIFO DVD_DEVICE DISK_LABEL BOOKMARKFILE DEFAULTFILE LISTFILE DISPLAY_WIDTH DISPLAY_HEIGHT; do
eval echo $data=\$"$data" | sed 's/ /\\ /g' >> $MEDIADIR/data
done

# Get startup data from the defaults file:
get_data title get_time 
wait
if [[ $title ]]; then
device="$DVD_DEVICE"\#"$title"
else
device="$DVD_DEVICE"
fi
if [[ $get_time ]]; then
starttime="--start-time=$get_time"
else
starttime=""
fi



# Miscellaneous settings that I found to be useful (more could be added):

# Adjust cache values to avoid jerky playback at chapter marks:
if [[ `grep '^file-caching' $DEFAULTFILE` ]]; then
fcache="--file-caching=`grep '^file-caching' $DEFAULTFILE | cut -d \= -f 2`"
else
fcache=""
fi
if [[ `grep '^disc-caching' $DEFAULTFILE` ]]; then
dcache="--disc-caching=`grep '^disc-caching' $DEFAULTFILE | cut -d \= -f 2`"
else
dcache=""
fi

# Some DVDs contain incorrect aspect ratio information:
if [[ `grep '^aspect' $DEFAULTFILE` ]]; then
aspect="--aspect-ratio=`grep '^aspect' $DEFAULTFILE | cut -d \= -f 2`"
else
aspect=""
fi

# Custom video cropping:
if [[ `grep '^crop' $DEFAULTFILE` ]]; then
crop="--crop=`grep '^crop' $DEFAULTFILE | cut -d \= -f 2`"
else
crop=""
fi

# Correct monitor pixel aspect ratio (Buffy Season 2! Try mpar=0.96):
if [[ `grep '^mpar' $DEFAULTFILE` ]]; then
stretch="--monitor-par=`grep '^mpar' $DEFAULTFILE | cut -d \= -f 2`"
else
stretch=""
fi

# Custom video zoom:
if [[ `grep '^zoom' $DEFAULTFILE` ]]; then
zoom="--zoom=`grep '^zoom' $DEFAULTFILE | cut -d \= -f 2` --no-autoscale"
else
zoom=""
fi

# Debugging:
if [[ `grep '^debug' $DEFAULTFILE` ]]; then
debug="--verbose=2"
else
debug="--quiet"
fi

# Custom commandline (could of course replace all of the above):
if [[ `grep '^custom@' $DEFAULTFILE` ]]; then
custom=`grep '^custom@' $DEFAULTFILE | cut -d \@ -f 2`
else
custom=""
fi

# Custom configfile (don't want to use this by default to avoid clutter):
if [[ `grep '^custom_config' $DEFAULTFILE` ]]; then
custom_conf="--config=$MEDIADIR/vlcrc/${DISC_ID}.vlcrc"
if [[ ! -d $MEDIADIR/vlcrc ]]; then
mkdir -p $MEDIADIR/vlcrc
fi
if [[ ! -f $MEDIADIR/vlcrc/${DISC_ID}.vlcrc ]]; then
cp $HOME/.config/vlc/vlcrc $MEDIADIR/vlcrc/${DISC_ID}.vlcrc
fi
else
custom_conf=""
fi



# Starting VLC with fifo input and generating logfile (The --extraintf option
# enables use of right-click menus and controller. $title and $get_time can be
# empty, so these commands will work with empty bookmark and resume files. Using
# nohup is unreliable and unnecessary. The logfile is needed for reading VLC's
# output into variables, unfortunately).
# The following command will kill the correct instance of tail after VLC exits,
# so we don't have to start this script from the commandline; we can use the
# "open with" menu and desktop icons:
tail --follow=name "$FIFO" | (sleep 0.1; PID=`pidof -s tail`; $VLC dvd://"$device" $starttime $fcache $dcache $aspect $crop $stretch $zoom $debug $custom $custom_conf --one-instance --extraintf="luaintf{intf=cli}" 1>$LOGFILE 2>$LOGFILE0; kill $PID) &

# The following will wait for VLC to start and then switch to the correct audio
# and subtitle tracks if autodetection fails. Polling for logfile entries is
# necessary because "wait `pidof vlc`" or synonyms will fail with a "not a child
# of this shell" error:
(if [[ `grep '^audio_id\|^sub_id' $DEFAULTFILE` ]] && [[ `grep "^title=$title\|^preserve=$title" $DEFAULTFILE` ]]; then
counter=0
until [[ $counter -eq 20 ]]; do
if [[ `grep 'libdvdread: Found\|libdvdread: Could' $LOGFILE0` ]]; then
if [[ -z "$*" ]]; then
sleep 2.5
fi
check_default
break
fi
sleep 0.3
counter=`expr $counter + 1`
done
fi) &

# Executing global commands in the bookmarkfile, such as switching the aspect
# ratio or disabling subtitles for certain titles:
(if [[ `grep '^global_commands@' $BOOKMARKFILE` ]]; then
counter1=0
until [[ $counter1 -eq 20 ]]; do
if [[ `grep 'libdvdread: Found\|libdvdread: Could' $LOGFILE0` ]]; then
if [[ -z "$*" ]]; then
sleep 1.5
fi
global_commands="$(grep '^global_commands@' $BOOKMARKFILE | cut -d \@ -f 2)"
wait
eval $global_commands
break
fi
sleep 0.3
counter1=`expr $counter1 + 1`
done
fi) &
The bookmarking script:
Code:
#!/bin/bash
# Copyright (C) 2014 nokangaroo nokangaroo@NOSPAM.aon.at

# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.



# Bookmark script for use with the dvdplayer script
# needs modified cli.lua
# work in progress



# Media folder:
MEDIADIR="${HOME}/vlc-DVDdata"
if [[ ! -d $MEDIADIR ]]; then
if [[ $1 == '-h' ]] || [[ $1 == '--help' ]]; then
continue
else
zenity --info --text 'You need to start VLC with the DVD player script first!' --timeout=3
exit
fi
fi

# Set the path to the DVD player script here:
DVDPLAYER=""  #/path/to/dvdplayer-script


# Functions:

vlc_command () {
echo "$*" > $FIFO
}

get_var () {
# Valid arguments: title get_time get_length get_remaining chapter
# (chapter will only work with vlc-2.2.0 or later)
local i
for i in "$@"; do
echo "$i" > $FIFO
sleep 0.1
eval "$i"=`grep -w -o "ans_$i=[0-9]\+" $LOGFILE | tail -n 1 | cut -d \= -f 2`
wait
done
}

get_resume () {
local j
for j in "$@"; do
eval "$j"=`grep -w -o "^resume@$j=[0-9]\+" $DEFAULTFILE | cut -d \= -f 2`
done
}

get_default () {
local k
for k in "$@"; do
eval "$k"=`grep -w -o "^$k=[0-9]\+" $DEFAULTFILE | cut -d \= -f 2`
done
}

check_default () {
local audio
local sub
local audio1
local sub1
local x
local y
local string
sleep 0.3
if [[ $audio_id ]]; then
x=0
until [[ $x == 20 ]]; do
sleep 0.2
vlc_command atrack
#wait
audio=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command atrack $audio
#wait
vlc_command atrack
#wait
audio1=`grep "Track $audio_id" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $audio1 ]] && [[ $audio == $audio1 ]]; then
break
fi
x=`expr $x + 1`
done
fi

if [[ $sub_id ]]; then
y=0
if [[ $sub_id == 0 ]]; then
string='Disable'
else
string="Track $sub_id"
fi
until [[ $y == 20 ]]; do
sleep 0.2
vlc_command strack
#wait
sub=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
vlc_command strack $sub
#wait
vlc_command strack
sub1=`grep "$string" $LOGFILE | tail -n 1 | cut -d \  -f 2`
if [[ $sub1 ]] && [[ $sub == $sub1 ]]; then
break
fi
y=`expr $y + 1`
done
fi
}

set_resume () {
local m
for m in "$@"; do
sed -i /"resume@$m"/d $DEFAULTFILE
eval echo "resume@$m"=\$"$m" >> $DEFAULTFILE
done
}

set_default () {
local n
for n in "$@"; do
sed -i -r /"^$n"/d $DEFAULTFILE
eval echo "$n"=\$"$n" >> $DEFAULTFILE
done
}

set_bookmark () {
echo -e "$(expr `grep -o ^[0-9]* $BOOKMARKFILE | sort -n | tail -n 1` + 1)"'\t'"$BMK" >> $BOOKMARKFILE
wait
local o
for o in "$@"; do
eval echo "$o"=\$"$o" >> $BOOKMARKFILE
done
}

run_global () {
if [[ `grep '^global_commands@' $BOOKMARKFILE` ]]; then
global_commands="$(grep '^global_commands@' $BOOKMARKFILE | cut -d \@ -f 2)"
eval $global_commands
fi
}

alt_audio () {
# Cycle through audio and commentary track(s)
local lang
local current
local other
local audio
if [[ `grep '^lang' $DEFAULTFILE` ]]; then
lang=`grep '^lang' $DEFAULTFILE | cut -d \= -f 2`
else
lang='English'
fi
if [[ ! -e $MAPFILE ]]; then
vlc_command atrack
wait
current=`grep -B 8 'end of audio-es' $LOGFILE | tail -n 9 | grep '*' | grep -v 'Disable' | cut -d \  -f 2`
other=`grep -B 8 'end of audio-es' $LOGFILE | tail -n 9 | grep "$lang" | grep -v '*' | grep -v 'Disable' | cut -d \  -f 2`
echo "$other" | tr ' ' '\n' > $MAPFILE
echo "$current" >> $MAPFILE
fi
audio=`cat $MAPFILE | head -n 1`
vlc_command atrack $audio
sed -i /"$audio"/d $MAPFILE
echo "$audio" >> $MAPFILE
}

quit_vlc () {
get_var title get_time
wait
set_resume title get_time
wait
vlc_command atrack -1
sleep 0.2
vlc_command quit
}

check_title () {
if [[ $title != $oldtitle ]]; then
vlc_command title $title
if [[ `grep '^audio_id\|^sub_id' $DEFAULTFILE` ]] && [[ `grep -w "^title=$title\|^preserve=$title" $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
fi
}

sequential () {
# Make bookmark numbers sequential after manual reordering 
local NUM
local LINES
local i
NUM=1
LINES=`sed -n '/^[0-9]\+\t/ =' $BOOKMARKFILE`
for i in $LINES; do
sed -i "$i s/^[0-9]*/$NUM/" $BOOKMARKFILE
NUM=`expr $NUM + 1`
done
}

################################################################################
# The following functions can be used to play text pages in DVDs (Buffy,
# X-Files). The command in the bookmark file is:
# commands@play_text <title> <startchapter>
# startchapter is usually 2
# the "title" and "get_time" lines created by the bookmarking function should
# be deleted, they are not needed (but leave the blank lines in! The commands@
# line must be in the 3rd line after the bookmark)
# add dvdsimple://$DVD_DEVICE#$1:$2 etc. won't work properly; VLC's playlist
# interface is totally unsuited for DVD playback, and playlist items have
# arbitrary IDs that would be cumbersome to keep track of.
################################################################################

# You will probably want both functions:
play_text () {
quit_vlc
sleep 0.3
(mplayer -fs dvd://"$1" -dvd-device "$DVD_DEVICE" -chapter "$2" -speed 0.02 -nocache) &
echo "PLAYER=mplayer" >> ${MEDIADIR}/data
}

play_text1 () {
# vlc_command add dvdsimple://$DVD_DEVICE#$1:$2 etc. won't work properly
quit_vlc
sleep 0.3
# Playback control is with the space bar - don't set the rate too low, just low
# enough that you have time to hit the space bar
(vlc dvdsimple://${DVD_DEVICE}#"$1":"$2" --rate=0.8) &
echo "PLAYER=vlc" >> ${MEDIADIR}/data
}

# End of functions block



# Get variables:
. ${MEDIADIR}/data

# Restart after watching text files on a DVD:
if [[ $DVDPLAYER ]] && [[ $PLAYER ]]; then
kill `pgrep -U $USER $PLAYER`
sleep 0.3
if [[ $DVD_DEVICE =~ /dev ]]; then
DVD_DEVICE=""
fi
($DVDPLAYER $DVD_DEVICE) &
exit
fi



# Audio map for toggling audio tracks:
MAPFILE=${MEDIADIR}/audiomap

# These flagfiles can be used for per-bookmark commands (especially for book-
# marking alternate audio tracks with the resuming script's alt_audio function.
# As VLC's ordering of audio tracks can change when the DVD is started from a
# resume bookmark, hardcoded audio track commands won't work):
FLAG=${MEDIADIR}/flag



case $1 in
-e|--edit)
# Insert your favourite graphical editor here (and force it to open a single
# window):
[[ -f $BOOKMARKFILE ]] && DOCUMENT[1]=$BOOKMARKFILE
[[ -f $DEFAULTFILE ]] && DOCUMENT[2]=$DEFAULTFILE
[[ ${DOCUMENT[@]} ]] && gedit ${DOCUMENT[@]}
;;
-m|--menu)
vlc_command title 0
;;
-u|--unset-resume)
for x in title get_time audio_id sub_id ; do
sed -i /"resume@$x"/d $DEFAULTFILE
done
;;
-x|--alt-audio)
alt_audio
;;
-y|--sequential)
sequential
;;
-h|--help)
cat << EOF
This 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 shortcuts to its various options.

Some of the options require arguments; they are indicated in angle brackets.


Calling this script without options will create a resume bookmark and close
VLC. The previous resume bookmark will be overwritten.


Options:

-b  --create-default    will create a default bookmark at the
                        current position to start the playback from.
                        Unlike the resume bookmark this will not be
                        overwritten unless you create a new default
                        bookmark.

-c  --create            will prompt for the name of a new bookmark
                        to be created at the current position.

-e  --edit              will open the bookmark and default files in a
                        graphical editor.

-k  --commentary        will add code to the last created bookmark to
                        switch to the alternative audio track of the
                        same language. This will fail if there are more
                        than two audio tracks of the same language,
                        but this script has a function (see below) to
                        do the switching manually.
                        The commands@ and global_commands@ lines will
                        have to be edited manually if the DVD has a
                        complex structure.

-l  --list              will open a bookmark menu; choose one by number,
                        scrolling or double-clicking. The numbers will
                        not be consecutive if you deleted bookmarks
                        (it is of course possible to edit them to be
                        consecutive; see below).

-m  --menu              calls title 0, which on most DVDs will go to
                        the current DVD submenu without always jumping
                        back to the root menu (one of the most annoying
                        features of VLC; the root menu on most DVDs is
                        in front of all the nag screens).

-q  --create-clip       will add code to the last created bookmark to
                        turn it into an infinitely repeating video clip
                        that starts at the time specified in the bookmark
                        and ends (approximately; manual editing may be
                        required) at the time you call this option.
                        To exit the clip, do "killall `basename $0`".

-r  --resume            will start playback from the resume bookmark,
                        if present.

-s  --start             will start playback from the default bookmark,
                        if present.

-u  --unset-resume      will unset the resume bookmark.

-x  --alt-audio         will switch between audio tracks of the language
                        specified in the script (useful for switching to
                        the commentary track(s) and back).

-y  --sequential        will restore consecutive bookmark numbers
                        in the bookmark file of the current DVD
                        after manual reordering of bookmarks.

-A  --set-atrack        will set the current audio track on the
                        current title as default.

-C  --crop              <crop ratio>
                        will force display cropping.
                        Requires restarting VLC.

-D  --disc-caching      <disc-caching value in ms>
                        will set a custom disc caching value
                        to override the VLC config setting.
                        Requires restarting VLC.

-E  --echo		<custom VLC commandline>
			will write a custom command to the defaults file.
			An existing custom@ line will be appended to.
			Requires restarting VLC.

-F  --file-caching      <file-caching value in ms>
                        will set a custom file caching value
                        to override the VLC config setting.
                        Requires restarting VLC.

-M  --monitor-par       <monitor pixel aspect ratio>
                        will stretch or pinch the display if necessary.
                        Requires restarting VLC.

-R  --aspect            <aspect ratio>
                        will force the display aspect ratio.
                        Requires restarting VLC.

-S  --set-strack        will set the current subtitle track on the
                        current title as default.

-T  --add-title         will add the current title to the defaults file,
                        so audio and subtitle default settings will be
                        applied to it. Multiple titles can be added. This
                        has no effect on the default playback position.

-Z  --reload            will reload default settings from the defaults
                        file, if present.


The capitalized options are useful if default settings fail. Use them only
if necessary.

For many of these options, see also the VLC documentation.

EOF
exit
;;
-l|--list)
################################################################################
# Note for matedialog (zenity does not seem to have this bug, but needs gtk3
# and is MUCH slower):
# In rare cases the bookmark list may not be completely displayed. After
# reordering the bookmarks, altering a name or adding new bookmarks the bug
# disappeared. For a workaround, it is possible to surround the string that
# is piped to matedialog with newlines:
# TEXT=`echo; sed -n '/^[0-9]\+\t.*$/ P' $BOOKMARKFILE; echo`
# or read it into a file instead of piping it (as is done below):
# sed -n '/^[0-9]\+\t.*$/ P' $BOOKMARKFILE > $LISTFILE
################################################################################
if [[ $BOOKMARKFILE -nt $LISTFILE ]]; then
#reload the file if it changed
sed -n '/^[0-9]\+\t.*$/ P' $BOOKMARKFILE > $LISTFILE
DISPLAY_WIDTH="$(echo "(`wc -L < $LISTFILE` * 7) + 44" | bc)"
DISPLAY_HEIGHT="$(echo "(`wc -l < $LISTFILE` * 23) + 86" | bc)"
sed -i /DISPLAY_.*/d ${MEDIADIR}/data
echo "DISPLAY_WIDTH=$DISPLAY_WIDTH" >> ${MEDIADIR}/data
echo "DISPLAY_HEIGHT=$DISPLAY_HEIGHT" >> ${MEDIADIR}/data
fi
#TEXT=`echo; grep -w -o '^[0-9]\+[[:space:]].*$' $BOOKMARKFILE; echo`
#TEXT="`grep -w -o '^[0-9]\+[[:space:]].*$' $BOOKMARKFILE`" #zenity
#TEXT="`sed -n '/^[0-9]\+\t.*$/ P' $BOOKMARKFILE`" #zenity
if [[ -s $LISTFILE ]]; then
#SELECTION=$(echo "$TEXT" | zenity --list --width="$(echo "(`echo "$TEXT" | wc -L` * 7) + 44" | bc)" --height="$(echo "(`echo "$TEXT" | wc -l` * 23) + 86" | bc)" --title="Bookmarks" --text="Select a bookmark:" --column="" --hide-header --timeout=30 | awk '{print $1}') #zenity
SELECTION=$(xargs -d '\n' -a "$LISTFILE" zenity --list --width="$DISPLAY_WIDTH" --height="$DISPLAY_HEIGHT" --title="Bookmarks" --text="Select a bookmark:" --column="" --hide-header --timeout=30 | awk '{print $1}')
else
zenity --info --text='No bookmarks yet.' --timeout=2
fi
if [ "$SELECTION" ]; then
get_var title
wait
oldtitle=$title
title=$(grep -w -A 1 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
check_title
get_time=$(grep -w -A 2 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2)
vlc_command seek $get_time
run_global
if [[ `echo $(grep -w -A 3 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \@ -f 1)` == 'commands' ]]; then
commands="$(grep -w -A 3 "^$SELECTION" $BOOKMARKFILE | tail -n 1 | cut -d \@ -f 2)"
eval $commands
fi
fi
;;
-A|--set-atrack)
vlc_command title
wait
get_var title
wait
vlc_command atrack
wait
audio_id=`grep 'Track.*\*' $LOGFILE | tail -n 1 | cut -d \  -f 5`
wait
set_default audio_id
;;
-S|--set-strack)
vlc_command title
wait
get_var title
wait
vlc_command strack
wait
if [[ `grep 'Disable\ \*' $LOGFILE | tail -n 1` ]]; then
sub_id=0
else
sub_id=`grep 'Track.*\*' $LOGFILE | tail -n 1 | cut -d \  -f 5`
fi
wait
set_default sub_id
;;
-E|--echo)
STRING=`grep '^custom@' $DEFAULTFILE`
if [[ -z "$STRING" ]]; then
echo 'custom@'"$2" >> $DEFAULTFILE
else
sed -i "s/$STRING/$STRING $2/" $DEFAULTFILE
fi
quit_vlc
;;
-M|--monitor-par)
sed -i /mpar/d $DEFAULTFILE
echo "mpar=$2" >> $DEFAULTFILE
wait
quit_vlc
;;
-T|--add-title)
get_var title
wait
echo "preserve=$title" >> $DEFAULTFILE
;;
-D|--disc-caching)
sed -i /disc-caching/d $DEFAULTFILE
echo "disc-caching=$2" >> $DEFAULTFILE
wait
quit_vlc
;;
-F|--file-caching)
sed -i /file-caching/d $DEFAULTFILE
echo "file-caching=$2" >> $DEFAULTFILE
wait
quit_vlc
;;
-C|--crop)
sed -i /crop/d $DEFAULTFILE
echo "crop=$2" >> $DEFAULTFILE
wait
quit_vlc
;;
-R|--aspect)
sed -i /aspect/d $DEFAULTFILE
echo "aspect=$2" >> $DEFAULTFILE
wait
quit_vlc
;;
-Z|--reload)
#if [[ `grep '^audio_id\|^sub_id' $DEFAULTFILE` ]] && [[ `grep -w "^title=$title\|^preserve=$title" $DEFAULTFILE` ]]; then
if [[ `grep '^audio_id\|^sub_id' $DEFAULTFILE` ]]; then
get_default audio_id sub_id
wait
check_default
fi
run_global
;;
-c|--create)
BMK=$(zenity --entry --title="New Bookmark" --text="A new bookmark will be created at the present position. Choose a name for it:")
if [[ $BMK ]]; then
get_var title get_time
wait
if [[ -z `grep '^title=' $DEFAULTFILE` ]] && [[ -z `grep '^title=' $BOOKMARKFILE` ]]; then
set_default title get_time
wait
fi
set_bookmark title get_time
wait
vlc_command play
fi
;;
-q|--create-clip)
starttime=`grep 'get_time' $BOOKMARKFILE | tail -n 1 | cut -d \= -f 2`
if [[ $starttime ]]; then
get_var get_time
wait
length=`echo $get_time - $starttime | bc`
echo 'commands@(while :; do sleep '"$length"'; vlc_command seek '"$starttime"'; done) &' >> $BOOKMARKFILE 
else
zenity --info --title="Error Creating Video Clip" --text="You need to create a bookmark first" --timeout=2
fi
vlc_command play
;;
-k|--commentary)
echo 'commands@if [[ ! -e $FLAG ]]; then sleep 0.4; alt_audio; touch $FLAG; fi' >> $BOOKMARKFILE
if [[ -z `grep 'global_commands@' $BOOKMARKFILE` ]]; then
echo 'global_commands@if [[ -e $FLAG ]]; then sleep 0.4; alt_audio; rm -f $FLAG; fi' >> $BOOKMARKFILE
fi
;;
-b|--create-default)
get_var title get_time
wait
set_default title get_time
wait
vlc_command play
;;
-s|--start)
if [[ `grep '^title\|^get_time' $DEFAULTFILE` ]]; then
get_var title
wait
oldtitle=$title
get_default title get_time
wait
check_title
vlc_command seek $get_time
wait
run_global
fi
;;
-r|--resume)
if [[ `grep "resume@" $DEFAULTFILE` ]]; then
get_var title
wait
oldtitle=$title
get_resume title get_time 
wait
check_title
vlc_command seek $get_time
wait
run_global
fi
;;
*)
quit_vlc
;;
esac

Last edited by nokangaroo; 07-31-2014 at 06:21 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Work in progress: Resuming and bookmarking scripts for DVD playback nokangaroo Linux - Software 1 03-17-2014 09:43 PM
Touchpad not working after resuming back from suspend/hibernation nelufarup Fedora 3 02-19-2010 05:10 PM
Wireless stops working after resuming from suspend to disk/ram piratesmack Slackware 9 12-25-2009 11:16 PM
Backup Solution for Sles environment - need scripts to migrate data hannesve Linux - Newbie 1 07-09-2008 08:54 AM
Nvidia driver not working properlly when resuming S3 suspend. redarrow Linux - Hardware 2 01-15-2007 10:08 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 11:58 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration