const { Podcast } = require('podcast'); const music_metadata = require('music-metadata'); const fs = require('fs'); const PODCAST_CDN_ROOT="https://podcast.rpg.cdn.ascorrea.com" 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, feedUrl: `${data.site.url}${data.page.filePathStem}.xml`, siteUrl: data.site.url, imageUrl: 'http://example.com/icon.png', 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 || 'http://example.com/image.png' }); const episodes = data.collections.episode.filter(episode=>episode.data.podcast==true) const items = data.tags ? episodes.filter(episode=>data.tags.every(tag=>episode.data.tags.includes(tag))) : episodes items.forEach(episode=>{ const episode_data = episode.data const zero_pad_season = episode_data.season.toString().padStart(2, '0') // const duration = getMp3Duration(`../episodes/s${zero_pad_season}/s${zero_pad_season}e${episode_data.episode}.mp3`) /* loop over data and add to feed */ feed.addItem({ title: `S${zero_pad_season}E${episode_data.episode}: ${episode_data.title}`, description: episode.content, 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:`${data.site.url}/episodes/s${zero_pad_season}/s${zero_pad_season}e${episode_data.episode}.mp3`}, // optional enclosure enclosure : {url:`${PODCAST_CDN_ROOT}/s${zero_pad_season}e${episode_data.episode}.mp3`}, // optional enclosure // itunesDuration: duration, }); }) // cache the xml to send to clients const xml = feed.buildXml(); return xml } } module.exports = PodcastFeed