Tuesday, November 12, 2013

DVD/Blu ray under linux

Unfortunately from what I read, neither MacOS nor Linux can play back blu-ray disks properly. That's because it's a closed format and they are only providing licenses for players in a very convoluted (and expensive) way. So there are no licensed players outside Windows, and certainly none that are free. That leaves those of us who still want to be able to watch a movie grappling to find solutions.

Fortunately there are some. First, vlc (apt-get install vlc) appears to play DVDs fine most of the time. You can try here for setting up blu-ray. It's a matter of adding a library and some keys, but like I said, it's apparently not great.

The alternative is to save the movies to disk first, and play them from there. This is also handy if you want to have them always available for your home theater.

To rip, MakeMKV seems to work great even though it's in beta. It's free too, for now. Just follow the directions at the link, which work flawlessly for me.

Now, you can insert a dvd/blu-ray and save it directly to disk. Unfortunately they're still full size, which can be quite big. Handbrake is a great tool for transcoding it for the output device you want to use. Simply:
sudo add-apt-repository ppa:stebbins/handbrake-releases
sudo apt-get update
sudo apt-get handbrake-gtk

Then it can be run with a nice GUI as handbrake-gtk. But there is also a useful command line interface. I've modified a tool I found in the handbrake forums (written for macos) that allows transcoding a whole directory full of files in a batch. The code is below the fold.


handbrakeCLIbatch
#!/bin/bash
# eg: handbrakeCLIbatch [dir(no trailing slash)] "*.mkv" -p "iPad" -q 17
###############################################################################
# handbrakeCLIbatch is a bash script utilizing HandbrakeCLI to batch transcode
# specified source files with a specified Handbrake transcoding profile.
#
# Handbrake is an open source, GPL-licensed, multiplatform, multithreaded video
# transcoder, available for Mac OS X, Linux and Windows. Handbrake Command Line
# Interface HandbrakeCLI is required by this script and can be downloaded from
# http://handbrake.fr/downloads2.php
#
# This script was authored and tested on Mac OS X 10.7.3 Lion.
# It now runs on Linux Mint 15.
#
# Download and move the script at the location of your choice (e.g. /usr/local/bin)
#
#     Usage is:
#     handbrakeCLIbatch [-c /path/to/HandbrakeCLI]
#                       [-d /path/to/destination/directory]
#                       [-p transcoding_preset]
#                       [-q quality]
#                       [-f container format]
#                       [-r]
#                       [source]
#                       [wildcard]
#                      
#         Where: [-c] optional parameter specifies the path to HandbrakeCLI. Script will
#                     try to determine the location of HandbrakeCLI if not specified
#                [-d] optional parameter specifies path to destination of transcoded
#                     files. Default value is the same as source directory.
#                [-p] optional parameter specifies the transcoding preset. Default value
#                     is "iPad"
#                [-q] optional parameter specifying video quality level.
#                     Specifying it may override the preset. [default from preset]
#                [-f] optional parameter specifies the container format and output file
#                     extension; e.g. m4v or mp4. Default value is m4v
#                [-r] optional parameter traverse into subfolders within source directory
#                [source] optional parameter specifies the (directory) path to source
#                     files. Default value is current directory
#                [wildcard] optional parameter specifies wildcard to select source
#                     files. Default value is *.avi
#
# Version: 0.1 2011-02-09, Initial release after test
# Modified 2013-11-08 by JB to run under linux and support specifying quality
###############################################################################

echo "#********************************************************************"
echo "# This script utilizes HandbrakeCLI to batch transcode specified "
echo "# source files with a specified Handbrake transcoding profile"
echo "#********************************************************************"

### Print usage information
print_help()
{
    echo "Usage: `basename $0` [-c \"/path/to/CLI\"]"
    echo "                         [-d \"/path/to/destination/directory\"]"
    echo "                         [-p \"transcoding_preset\"]"
    echo "                         [-q \"quality level\"]"
    echo "                         [-f \"container format\"]"
    echo "                         [-r]"
    echo "                         [source]"
    echo "                         [\"wildcard\"]"
    echo "       `basename $0` -h"
    echo ""
    echo "     Where: [-c] optional parameter specifies the path to HandbrakeCLI. Script will"
    echo "                 try to determine the location of HandbrakeCLI if not specified"
    echo "            [-d] optional parameter specifies path to destination of transcoded"
    echo "                 files. Default value is the same as source directory."
    echo "            [-p] optional parameter specifies the transcoding preset.
Default value"
    echo "                 is \"AppleTV 2\""
    echo "        [-q] optional parameter specifies the video quality level (default from preset)."
    echo "            [-f] optional parameter specifies the container format and output file"
    echo "                 extension; e.g. m4v or mp4. Default value is m4v"
    echo "            [-r] optional parameter traverse into subfolders within source directory"
    echo "            [source] optional parameter specifies the (directory) path to source"
    echo "                 files. Default value is current directory"
    echo "            [wildcard] optional parameter specifies wildcard to select source"
    echo "                 files. Default value is '*.avi'"
    return
}

### Sanity check! Exit if no arguments specified
# if [ $# -eq 0 ] ; then
#     echo "Error in $0 - Invalid Argument Count"
#     print_help
#     exit 1
# fi
#

### if first argument is -h then print help and exit
[[ "$1" = "-h" ]] \
    && { print_help; exit 1; }


RECURSIVE="-maxdepth 1" # set recursive before argument parsing, since -r should remove it from find command line
### Parse options
while getopts "c:s:d:p:q:f:w:r" flag
do
#     echo "-->$flag" $OPTIND $OPTARG
    case "$flag" in
        c) CLI="$OPTARG";;
        d) DSTPATH="$OPTARG";;
        p) PRESET="$OPTARG";;
        q) QUALITY="$OPTARG";;
        f) CONTAINER="$OPTARG";;
        r) RECURSIVE=""; echo "RECURSIVE $RECURSIVE";;
        \?) print_help; exit 1;;
    esac
done

### Parse remaining arguments
shift $(($OPTIND -1))
# Sanity check! Exit if no other arguments specified
[[ $# -eq 0 ]] \
    && { echo "Error in $0 - Either Source Directory or Wildcard must be specified"; print_help; exit 1; }

# if first argument is a folder, then it is source directory
# otherwise it should be the wildcard, and user wants to use the current directory
if [ -d "$1" ] ; then
    SRCPATH=$1
    WILDCARD=${2:-"*.avi"}                  #use *.avi as wildcard, if second argument not specified
else
    WILDCARD=$1
fi

SRCPATH=${SRCPATH:-`pwd`}                   #use current directory as source, if no argument was specified
[[ ! -r "$SRCPATH" ]] \
    && { echo "Error in $0 - source directory $SRCPATH is not readable" ; exit 1; }
   
CLI=${CLI:-`which HandBrakeCLI`}
[[ ! -x "$CLI" ]] \
    && { echo "Error in $0 - CLI $CLI does not exists or not executable" ; exit 1; }
   
DSTPATH=${DSTPATH:-$SRCPATH}            #use source directory as the destination
, if no argument was specified
[ ! -d "$DSTPATH" -o ! -w "$DSTPATH" ] \
    && { echo "Error in $0 - destination directory $DSTPATH does not exists or not writable" ; exit 1; }
   
PRESET=${PRESET:-"AppleTV 2"} #use iPad as default preset, if no argument was specified
PRESETLIST=`$CLI -z`
[[ ! "$PRESETLIST" =~ "${PRESET}" ]] \
    && { echo "Error in $0 - specified preset is not recognized by Handbrake" ; exit 1; }
PRESET="--preset=\"$PRESET\""
   
QUALITY=${QUALITY:-""}
[[ "$QUALITY" != "" ]] && QUALITY="--quality=$QUALITY"

CONTAINER=${CONTAINER:-"m4v"}           #use m4v as default container, if no argument was specified

### IFS is Bash's internal field separator,
# and here we set it to consist of a newline character only
# So that the array elements will be set from each line of
# find command output
OLDIFS=$IFS
IFS=$'\n'

### Get the source files into FIRSSET, as a regular variable
# we need eval here, since $RECURSIVE is a two word string.
FINDSTR="find $SRCPATH $RECURSIVE -name $WILDCARD | sort"
FIRSTSET=$(eval find $SRCPATH $RECURSIVE -name $WILDCARD | sort)
echo "$FIRSTSET"

### Print what will we done, and ask user to proceed
echo "Using HandbrakeCLI at    :" $CLI
echo "Source directory is      :" $SRCPATH
echo "Destination directory is :" $DSTPATH
echo "Transcoding profile is   :" $PRESET
echo "Quality level is         :" $QUALITY
echo "Container format is      :" $CONTAINER
echo "Find recursive is        :" $RECURSIVE
echo "Files to be processed are:"
echo " --> (executing $FINDSTR)"
for f in $FIRSTSET
do
  echo " --> $f"
done
echo " --> End of file list"

read -p "Do you want me to proceed with transcoding [Y/n]?" ANSWER

[ "$ANSWER" = "n" -o "$ANSWER" = "N" ] \
    && { echo "Aborting on user request" ; exit 1; }

echo "HandbrakeCLI Batch conversion Errors" `date` > $SRCPATH/handbrake-error.log
echo "HandbrakeCLI Batch conversion Messages" `date` > $SRCPATH/handbrake-out.log

for f in $FIRSTSET
do
  echo "Processing $f..."
  tSub=${f##*/} #get basename for the source file. Then ${tSub%.*} below will strip the extension from this basename
 
  # Run HandbrakeCLI. Send standard output and standard error to files.
  $CLI -i "$f" -o "$DSTPATH/${tSub%.*}.$CONTAINER" "$PRESET" "$QUALITY" >> $SRCPATH/handbrake-error.log 2>>$SRCPATH/handbrake-out.log
  if [ $? != 0 ]
  then
    echo "Failed transcoding $f" >> handbrake-error.log 
  fi
done

#Restore IFS
#IFS=$OLDIFS
 
echo "Job finished. Exiting."


Save, make executable, and enjoy. Credit goes to the original author oscarrines.

No comments:

Post a Comment