Skip to content

Commit

Permalink
Update:Download podcast episodes and embed meta tags #1488
Browse files Browse the repository at this point in the history
  • Loading branch information
advplyr committed Mar 29, 2023
1 parent 575a162 commit 704fbac
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 6 deletions.
14 changes: 8 additions & 6 deletions server/managers/PodcastManager.js
Expand Up @@ -4,11 +4,12 @@ const SocketAuthority = require('../SocketAuthority')
const fs = require('../libs/fsExtra')

const { getPodcastFeed } = require('../utils/podcastUtils')
const { downloadFile, removeFile } = require('../utils/fileUtils')
const { removeFile } = require('../utils/fileUtils')
const filePerms = require('../utils/filePerms')
const { levenshteinDistance } = require('../utils/index')
const opmlParser = require('../utils/parsers/parseOPML')
const prober = require('../utils/prober')
const ffmpegHelpers = require('../utils/ffmpegHelpers')

const LibraryFile = require('../objects/files/LibraryFile')
const PodcastEpisodeDownload = require('../objects/PodcastEpisodeDownload')
Expand Down Expand Up @@ -93,7 +94,8 @@ class PodcastManager {
await filePerms.setDefault(this.currentDownload.libraryItem.path)
}

let success = await downloadFile(this.currentDownload.url, this.currentDownload.targetPath).then(() => true).catch((error) => {
// Downloads episode and tags it
let success = await ffmpegHelpers.downloadPodcastEpisode(this.currentDownload).catch((error) => {
Logger.error(`[PodcastManager] Podcast Episode download failed`, error)
return false
})
Expand Down Expand Up @@ -126,22 +128,22 @@ class PodcastManager {
}

async scanAddPodcastEpisodeAudioFile() {
var libraryFile = await this.getLibraryFile(this.currentDownload.targetPath, this.currentDownload.targetRelPath)
const libraryFile = await this.getLibraryFile(this.currentDownload.targetPath, this.currentDownload.targetRelPath)

// TODO: Set meta tags on new audio file

var audioFile = await this.probeAudioFile(libraryFile)
const audioFile = await this.probeAudioFile(libraryFile)
if (!audioFile) {
return false
}

var libraryItem = this.db.libraryItems.find(li => li.id === this.currentDownload.libraryItem.id)
const libraryItem = this.db.libraryItems.find(li => li.id === this.currentDownload.libraryItem.id)
if (!libraryItem) {
Logger.error(`[PodcastManager] Podcast Episode finished but library item was not found ${this.currentDownload.libraryItem.id}`)
return false
}

var podcastEpisode = this.currentDownload.podcastEpisode
const podcastEpisode = this.currentDownload.podcastEpisode
podcastEpisode.audioFile = audioFile
libraryItem.media.addPodcastEpisode(podcastEpisode)
if (libraryItem.isInvalid) {
Expand Down
4 changes: 4 additions & 0 deletions server/objects/entities/PodcastEpisode.js
Expand Up @@ -106,6 +106,10 @@ class PodcastEpisode {
get enclosureUrl() {
return this.enclosure ? this.enclosure.url : null
}
get pubYear() {
if (!this.publishedAt) return null
return new Date(this.publishedAt).getFullYear()
}

setData(data, index = 1) {
this.id = getId('ep')
Expand Down
75 changes: 75 additions & 0 deletions server/utils/ffmpegHelpers.js
@@ -1,3 +1,4 @@
const axios = require('axios')
const Ffmpeg = require('../libs/fluentFfmpeg')
const fs = require('../libs/fsExtra')
const Path = require('path')
Expand Down Expand Up @@ -86,3 +87,77 @@ async function resizeImage(filePath, outputPath, width, height) {
})
}
module.exports.resizeImage = resizeImage

module.exports.downloadPodcastEpisode = (podcastEpisodeDownload) => {
return new Promise(async (resolve) => {
const response = await axios({
url: podcastEpisodeDownload.url,
method: 'GET',
responseType: 'stream',
timeout: 30000
})

const ffmpeg = Ffmpeg(response.data)
ffmpeg.outputOptions([
'-c copy',
'-metadata',
`album=${podcastEpisodeDownload.libraryItem?.media.metadata.title ?? ""}`, // Podcast Title
'-metadata',
`album-sort=${podcastEpisodeDownload.libraryItem?.media.metadata.title ?? ""}`, // Podcast Title
'-metadata',
`artist=${podcastEpisodeDownload.libraryItem?.media.metadata.author ?? ""}`, // Podcast Artist
'-metadata',
`artist-sort=${podcastEpisodeDownload.libraryItem?.media.metadata.author ?? ""}`, // Podcast Artist
'-metadata',
`comment=${podcastEpisodeDownload.podcastEpisode?.description ?? ""}`, // Episode Description
'-metadata',
`description=${podcastEpisodeDownload.podcastEpisode?.subtitle ?? ""}`, // Episode Subtitle
'-metadata',
`disc=${podcastEpisodeDownload.podcastEpisode?.season ?? ""}`, // Episode Season
'-metadata',
`genre=${podcastEpisodeDownload.libraryItem?.media.metadata.genres.join(';') ?? ""}`, // Podcast Genres
'-metadata',
`language=${podcastEpisodeDownload.libraryItem?.media.metadata.language ?? ""}`, // Podcast Language
'-metadata',
`MVNM=${podcastEpisodeDownload.libraryItem?.media.metadata.title ?? ""}`, // Podcast Title
'-metadata',
`MVIN=${podcastEpisodeDownload.podcastEpisode?.episode ?? ""}`, // Episode Number
'-metadata',
`track=${podcastEpisodeDownload.podcastEpisode?.episode ?? ""}`, // Episode Number
'-metadata',
`series-part=${podcastEpisodeDownload.podcastEpisode?.episode ?? ""}`, // Episode Number
'-metadata',
`podcast=1`,
'-metadata',
`title=${podcastEpisodeDownload.podcastEpisode?.title ?? ""}`, // Episode Title
'-metadata',
`title-sort=${podcastEpisodeDownload.podcastEpisode?.title ?? ""}`, // Episode Title
'-metadata',
`year=${podcastEpisodeDownload.podcastEpisode?.pubYear ?? ""}`, // Episode Pub Year
'-metadata',
`date=${podcastEpisodeDownload.podcastEpisode?.pubDate ?? ""}`, // Episode PubDate
'-metadata',
`releasedate=${podcastEpisodeDownload.podcastEpisode?.pubDate ?? ""}`, // Episode PubDate
'-metadata',
`itunes-id=${podcastEpisodeDownload.libraryItem?.media.metadata.itunesId ?? ""}`, // Podcast iTunes ID
'-metadata',
`podcast-type=${podcastEpisodeDownload.libraryItem?.media.metadata.type ?? ""}`, // Podcast Type
'-metadata',
`episode-type=${podcastEpisodeDownload.podcastEpisode?.episodeType ?? ""}` // Episode Type
])
ffmpeg.addOutput(podcastEpisodeDownload.targetPath)

ffmpeg.on('start', (cmd) => {
Logger.debug(`[FfmpegHelpers] downloadPodcastEpisode: Cmd: ${cmd}`)
})
ffmpeg.on('error', (err, stdout, stderr) => {
Logger.error(`[FfmpegHelpers] downloadPodcastEpisode: Error ${err} ${stdout} ${stderr}`)
resolve(false)
})
ffmpeg.on('end', () => {
Logger.debug(`[FfmpegHelpers] downloadPodcastEpisode: Complete`)
resolve(podcastEpisodeDownload.targetPath)
})
ffmpeg.run()
})
}

0 comments on commit 704fbac

Please sign in to comment.