Skip to content

Instantly share code, notes, and snippets.

@mykola2312
Created August 18, 2024 02:48
Show Gist options
  • Save mykola2312/375b7ad8e1fc4f4d0f0a96b33b7a4573 to your computer and use it in GitHub Desktop.
Save mykola2312/375b7ad8e1fc4f4d0f0a96b33b7a4573 to your computer and use it in GitHub Desktop.
bash script for CD/DVD music ripping
#!/usr/bin/env bash
# first, we need to determine type of disk
# this can be achieved by trying first mount_cd9660 and checking error
# if it returns "Device not configured" - we need to wait,
# otherwise its not CD9660 fs and we can move to next
#
# try mounting UDF, if it returns "Invalid argument" - it's not an UDF
#
# the last remaining disc type is CD audio disc, that we must
# rip with cdparanoia -B -d /dev/cd0 and then ffmpeg all tracks into mp3
# DISC RIPPING LOGIC
rips_user="mykola"
rips_group="mykola"
rips_perms="600"
rips_dir_perms="700"
rips_dir="$(pwd)"
rip_begin() {
echo "Enter rip name: "
read -r name
echo "Enter rip full-name: "
read -r full_name
echo -e "$name\t$full_name" >> rips.txt
# create rip directory and cd into it, so we can have workplace
mkdir "$name"
cd "$name"
}
rip_end() {
# own files
chown -R "$rips_user:$rips_group" .
chmod $rips_perms *
chmod $rips_dir_perms .
# leave title dir
# NOTE: fs is already mounted by mount_cd9660 and mount_udf probing
cd "$rips_dir"
# eject disc
cdcontrol eject
}
rip_fs() {
rip_begin
# just copy all files
cp -rf /mnt/cdrom/* ./
# only for filesystem discs: unmount
umount /mnt/cdrom
rip_end
}
rip_audio() {
rip_begin
# directly ripping using cdparanoia is too slow,
# so we're gonna parse CD's table of contents and
# dd each track one by one
sectorsize=$(geom disk list /dev/cd0 | awk '$1 == "Sectorsize:" { print $2 }')
while read -r track_id track_len track_start track_ch; do
dd if=/dev/cd0 bs=$sectorsize skip=$track_start count=$track_len | ffmpeg -f s16le -ar 44100 -ac $track_ch -i pipe: -b:a 320k "track$track_id.mp3"
done < <(cdparanoia -Q -d /dev/cd0 2>&1 | awk '$1 ~ /[0-9]/ { sub(/.$/,"",$1); print $1, $2, $4, $8 }')
rip_end
}
# DETECT DISC TYPE
# try mounting CD9660
stderr=$(mount_cd9660 /dev/cd0 /mnt/cdrom 2>&1 >/dev/null)
ret=$?
echo $stderr
if [ $ret -ne 0 ]; then
# we got an error, let's taste stderr message
if [[ $stderr == *"Device not configured"* ]]; then
# gonna wait for disc to be configured in a loop
while [[ $stderr == *"Device not configured"* ]]; do
stderr=$(mount_cd9660 /dev/cd0 /mnt/cdrom 2>&1 >/dev/null)
ret=$?
done
fi
fi
if [ $ret -eq 0 ]; then
echo "we got cd9660 mounted!"
rip_fs
else
# let's try UDF
stderr=$(mount_udf /dev/cd0 /mnt/cdrom 2>&1 >/dev/null)
ret=$?
if [[ $ret -eq 0 ]]; then
# it's UDF!
echo "we got UDF mounted!"
rip_fs
else
# final try - CD audio disc
stderr=$(cdparanoia -Q -d /dev/cd0 2>&1 >/dev/null)
if [[ $stderr == *"Unable to read table of contents header"* ]]; then
# not even an audio cd disc
echo "unknwon disc type and fs" >&2
exit 1
else
# thats an audio disc!
echo "got audio cd"
rip_audio
fi
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment