Skip to content

Instantly share code, notes, and snippets.

@Alexia
Last active August 11, 2021 05:09
Show Gist options
  • Save Alexia/649d034ab231c2e1a4ca9b765ad9f4d2 to your computer and use it in GitHub Desktop.
Save Alexia/649d034ab231c2e1a4ca9b765ad9f4d2 to your computer and use it in GitHub Desktop.
Automated Blu-ray Ripping for Linux
<?php
//Proof of concept for automated ripping of video discs. I will expand this to handle CDs and DVDs for myself in the future.
//Ugly code. "Just get it done" was the mentality used here.
$statuses = [
0 => 'idle',
1 => 'waiting',
2 => 'mounted',
3 => 'ripping',
];
$error = false;
$status = 0;
$currentTitle = '';
$device = '/dev/sr0';
if (isset($argv[1]) && strlen($argv[1])) {
if (file_exists($argv[1]) && strpos($argv[1], '/dev/s') == 0) {
$device = $argv[1];
} else {
echo "Device not found.\n";
exit;
}
}
$destination = '/media/rips/';
if (isset($argv[2]) && strlen($argv[2])) {
$destination = rtrim(trim($argv[2]), '/');
if (!file_exists($destination)) {
echo "Destination not found.\n";
exit;
}
}
$pieces = explode('/', $device);
$ident = array_pop($pieces);
$mount = sys_get_temp_dir().'/'.$ident;
if (!file_exists($mount)) {
mkdir($mount);
}
$bdInfo = $mount.'/BDMV/META/DL/bdmt_eng.xml';
while ($error == false) {
$output = '';
if ($status == 0) {
$output = shell_exec('setcd -i '.$device);
if (strpos($output, 'CD tray is open') > 0) {
echo "Tray is open.\n";
sleep(5);
continue;
}
if (strpos($output, 'Drive is not ready') > 0) {
echo "Waiting on drive...\n";
//Give it time to spin up the disk.
sleep(5);
continue;
}
if (strpos($output, 'No disc is inserted') > 0) {
echo "No disc.\n";
notify("No disc. Quitting.", true);
exit;
}
if (strpos($output, 'Disc found in drive: data disc type 1') > 0) {
echo "Disk found, detecting.\n";
$status = 1;
sleep(1);
continue;
}
}
if ($status == 1) {
passthru('mount '.$device.' '.$mount);
$status = 2;
}
if ($status == 2) {
if (file_exists($bdInfo)) {
$contents = file_get_contents($bdInfo);
$matches = null;
if (preg_match("#<di:name>(.*?)</di:name>#is", $contents, $matches) > 0) {
if (strlen($matches[1]) > 0) {
$currentTitle = $matches[1];
notify("Ripping Blu-ray: {$currentTitle}", true);
$status = 3;
continue;
}
}
notify("Blu-ray, could not detect title!");
passthru('eject '.$device);
} else {
passthru('umount '.$mount);
echo "Could not detect disk, skipping.\n";
$status = 0;
continue;
}
}
if ($status == 3) {
//Sanitize a folder name from the current title.
$folder = str_replace(["\0", '\\', '/', ':', '*', '?', "'", '<', '>', '|'], ' ', $currentTitle); //Bad characters for file systems.
$folder = preg_replace('# {2,}#', ' ', $folder); //Remove extra spaces.
$folder = trim($folder); //Remove junk from the ends.
$ripStatus = shell_exec("makemkvcon --decrypt backup disc:{$ident} \"{$destination}{$folder}\" 2>&1");
if (!$ripStatus) {
notify("Bested by Subaru, pls help. ;_;", true);
}
if (strpos($ripStatus, 'Backup done.') != false) {
notify("DONE! GIMME ANOTHER.", true);
}
passthru('umount '.$mount);
passthru('eject '.$device);
$status = 0;
}
}
function notify($status, bool $echo = false) {
echo $status."\n";
$webhook = "";
$hostname = gethostname();
$date = date(DATE_ISO8601);
$jsonRaw = [
"embeds" => [
[
"title" => "RIPPER",
"description" => "$status",
"footer" => [
"text" => "$date on $hostname"
],
"thumbnail" => [
"url" => "",
"height" => 16,
"width" => 16
]
]
]
];
$json = json_encode($jsonRaw);
$ch = curl_init();
curl_setopt_array($ch,
[
CURLOPT_URL => $webhook,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_POST => 1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Accept: application/json"
],
CURLOPT_POSTFIELDS => $json,
]
);
curl_exec($ch);
curl_close($ch);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment