From 394d312282bfc494a23e0cc14f529a7a9a20b353 Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 9 Sep 2021 05:10:55 -0500 Subject: [PATCH] Merge tracks with codec copy' --- .../components/modals/edit-tabs/Download.vue | 4 +- client/package.json | 2 +- package.json | 2 +- server/DownloadManager.js | 54 ++++++++++++------- server/objects/Download.js | 8 +++ 5 files changed, 49 insertions(+), 21 deletions(-) diff --git a/client/components/modals/edit-tabs/Download.vue b/client/components/modals/edit-tabs/Download.vue index 76c08efc..28a15388 100644 --- a/client/components/modals/edit-tabs/Download.vue +++ b/client/components/modals/edit-tabs/Download.vue @@ -106,7 +106,9 @@ export default { var downloadPayload = { audiobookId: this.audiobook.id, - type: 'singleAudio' + type: 'singleAudio', + includeMetadata: true, + includeCover: true } this.$root.socket.emit('download', downloadPayload) }, diff --git a/client/package.json b/client/package.json index 03b23a56..33f800c7 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-client", - "version": "1.1.1", + "version": "1.1.2", "description": "Audiobook manager and player", "main": "index.js", "scripts": { diff --git a/package.json b/package.json index cde943a2..fc636e87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf", - "version": "1.1.1", + "version": "1.1.2", "description": "Self-hosted audiobook server for managing and playing audiobooks.", "main": "index.js", "scripts": { diff --git a/server/DownloadManager.js b/server/DownloadManager.js index 68319159..93ad705b 100644 --- a/server/DownloadManager.js +++ b/server/DownloadManager.js @@ -65,10 +65,14 @@ class DownloadManager { var audiobookDirname = Path.basename(audiobook.path) if (downloadType === 'singleAudio') { - var audioFileType = options.audioFileType || 'm4b' + var audioFileType = options.audioFileType || '.m4b' delete options.audioFileType - filename = audiobookDirname + '.' + audioFileType - fileext = '.' + audioFileType + if (audioFileType === 'same') { + var firstTrack = audiobook.tracks[0] + audioFileType = firstTrack.ext + } + filename = audiobookDirname + audioFileType + fileext = audioFileType filepath = Path.join(dlpath, filename) } @@ -97,33 +101,47 @@ class DownloadManager { } async processSingleAudioDownload(audiobook, download) { + + // If changing audio file type then encoding is needed + var requiresEncode = audiobook.tracks[0].ext !== download.ext || download.includeCover || download.includeMetadata + var concatFilePath = Path.join(download.dirpath, 'files.txt') await writeConcatFile(audiobook.tracks, concatFilePath) - var metadataFilePath = Path.join(download.dirpath, 'metadata.txt') - await writeMetadataFile(audiobook, metadataFilePath) - const ffmpegInputs = [ { input: concatFilePath, options: ['-safe 0', '-f concat'] - }, - { - input: metadataFilePath } ] const logLevel = process.env.NODE_ENV === 'production' ? 'error' : 'warning' - const ffmpegOptions = [ - `-loglevel ${logLevel}`, - '-map 0:a', - '-map_metadata 1', - '-acodec aac', - '-ac 2', - '-b:a 64k', - '-id3v2_version 3'] + var ffmpegOptions = [`-loglevel ${logLevel}`] - if (audiobook.book.cover) { + if (requiresEncode) { + ffmpegOptions = ffmpegOptions.concat([ + '-map 0:a', + '-acodec aac', + '-ac 2', + '-b:a 64k', + '-id3v2_version 3' + ]) + } else { + ffmpegOptions.push('-c copy') + } + + if (download.includeMetadata) { + var metadataFilePath = Path.join(download.dirpath, 'metadata.txt') + await writeMetadataFile(audiobook, metadataFilePath) + + ffmpegInputs.push({ + input: metadataFilePath + }) + + ffmpegOptions.push('-map_metadata 1') + } + + if (download.includeCover && audiobook.book.cover) { ffmpegInputs.push({ input: audiobook.book.cover, options: ['-f image2pipe'] diff --git a/server/objects/Download.js b/server/objects/Download.js index dff55948..a28ac2a6 100644 --- a/server/objects/Download.js +++ b/server/objects/Download.js @@ -28,6 +28,14 @@ class Download { } } + get includeMetadata() { + return !!this.options.includeMetadata + } + + get includeCover() { + return !!this.options.includeCover + } + get mimeType() { if (this.ext === '.mp3' || this.ext === '.m4b' || this.ext === '.m4a') { return 'audio/mpeg'