const { Podcast } = require('podcast'); const music_metadata = require('music-metadata'); const fs = require('fs'); async function getMp3Duration(filePath) { try { const metadata = await music_metadata.parseFile(filePath); console.log('Duration:', metadata.format.duration, 'seconds'); return metadata.format.duration; // Duration in seconds } catch (error) { console.error('Error reading file:', error.message); return null; } } class PodcastFeed { data() { return { // Writes to "/my-permalink/hello/index.html" permalink: (data) => `${data.page.filePathStem}.xml`, }; } async render(data) { const feed = new Podcast({ title: data.title, description: data.description, customNamespaces: {podcast:"https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md"}, feedUrl: `${data.site.url}${data.page.filePathStem}.xml`, siteUrl: data.site.url, imageUrl: data.site.imageUrl || `${data.site.url}${data.page.filePathStem}.jpg`, author: data.author || `${data.site.author.name}`, copyright: data.copyright || `${new Date().getFullYear()} ${data.site.author.name}`, language: 'en', categories: data.categories, pubDate: data.page.date, ttl: 60, itunesAuthor: data.itunes?.author || `${data.site.author.name}`, itunesSubtitle: data.itunes?.subtitle || '', itunesSummary: data.itunes?.summary || '', itunesOwner: { name: data.itunes?.owner?.name || `${data.site.author.name}`, email: data.itunes?.owner?.email ||`${data.site.author.email}` }, itunesExplicit: data.itunes?.explicit || false, itunesCategory: [], itunesImage: data.itunes?.image || data.site.imageUrl || `${data.site.url}${data.page.filePathStem}.jpg` }); const items = data.collections[data.episodeCollection]?.filter(episode=>episode.data.podcast!=false) var item items.forEach(episode=>{ // const duration = getMp3Duration(`../episodes/s${zero_pad_season}/s${zero_pad_season}e${episode.data.episode}.mp3`) /* loop over data and add to feed */ item = { title: `${episode.data.podcast.title}`, description: episode.content, url: data.site.url+this.url(episode.url), // link to the item guid: episode.url, // optional - defaults to url date: episode.data.date, // any format that js Date can parse. enclosure : {url:`${episode.data.podcast.enclosureUrl}`}, // optional enclosure customElements: [] // itunesDuration: duration, } if (episode.data.podcast.transcriptUrl) { item.customElements.push({ 'podcast:transcript': {_attr:{ url:`${episode.data.podcast.transcriptUrl}`, type:"application/srt", language:"en-us" }} }) console.log() } item = feed.addItem(item); }) // cache the xml to send to clients const xml = feed.buildXml(); return xml.replace('>',' />') } } module.exports = PodcastFeed