Episode 19 – I built my own PWA podcast app!

I felt so good about building my own RSS feed builder I was compelled to build my own podcast app. Well… when I say build I mean Claude.ai built it while I told it what I want. The app is custom branded for this site, because, why not. I went with a progressive web app (PWA) because it’s the easiest thing to build and implement. There is no need for an app store and it’s cross platform. It’s built for me after all so I’m the only customer that matters.

All I needed to build this is an API key from Podcast Index, the virtual private server I use to host this site, and Claude.ai. The first version came together quick. Search worked, audio played, it used my branding and everything looked functional! But as usual there are issues that I didn’t think of because I’m not a developer.

The first problem was Cross Origin Resource Sharing (CORS). I curse CORS!! The browser talked to the Podcast Index API but started throwing some fits when the app tried pulling podcast RSS feeds directly. Some feeds allow it and some don’t. Claude suggested I use a proxy. The browser talks to my server. My server fetches the feed. Problem solved… almost.

The first proxy version was too strict and blocked chapters and transcripts. The second version was too permissive. After enough back and forth, the app finally worked and doesn’t appear to be a huge security risk for my server.

Then I noticed my own podcast showing an episode that no longer existed. That turned out to be a stale Podcast Index entry. I don’t know why it shows up there. The episode titled, “Live streaming music show test 3” is not in my RSS feed. It was at one point but I fixed it and took it out. I used podping to send a signal that my feed is updated and I used the manual refresh function for Podcast Index to push the index to re-examine my feed. But none of it worked to fix the index to show my updated feed. So I told Claude to get the location of the RSS feed from the index but use the actual RSS feed as the source of truth instead of what the index displays. Poof! That ghost episode in my app is gone!

Get the podcast idiot podcast player

Next up was chapters and transcripts. This is where XML namespaces made things difficult. Browser parsing failed, returned nothing, and offered no explanation whatsoever. After fighting with namespace handling, Claude abandoned the elegant solution it originally chose and used regex against the raw RSS text instead (I have no idea what regex is or what Claude did to fix the issue.) It worked immediately!



Transcripts have multiple formats, timestamp parsing, and a user needs auto-scrolling synced to audio playback. That didn’t work either at the start. After a little back and forth Claude got it to work where the transcript auto scrolls and highlights the text in yellow so the user can follow along.

It’s a pretty decent little podcast app now. It searches the Podcast Index for shows you want, it can save favorites, and allow you to export your favorites to a JSON file so you can transfer them between devices. The podcast:funding tag is implemented so a listener can tap that support button to send the podcaster some fiat love. I didn’t implement full Value4Value as I don’t want to get into streaming payments. I think that is a little beyond what I want from the app.

The finished app is super simple. It pulls live data from RSS feeds, supports chapters, transcripts, and funding tags, runs in a browser, and you can install it to your computer or phone as it’s a Progressive Web App (PWA). It’s mainly an HTML file and a few bits and bobs to get it working. No app store needed and no backend infrastructure other than that pesky proxy that sits on my server. Claude insists it shouldn’t cause me any bandwidth issues. But I don’t think that’ll cause me too much trouble. Unless this PWA becomes the most popular podcast app on the Internet!!

Stranger things have happened in this world.


Posted

in

,

by

Comments

Leave a Reply