Skip to content

Instantly share code, notes, and snippets.

@hello-party
Last active May 6, 2022 20:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hello-party/27ba021c7a31a482fb76d9f10c5846b8 to your computer and use it in GitHub Desktop.
Save hello-party/27ba021c7a31a482fb76d9f10c5846b8 to your computer and use it in GitHub Desktop.
Simple Podcast Generator

This is pretty hacky, but it does work well once you're in the rhythm. So far as I understand it, id3v2 is out of date and doesn't support the latest id3 tag version or something. To get around this, I'm bumping the id3 tags down to v1 when I convert the flacs.

Requirements

  • ffmpeg
  • kid3-cli
  • id3v2
  • vlc-nox
  • procps
  • php

ZSH Config

This will convert a FLAC and rename it to Artist_-_Title with underscores.

Convert the MP3s

function renamemp3() {
  title=`ffprobe -loglevel error -show_entries format_tags=title -of default=noprint_wrappers=1:nokey=1 "$1"`
  artist=`ffprobe -loglevel error -show_entries format_tags=artist -of default=noprint_wrappers=1:nokey=1 "$1"`
  album=`ffprobe -loglevel error -show_entries format_tags=album -of default=noprint_wrappers=1:nokey=1 "$1"`
  name="$artist - $title"
  mv "$1" `echo "$name" | tr ' ' '_'`
  ffmpeg -i `echo "$name" | tr ' ' '_'` -ab 320k -map_metadata 0 -write_id3v1 true -id3v2_version 3 `echo "$name" | tr ' ' '_'`.mp3;
  mv `echo "$name" | tr ' ' '_'`.mp3 `echo "$name" | sed "s/flac//g"`
  mv `echo "$name" | tr ' ' '_'` `echo "$name" | tr ' ' '_'`.flac
}

The PHP

Save this as index.php into your directory. This is a modified version of this script. It is a little out of date and I couldn't get the duration to work, so I figured out a hacky fix. Make sure you update the metadata, too (desc, image, etc)

<?php
/*
    @license    http://www.gnu.org/licenses/agpl.txt
    @copyright  2014 Sourcefabric o.p.s.
    @link       http://www.sourcefabric.org
    @author     Micz Flor <micz.flor@sourcefabric.org>

    This php script will create a podcast XML on the fly
    listing all mp3 files in the same directory.
*/

$channeltitle   = "Podcast Title";
$channelauthor  = "Podcast Author";
/* $sortby sets the order in which tracks are listed.
   Options:
   "newest" = newest on top
   "oldest" = oldest on top
   "filedesc" = alphabetically descending
   "fileasc" = alphabetically ascending
   default: "filedesc" (== how streamplan.sh works)
*/
$sortby = "newest"; 

$dir = "https://".$_SERVER['SERVER_NAME'];
$parts = explode('/',$_SERVER['REQUEST_URI']);
for ($i = 0; $i < count($parts) - 1; $i++) {
  $dir .= $parts[$i] . "/";
}

header('Content-type: text/xml', true);

print"<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:itunes='http://www.itunes.com/DTDs/Podcast-1.0.dtd' version='2.0'>
<channel>
  <title>$channeltitle</title>
  <link>$dir</link>
  <description>Description</description>
  <itunes:image href='https://domain.com/cover.png'/>
  <itunes:author>$channelauthor</itunes:author>
  <language>en-us</language>
";
/**/
// read all mp3 files in the directory
$temp = glob("*.mp3");
// create array with timestamp.filename as key
foreach ($temp as $filename) {
  $mp3files[filemtime($filename).$filename] = $filename;
}
// change the order of the list according to $sortby set above
switch ($sortby) {
  case "newest":
    krsort($mp3files);
    break;
  case "oldest":
    ksort($mp3files);
    break;
  case "fileasc":
    natcasesort($mp3files);
    break;
  default:
    // filedesc 
    natcasesort($mp3files);
    $mp3files = array_reverse($mp3files);
    break;
}
// go through files and create <item> for podcast
foreach ($mp3files as $filename) {
  // set empty array for metadata
  $iteminfo = array(
    "TPE1" => "",
    "TIT2" => "",
    "WOAF" => "",
    "Filename" => ""
  );
  // read id3 from shell command

  $result = shell_exec("ffmpeg -i ".$filename.' 2>&1 | grep -o \'Duration: [0-9:]*\'');
  $duration = str_replace('Duration: ', '', $result);

  $idtag = explode("\n",shell_exec("id3v2 -R '$filename'"));
  foreach($idtag as $line) {
    // to to match key => value from each line
    preg_match("/((\w+): (.*))/", $line, $results);
    // if ID3 tag found, results will return four values
    if(count($results) == 4) {
      $iteminfo[$results[2]] = $results[3];
    }
  }
  // if title too short, use filename as title
  if (strlen($iteminfo['TIT2']) < 2) {
    $iteminfo['TIT2'] = $filename;
  }
  print "
  <item>
    <title>".$iteminfo['TPE1']." - ".$iteminfo['TIT2']." (".$iteminfo['TYER'].", ".$iteminfo['TALB'].")</title>
    <itunes:author>".$iteminfo['TPE1']."</itunes:author>
    <description>".$iteminfo['TPE1']." - ".$iteminfo['TIT2']." (".$iteminfo['TYER'].", ".$iteminfo['TALB'].")</description>
    <itunes:subtitle>".$iteminfo['TPE1']." - ".$iteminfo['TIT2']." (".$iteminfo['TYER'].", ".$iteminfo['TALB'].")</itunes:subtitle>
    <enclosure url=\"".$dir.$filename."\" length=\"".filesize($filename)."\" type=\"audio/mpeg\"/>
    <itunes:duration>".$duration."</itunes:duration>
    <guid>".$dir.$filename."</guid>
    <pubDate>".date ("r", filemtime($filename))."</pubDate>
  </item>";
}
print"
</channel>
</rss>";
?>

Once you have your first mp3 in there, go to https://pocketcasts.com/submit and submit it. It'll take a few seconds, but it should work perfectly.

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