Plok
Plok is a simple Bash script for generating a podcast website and RSS feed from a directory of MP3 files.
You can download the code here.
It reads podcast information from site.conf, extracts episode metadata from MP3 files using ffprobe, generates an index.html page, and creates a podcast-compatible rss.xml feed.
Requirements
Plok requires:
- Bash
ffprobefrom FFmpegsedstatfindawksortcutxargsdatemktemp
On Debian, the main external dependency can be installed with:
sudo apt install ffmpegDirectory structure
A basic Plok project looks like this:
.
├── plok
├── site.conf
├── media/
│ ├── 20260801-first-episode.mp3
│ ├── 20260808-second-episode.mp3
│ └── 20260815-third-episode.mp3
├── head.html # optional
├── foot.html # optional
├── style.css # optional
└── avatar.png # used by the RSS feed
Running:
./plokgenerates:
index.html
rss.xml
The generated files replace any existing index.html and rss.xml.
MP3 filenames
MP3 filenames must begin with an eight-digit date in YYYYMMDD format.
For example:
20260801-first-episode.mp3
20260808-second-episode.mp3
20260901-third-episode.mp3
The first eight characters are used to determine the episode date.
The date is used for:
- The date displayed on the website
- The
<pubDate>in the RSS feed
The remainder of the filename does not determine the episode title. The title is read from the MP3 TITLE metadata tag.
If the MP3 does not contain a TITLE tag, the episode is displayed as:
Untitled
The DESCRIPTION metadata tag is used as the episode synopsis.
MP3 metadata
Plok reads the following metadata from each MP3:
| Metadata | Used for |
|---|---|
TITLE |
Episode title |
DESCRIPTION |
Episode synopsis |
For example, using ffmpeg:
ffmpeg -i input.mp3
-metadata title="My Episode"
-metadata description="This is the episode description."
-c copy output.mp3site.conf
The site.conf file contains the podcast configuration.
Settings use the following format:
key: value
Whitespace around the key and value is removed.
Required settings
title
The podcast title.
title: My Podcast
author
The podcast author.
author: Chris
url
The base URL of the podcast website.
url: https://example.com
The trailing / is automatically removed if present.
Optional settings
description
The podcast description.
description: A podcast about interesting things.
email
The podcast contact email address.
email: chris@example.com
language
The podcast language.
Default:
language: en-GB
category
The podcast category.
Default:
category: Society & Culture
explicit
Whether the podcast contains explicit content.
Default:
explicit: false
date_format
The format used for dates displayed on the HTML page.
Default:
date_format: %d %b %Y
This produces dates such as:
08 Aug 2026
The format follows the GNU date format.
recursive
Controls whether Plok searches subdirectories inside media/.
Default:
recursive: false
With:
recursive: true
Plok searches recursively.
order
Controls the order of episodes on the generated page and RSS feed.
Default:
order: reverse
This puts newer episodes first.
To put older episodes first:
order: forward
HTML templates
Plok has two built-in HTML templates:
defaultcompact
The template is selected using the template setting in site.conf.
head.html
If head.html exists, its contents are inserted into the generated HTML immediately after the opening <body> tag.
This can be used for things such as:
- Site navigation
- Headers
- Introductory text
- Podcast information
- Other HTML content
foot.html
If foot.html exists, its contents are added after all episode entries and before the closing </body> and </html> tags.
This can be used for:
- Footers
- Copyright information
- Additional navigation
- Other HTML content
style.css
If style.css exists, Plok automatically adds:
<link rel="stylesheet" href="style.css">to the generated HTML <head>.
This allows the generated page and its templates to be styled without modifying Plok.
RSS feed
Plok generates a podcast RSS 2.0 feed containing:
- Podcast title
- Podcast description
- Author
- Language
- Category
- Explicit-content status
- Podcast artwork
- Episode title
- Episode description
- Episode publication date
- Episode URL
- MP3 file size
- MP3 enclosure
The generated feed is:
rss.xml
The podcast artwork is expected at:
avatar.png
and is referenced using:
https://example.com/avatar.png
The RSS feed URL is:
https://example.com/rss.xml
Example site.conf
A complete configuration might look like:
title: My Podcast
description: A podcast about interesting things.
author: Chris
email: chris@example.com
language: en-GB
category: Society & Culture
explicit: false
date_format: %d %b %Y
recursive: false
order: reverse
url: https://example.com
template: compact
The minimum configuration is:
title: My Podcast
author: Chris
url: https://example.com
All other settings have defaults.
Running Plok
Make the script executable:
chmod +x plokThen run:
./plokPlok will report each MP3 as it processes it:
Processing: 20260808-second-episode.mp3
Processing: 20260801-first-episode.mp3
Done
The resulting files are:
index.html
rss.xml
Generated HTML safety
Episode titles are HTML-escaped before being inserted into the generated page.
Episode descriptions are also HTML-escaped before being converted into links and line breaks.
This prevents characters such as:
&
<
>
from being interpreted as HTML.
URLs found in episode descriptions beginning with http:// or https:// are automatically converted into HTML links.
Temporary files
Plok generates temporary files using mktemp while creating the HTML and RSS files.
A shell trap removes these temporary files when the script exits.
The completed temporary files are moved into place only after generation has finished.