$title =

Automate DVD Digitization

;

$content = [

The process of digitizing a media library is fairly straightforward. The first step is to move your media from the disc to your computer. MakeMKV is the preferred program for this process. This created an exact copy of the files from the disc, which means large files. A tool like handbrake is used as a next step compress the files for media storage and streaming playback. Because the compression process is the lengthiest part, it’s easy to accumulate a backlog of movies and shows that are waiting to be compressed. While there’s not much we can do about the time it takes to compress media, we can automate the lengthiest parts of the process so it’ll just run in the background.

Install CLI Tools

Install the necessary tools, the following works on Debian/Ubuntu-based systems

sudo apt install makemkv-bin makemkv-oss handbrake-cli udev inotify-tools eject

Encoding Queue

If there’s one thing you should automate, it’s the encoding queue. The idea is simple: have a designated queue folder where uncompressed files go. While files exist, a process will pick the oldest file, compress it using the handbrake CLI, and remove the original file when complete.

Setup

~/scripts/encode-worker.sh
#!/bin/bash
# ~/scripts/encode-worker.sh
QUEUE_DIR="$HOME/rips/queue" # uncompressed input
ENCODED_DIR="$HOME/rips/encoded" # compressed output
PRESET_FILE="$HOME/scripts/SAVED_PRESET_CONFIG.json" # create in handbrake, export to JSON
PRESET_NAME="SAVED_PRESET_NAME" # whatever you named your config
LOGFILE="$HOME/rips/encode.log"
mkdir -p "$QUEUE_DIR" "$ENCODED_DIR"
echo "[$(date)] Encode worker started, watching $QUEUE_DIR" >> "$LOGFILE"
while true; do
# Grab the oldest queued file across all title subfolders, if any
FILE=$(find "$QUEUE_DIR" -mindepth 2 -maxdepth 2 -name '*.mkv' -printf '%T+ %p\n' 2>/dev/null | sort | head -n1 | cut -d' ' -f2-)
if [ -z "$FILE" ]; then
sleep 30
continue
fi
CLEAN_TITLE=$(basename "$(dirname "$FILE")")
base=$(basename "$FILE" .mkv)
OUT_DIR="$ENCODED_DIR/$CLEAN_TITLE"
mkdir -p "$OUT_DIR"
out="$OUT_DIR/${base}.mkv"
# Claim the file immediately so a restart mid-run doesn't double-process it
mv "$FILE" "$FILE.processing"
FILE="$FILE.processing"
echo "[$(date)] Encoding: $CLEAN_TITLE/$base" >> "$LOGFILE"
HandBrakeCLI -i "$FILE" -o "$out" --preset-import-file "$PRESET_FILE" -Z "$PRESET_NAME" >> "$LOGFILE" 2>&1
if [ $? -eq 0 ]; then
ORIGINAL_SIZE=$(stat -c%s "$FILE")
ENCODED_SIZE=$(stat -c%s "$out")
if [ "$ENCODED_SIZE" -gt "$ORIGINAL_SIZE" ]; then
echo "[$(date)] Encoded file larger than original ($ENCODED_SIZE > $ORIGINAL_SIZE bytes) for $CLEAN_TITLE/$base — keeping original" >> "$LOGFILE"
rm -f "$out"
mv "$FILE" "$out"
else
rm -f "$FILE"
echo "[$(date)] Encode complete: $CLEAN_TITLE/$base" >> "$LOGFILE"
fi
else
echo "[$(date)] ENCODE FAILED: $CLEAN_TITLE/$base — left as $FILE for manual review" >> "$LOGFILE"
fi
# Clean up empty title subfolder in the queue once drained
rmdir "$(dirname "${FILE%.processing}")" 2>/dev/null || true
done
/etc/systemd/system/encode-worker.service
[Unit]
Description=HandBrake encode queue worker
After=network.target
[Service]
Type=simple
User=YOUR_USERNAME
Environment=HOME=/home/YOUR_USERNAME
ExecStart=/home/YOUR_USERNAME/scripts/encode-worker.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

Creating encode-worker.service requires elevated permissions. One way to do this is by running

sudo nano /etc/systemd/system/encode-worker.service

Once the files are created, run the following commands

chmod +x ~/scripts/encode-worker.sh
sudo systemctl daemon-reload
sudo systemctl enable --now encode-worker.service

To stop the service, run

sudo systemctl stop --now encode-worker.service

Disc Detection Event Driven Rip

There are three components to automating ripping when a disc in inserted:

  1. a udev rule to respond to a disc being inserted into the drive
  2. a service that initiates the ripping process
  3. a script the service executes
/etc/udev/rules.d/99-dvd-rip.rules
ACTION=="change", SUBSYSTEM=="block", KERNEL=="sr0", ENV{ID_CDROM_MEDIA}=="1", TAG+="systemd", ENV{SYSTEMD_WANTS}="dvd-rip.service"
/etc/systemd/system/dvd-rip.service
[Unit]
Description=Automated disc rip pipeline
[Service]
Type=oneshot
User=YOUR_USERNAME
Environment=HOME=/home/YOUR_USERNAME
ExecStart=/home/YOUR_USERNAME/scripts/rip-trigger.sh
~/scripts/rip-trigger.sh
#!/bin/bash
# ~/scripts/rip-trigger.sh
set -e
RAW_DIR="$HOME/rips/raw"
QUEUE_DIR="$HOME/rips/queue"
LOGFILE="$HOME/rips/rip.log"
mkdir -p "$RAW_DIR" "$QUEUE_DIR"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
RAW_LABEL=$(blkid -o value -s LABEL /dev/sr0 2>/dev/null || echo "UNKNOWN_DISC")
CLEAN_TITLE=$(echo "$RAW_LABEL" | sed -E 's/_DISC[0-9]*//I; s/[_\.]+/ /g; s/ +/ /g' | sed -E 's/\b(\w)/\U\1/g')
echo "[$TIMESTAMP] Disc detected: '$RAW_LABEL' -> guessed title '$CLEAN_TITLE'" >> "$LOGFILE"
DISC_RAW="$RAW_DIR/$TIMESTAMP"
mkdir -p "$DISC_RAW"
makemkvcon mkv disc:0 all "$DISC_RAW" --minlength=120 >> "$LOGFILE" 2>&1
echo "[$TIMESTAMP] Rip complete, ejecting disc..." >> "$LOGFILE"
eject /dev/sr0
# Move every ripped file into its own titled subfolder in the queue
DEST_DIR="$QUEUE_DIR/$CLEAN_TITLE"
mkdir -p "$DEST_DIR"
for f in "$DISC_RAW"/*.mkv; do
[ -e "$f" ] || continue
mv "$f" "$DEST_DIR/"
echo "[$TIMESTAMP] Queued: $CLEAN_TITLE/$(basename "$f")" >> "$LOGFILE"
done
rmdir "$DISC_RAW" 2>/dev/null || true
echo "[$TIMESTAMP] Disc processing done. Ready for next disc." >> "$LOGFILE"

Once all three files are saved, run the following commands

sudo systemctl daemon-reload
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=block

Once setup, inserting a disc will initiate a rip and then place the file into a queue to be compressed, and digitizing your media library is as simple as inserting a DVD.

];

$date =

;

$category =

,

;

$author =

;

$next =

;