diff --git a/client/components/tables/TracksTable.vue b/client/components/tables/TracksTable.vue
index d0f93ff4..0b25720c 100644
--- a/client/components/tables/TracksTable.vue
+++ b/client/components/tables/TracksTable.vue
@@ -24,6 +24,14 @@
Size |
Duration |
Download |
+
+
+ Tone
+
+ information
+
+
+ |
@@ -38,7 +46,10 @@
{{ $secondsToTimestamp(track.duration) }}
- download
+ download
+ |
+
+
|
@@ -65,7 +76,8 @@ export default {
data() {
return {
showTracks: false,
- showFullPath: false
+ showFullPath: false,
+ toneProbing: false
}
},
computed: {
@@ -77,11 +89,35 @@ export default {
},
userCanUpdate() {
return this.$store.getters['user/getUserCanUpdate']
+ },
+ showExperimentalFeatures() {
+ return this.$store.state.showExperimentalFeatures
}
},
methods: {
clickBar() {
this.showTracks = !this.showTracks
+ },
+ toneProbe(index) {
+ this.toneProbing = true
+
+ this.$axios
+ .$post(`/api/items/${this.libraryItemId}/tone-scan/${index}`)
+ .then((data) => {
+ console.log('Tone probe data', data)
+ if (data.error) {
+ this.$toast.error('Tone probe error: ' + data.error)
+ } else {
+ this.$toast.success('Tone probe successful! Check browser console')
+ }
+ })
+ .catch((error) => {
+ console.error('Failed to tone probe', error)
+ this.$toast.error('Tone probe failed')
+ })
+ .finally(() => {
+ this.toneProbing = false
+ })
}
},
mounted() {}
diff --git a/server/controllers/LibraryItemController.js b/server/controllers/LibraryItemController.js
index bcaa3b33..b1f3f77d 100644
--- a/server/controllers/LibraryItemController.js
+++ b/server/controllers/LibraryItemController.js
@@ -1,5 +1,5 @@
const Logger = require('../Logger')
-const { reqSupportsWebp } = require('../utils/index')
+const { reqSupportsWebp, isNullOrNaN } = require('../utils/index')
const { ScanResult } = require('../utils/constants')
class LibraryItemController {
@@ -464,6 +464,22 @@ class LibraryItemController {
res.sendStatus(200)
}
+ async toneScan(req, res) {
+ if (!req.libraryItem.media.audioFiles.length) {
+ return res.sendStatus(404)
+ }
+
+ const audioFileIndex = isNullOrNaN(req.params.index) ? 1 : Number(req.params.index)
+ const audioFile = req.libraryItem.media.audioFiles.find(af => af.index === audioFileIndex)
+ if (!audioFile) {
+ Logger.error(`[LibraryItemController] toneScan: Audio file not found with index ${audioFileIndex}`)
+ return res.sendStatus(404)
+ }
+
+ const toneData = await this.scanner.probeAudioFileWithTone(audioFile)
+ res.json(toneData)
+ }
+
middleware(req, res, next) {
var item = this.db.libraryItems.find(li => li.id === req.params.id)
if (!item || !item.media) return res.sendStatus(404)
diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js
index e45adc4c..03fc9149 100644
--- a/server/routers/ApiRouter.js
+++ b/server/routers/ApiRouter.js
@@ -101,6 +101,7 @@ class ApiRouter {
this.router.post('/items/:id/chapters', LibraryItemController.middleware.bind(this), LibraryItemController.updateMediaChapters.bind(this))
this.router.post('/items/:id/open-feed', LibraryItemController.middleware.bind(this), LibraryItemController.openRSSFeed.bind(this))
this.router.post('/items/:id/close-feed', LibraryItemController.middleware.bind(this), LibraryItemController.closeRSSFeed.bind(this))
+ this.router.post('/items/:id/tone-scan/:index?', LibraryItemController.middleware.bind(this), LibraryItemController.toneScan.bind(this))
this.router.post('/items/batch/delete', LibraryItemController.batchDelete.bind(this))
this.router.post('/items/batch/update', LibraryItemController.batchUpdate.bind(this))
diff --git a/server/scanner/MediaFileScanner.js b/server/scanner/MediaFileScanner.js
index c57d30b2..fb22cb25 100644
--- a/server/scanner/MediaFileScanner.js
+++ b/server/scanner/MediaFileScanner.js
@@ -289,5 +289,10 @@ class MediaFileScanner {
return hasUpdated
}
+
+ probeAudioFileWithTone(audioFile) {
+ Logger.debug(`[MediaFileScanner] using tone to probe audio file "${audioFile.metadata.path}"`)
+ return toneProber.rawProbe(audioFile.metadata.path)
+ }
}
module.exports = new MediaFileScanner()
\ No newline at end of file
diff --git a/server/scanner/Scanner.js b/server/scanner/Scanner.js
index e0604123..2caf9e0e 100644
--- a/server/scanner/Scanner.js
+++ b/server/scanner/Scanner.js
@@ -991,5 +991,9 @@ class Scanner {
this.librariesScanning = this.librariesScanning.filter(ls => ls.id !== library.id)
this.emitter('scan_complete', libraryScan.getScanEmitData)
}
+
+ probeAudioFileWithTone(audioFile) {
+ return MediaFileScanner.probeAudioFileWithTone(audioFile)
+ }
}
module.exports = Scanner
\ No newline at end of file
diff --git a/server/utils/toneProber.js b/server/utils/toneProber.js
index 44dee28b..c1d8de9d 100644
--- a/server/utils/toneProber.js
+++ b/server/utils/toneProber.js
@@ -155,4 +155,19 @@ module.exports.probe = (filepath, verbose = false) => {
error
}
})
+}
+
+module.exports.rawProbe = (filepath) => {
+ if (process.env.TONE_PATH) {
+ tone.TONE_PATH = process.env.TONE_PATH
+ }
+
+ return tone.dump(filepath).then((dumpPayload) => {
+ return dumpPayload
+ }).catch((error) => {
+ Logger.error(`[toneProber] Failed to probe file at path "${filepath}"`, error)
+ return {
+ error
+ }
+ })
}
\ No newline at end of file