Add:Button for testing scan probes in audiobook tracks table

This commit is contained in:
advplyr 2022-10-02 15:24:32 -05:00
parent d22b475539
commit c254dc5144
6 changed files with 80 additions and 3 deletions

View File

@ -24,6 +24,14 @@
<th class="text-left w-20">Size</th> <th class="text-left w-20">Size</th>
<th class="text-left w-20">Duration</th> <th class="text-left w-20">Duration</th>
<th v-if="userCanDownload" class="text-center w-20">Download</th> <th v-if="userCanDownload" class="text-center w-20">Download</th>
<th v-if="showExperimentalFeatures" class="text-center w-20">
<div class="flex items-center">
<p>Tone</p>
<ui-tooltip text="Experimental feature for testing Tone library metadata scan results. Results logged in browser console." class="ml-2 w-2" direction="left">
<span class="material-icons-outlined text-sm">information</span>
</ui-tooltip>
</div>
</th>
</tr> </tr>
<template v-for="track in tracks"> <template v-for="track in tracks">
<tr :key="track.index"> <tr :key="track.index">
@ -38,7 +46,10 @@
{{ $secondsToTimestamp(track.duration) }} {{ $secondsToTimestamp(track.duration) }}
</td> </td>
<td v-if="userCanDownload" class="text-center"> <td v-if="userCanDownload" class="text-center">
<a :href="`${$config.routerBasePath}/s/item/${libraryItemId}/${$encodeUriPath(track.metadata.relPath).replace(/^\//, '')}?token=${userToken}`" download><span class="material-icons icon-text">download</span></a> <a :href="`${$config.routerBasePath}/s/item/${libraryItemId}/${$encodeUriPath(track.metadata.relPath).replace(/^\//, '')}?token=${userToken}`" download><span class="material-icons icon-text pt-1">download</span></a>
</td>
<td v-if="showExperimentalFeatures" class="text-center">
<ui-icon-btn borderless :loading="toneProbing" icon="search" @click="toneProbe(track.index)" />
</td> </td>
</tr> </tr>
</template> </template>
@ -65,7 +76,8 @@ export default {
data() { data() {
return { return {
showTracks: false, showTracks: false,
showFullPath: false showFullPath: false,
toneProbing: false
} }
}, },
computed: { computed: {
@ -77,11 +89,35 @@ export default {
}, },
userCanUpdate() { userCanUpdate() {
return this.$store.getters['user/getUserCanUpdate'] return this.$store.getters['user/getUserCanUpdate']
},
showExperimentalFeatures() {
return this.$store.state.showExperimentalFeatures
} }
}, },
methods: { methods: {
clickBar() { clickBar() {
this.showTracks = !this.showTracks 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() {} mounted() {}

View File

@ -1,5 +1,5 @@
const Logger = require('../Logger') const Logger = require('../Logger')
const { reqSupportsWebp } = require('../utils/index') const { reqSupportsWebp, isNullOrNaN } = require('../utils/index')
const { ScanResult } = require('../utils/constants') const { ScanResult } = require('../utils/constants')
class LibraryItemController { class LibraryItemController {
@ -464,6 +464,22 @@ class LibraryItemController {
res.sendStatus(200) 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) { middleware(req, res, next) {
var item = this.db.libraryItems.find(li => li.id === req.params.id) var item = this.db.libraryItems.find(li => li.id === req.params.id)
if (!item || !item.media) return res.sendStatus(404) if (!item || !item.media) return res.sendStatus(404)

View File

@ -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/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/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/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/delete', LibraryItemController.batchDelete.bind(this))
this.router.post('/items/batch/update', LibraryItemController.batchUpdate.bind(this)) this.router.post('/items/batch/update', LibraryItemController.batchUpdate.bind(this))

View File

@ -289,5 +289,10 @@ class MediaFileScanner {
return hasUpdated 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() module.exports = new MediaFileScanner()

View File

@ -991,5 +991,9 @@ class Scanner {
this.librariesScanning = this.librariesScanning.filter(ls => ls.id !== library.id) this.librariesScanning = this.librariesScanning.filter(ls => ls.id !== library.id)
this.emitter('scan_complete', libraryScan.getScanEmitData) this.emitter('scan_complete', libraryScan.getScanEmitData)
} }
probeAudioFileWithTone(audioFile) {
return MediaFileScanner.probeAudioFileWithTone(audioFile)
}
} }
module.exports = Scanner module.exports = Scanner

View File

@ -156,3 +156,18 @@ module.exports.probe = (filepath, verbose = false) => {
} }
}) })
} }
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
}
})
}