Skip to content

Instantly share code, notes, and snippets.

@tobek
Created October 19, 2020 23:16
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tobek/eb1af258175ed3627a6b7256859ad4c4 to your computer and use it in GitHub Desktop.
Save tobek/eb1af258175ed3627a6b7256859ad4c4 to your computer and use it in GitHub Desktop.
Rip and encode individual titles and chapters from DVD or ISO
#!/bin/bash
set -eo pipefail
shopt -s expand_aliases
alias ffmpeg='ffmpeg -hide_banner'
usage()
{
cat << EOF
usage: extract-dvd-chapters DVD [TITLE] [CHAPTER_START] [CHAPTER_END]
Rips individual chapters in the given DVD title and encodes each to an x264/aac video.
DVD e.g. /dev/sr0 or ISO file. NOTE: don't use mounted ISO mountpoint, lsdvd doesn't like it
TITLE Title to rip (default 1)
CHAPTER_START Chapter to start with, use "-" to merge all chapters in the title to one video (default 1)
CHAPTER_END Chapter to end with, inclusive (default: all chapters in the title)
EOF
}
if [ -z "$1" ]; then
usage
exit 2
fi
dvd="$1"
if [ -n "$2" ]; then
title_num="$2"
else
# TODO loop through titles
# eval $(lsdvd "$dvd" | sed -n 's/Title: \([0-9]\+\), .* Chapters: \([0-9]\+\), Cells: .*/cells[$((10#\1))]=$((10#\2));/p')
# titles=${#cells[@]}
# for now just:
title_num=1
fi
num_chaps="$(dvdxchap -t $title_num "$dvd"| sed -n 's/^CHAPTER\([0-9]\+\).*/\1/p' | sed -n '$p')"
if [ -n "$3" ]; then
from_chap="$3"
else
from_chap=1
fi
if [ -n "$4" ]; then
to_chap="$4"
else
to_chap="$num_chaps"
fi
if [ "$3" == "-" ]; then
merge_chaps=true
# only want to loop through once
from_chap=1
to_chap=1
fi
if [ "$merge_chaps" = true ] ; then
echo -e "\n\n$dvd: Extracting title $title_num, merging chapters"
else
echo -e "\n\n$dvd: Extracting title $title_num chapters $from_chap through $to_chap"
fi
for ((c=$from_chap; c<=$to_chap; c++)); do
# TODO make sure title and chapter are 0-padded for output file name
if [ "$merge_chaps" = true ] ; then
chaps="1-$num_chaps"
output_file="$dvd - $title_num.mp4"
else
chaps="$c-$c"
output_file="$dvd - $title_num.$c.mp4"
fi
echo -e "\n\nEncoding title $title_num chapters $chaps...\n"
# TODO maybe should automate using `-vf cropdetect` with mplayer and passing crop filter to ffmpeg
# mplayer "dvd://$title_num" -dvd-device "$dvd" -chapter "$chaps" -vf cropdetect
mkfifo fifo
mplayer -quiet -msglevel all=2 dvd://"$title_num" -dvd-device "$dvd" -chapter "$chaps" -dumpstream -dumpfile fifo &
ffmpeg -y -i fifo -c:v libx264 -preset slower -crf 20 -c:a libfdk_aac -vbr 5 -loglevel error "$output_file"
rm fifo
done
@Lili1228
Copy link

L34-38, just title_num=$(lsdvd /dev/sr0 -q | grep ^Title | wc -l)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment