I an audiobook collection and am trying to figure out a free way to keep my audiobooks in sync across devices. A friend of mine recommended I check out the gPodderSync plugin for NextCloud. I wrote a PHP script to create the RSS feeds for each audiobook and another PHP script to create an OPML file so I can import all audiobooks into AntennaPod or Kasts. The problem I am having is that gPodderSync doesn't list all the audiobooks that I have. It only lists a small portion of them. Is there something wrong with my scripts or does gPodderSync have a limit on how many podcasts it can handle?
create-podcasts.php:
<?php// Recursive implementation of glob()function rglob(string $pattern, int $flags = 0) { $files = glob($pattern, $flags); foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { $files = array_merge($files, rglob($dir . '/' . basename($pattern), $flags)); } return $files;}// Get tracks$tracks = rglob("audiobooks/**/*.mp3");// Get folders$folders = array();foreach ($tracks as $track) { $folder = dirname($track); if (!in_array($folder, $folders)) { $folders[] = $folder; }}// Constantsconst HOST = "http://notrealdomain.com:3000";const OUTDIR = "podcasts";// Return and update pubDate$date = new DateTime("1970-01-01 12:00:00 -0700");$orig = $date;function getPubDate() { global $date; $date->modify("+1 day"); return $date;}// Create xml item for trackfunction createTrack(string $track, string $folder, DateTime $date) { // Get track info $title = str_replace(" ", "_", basename($track, ".mp3")); $desc = "Audiobook: " . basename($folder); $url = HOST . "/" . $track; $pubDate = $date->format(DateTime::RSS); $length = filesize($track); // Create xml $xml = <<<XML<item><title>$title</title><description>$desc</description><pubDate>$pubDate</pubDate><enclosure url="$url" length="$length" type="audio/mpeg" /></item>\n XML; // Return xml item return $xml;}// Create podcast for each folderforeach ($folders as $folder) { // Beginning of xml $title = basename($folder); $rss = <<<XML<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>$title</title><description>Audiobook: $folder</description><link>$folder</link><language>en-us</language>\n XML; // Get tracks in folder and sort $tracks = glob("$folder/*.mp3"); usort($tracks, function (string $a, string $b) { // Get numbers from track names preg_match_all("/\d+/", $a, $numsA); preg_match_all("/\d+/", $b, $numsB); // Get last number from track names (no mp3) $numA = $numsA[0][count($numsA[0]) - 2]; $numB = $numsB[0][count($numsB[0]) - 2]; // Compare numbers return $numA <=> $numB; }); array_reverse($tracks); // Create xml item for each track foreach ($tracks as $track) { $xml = createTrack($track, $folder, getPubDate()); $rss .= $xml; } // End of xml $rss .= <<<XML</channel></rss> XML; // Write to file $file = OUTDIR . "/" . basename($folder) . ".rss"; file_put_contents($file, $rss); // Reset date $date = $orig;}
create-opml.php:
<?php// Constantsconst HOST = "http://notrealdomain.com:3000";const RSSDIR = "podcasts";// Get all rss files$rssFiles = glob(RSSDIR . "/*.rss");// Create start of xml file$opml = <<<XML<?xml version="1.0" encoding="UTF-8"?><opml version="1.0"><head><title>Audiobook Collection</title></head><body>\nXML;// Add each rss file to opmlforeach ($rssFiles as $file) { // Get podcast info $title = $text = basename($file, ".rss"); $url = HOST . "/" . $file; // Add podcast to opml $opml .= <<<XML<outline text="$text" title="$title" type="rss" xmlUrl="$url" />\n XML;}// Add end of xml file$opml .= <<<XML</body></opml>XML;// Write opml to filefile_put_contents(RSSDIR . "/podcasts.opml", $opml);