mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-11-08 17:14:18 +01:00
DRAFT client support for overdrive media markers
Initial client side support. Still a good amount to do. Specifically around actually parsing out all of the media markers, and generating a single chapter object that can be applied
This commit is contained in:
parent
fc614b9833
commit
27e6b9ce0d
@ -22,6 +22,16 @@
|
||||
<div class="w-40" />
|
||||
</div>
|
||||
|
||||
<div class="w-full max-w-3xl py-4" v-if="overdriveMediaMarkersExist">
|
||||
<div class="flex items-center">
|
||||
<p class="text-sm mb-4">Overdrive Media Markers Found! Would you like to generate chapter data from them?</p>
|
||||
<div class="flex-grow" />
|
||||
<ui-btn color="primary" small class="mx-2" @click="this.generateChaptersFromOverdriveMediaMarkers">Yes</ui-btn>
|
||||
<!-- <ui-btn color="error" small @click="saveChapters">No</ui-btn> -->
|
||||
<div class="w-40" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex text-xs uppercase text-gray-300 font-semibold mb-2">
|
||||
<div class="w-12"></div>
|
||||
<div class="w-32 px-2">Start</div>
|
||||
@ -85,6 +95,7 @@
|
||||
<span v-if="(track.chapters || []).length" class="material-icons text-success text-sm">check</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@ -131,6 +142,45 @@
|
||||
</div>
|
||||
</div>
|
||||
</modals-modal>
|
||||
|
||||
<modals-modal v-model="showImportOverdriveMediaMarkersModal" name="edit-book2" :width="500" :processing="findingChapters">
|
||||
<template #outer>
|
||||
<div class="absolute top-0 left-0 p-5 w-2/3 overflow-hidden pointer-events-none">
|
||||
<p class="font-book text-3xl text-white truncate pointer-events-none">Find Chapters</p>
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-full h-full max-h-full text-sm rounded-lg bg-bg shadow-lg border border-black-300 relative">
|
||||
<div v-if="!chapterData" class="flex p-20">
|
||||
<ui-text-input-with-label v-model="asinInput" label="NOT ASIN" />
|
||||
<ui-btn small color="primary" class="mt-5 ml-2" @click="findChapters">Find</ui-btn>
|
||||
</div>
|
||||
<div v-else class="w-full p-4">
|
||||
<p class="mb-4">Duration found: {{ chapterData.runtimeLengthSec }}</p>
|
||||
<div v-if="chapterData.runtimeLengthSec > mediaDuration" class="w-full bg-error bg-opacity-25 p-4 text-center mb-2 rounded border border-white border-opacity-10 text-gray-100 text-sm">
|
||||
<p>Chapter data invalid duration<br />Your media duration is shorter than duration found</p>
|
||||
</div>
|
||||
|
||||
<div class="flex py-0.5 text-xs font-semibold uppercase text-gray-300 mb-1">
|
||||
<div class="w-24 px-2">Start</div>
|
||||
<div class="flex-grow px-2">Title</div>
|
||||
</div>
|
||||
<div class="w-full max-h-80 overflow-y-auto my-2">
|
||||
<div v-for="(chapter, index) in chapterData.chapters" :key="index" class="flex py-0.5 text-xs" :class="chapter.startOffsetSec > mediaDuration ? 'bg-error bg-opacity-20' : chapter.startOffsetSec + chapter.lengthMs / 1000 > mediaDuration ? 'bg-warning bg-opacity-20' : index % 2 === 0 ? 'bg-primary bg-opacity-30' : ''">
|
||||
<div class="w-24 min-w-24 px-2">
|
||||
<p class="font-mono">{{ $secondsToTimestamp(chapter.startOffsetSec) }}</p>
|
||||
</div>
|
||||
<div class="flex-grow px-2">
|
||||
<p class="truncate max-w-sm">{{ chapter.title }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex pt-2">
|
||||
<div class="flex-grow" />
|
||||
<ui-btn small color="success" @click="applyChapterData">Apply Chapters</ui-btn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</modals-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -168,6 +218,7 @@ export default {
|
||||
asinInput: null,
|
||||
findingChapters: false,
|
||||
showFindChaptersModal: false,
|
||||
showImportOverdriveMediaMarkersModal: false,
|
||||
chapterData: null
|
||||
}
|
||||
},
|
||||
@ -190,13 +241,19 @@ export default {
|
||||
mediaDuration() {
|
||||
return this.media.duration
|
||||
},
|
||||
overdriveMediaMarkersExist() {
|
||||
return (this.overdriveMediaMarkers?.length > 0 ? true : false ) || false
|
||||
},
|
||||
overdriveMediaMarkers() {
|
||||
return this.audioFiles.map((af) => af.metaTags.tagOverdriveMediaMarker).filter(notUndefined => notUndefined !== undefined) || []
|
||||
},
|
||||
chapters() {
|
||||
return this.media.chapters || []
|
||||
},
|
||||
tracks() {
|
||||
return this.media.tracks || []
|
||||
},
|
||||
audioFiles() {
|
||||
audioFiles() {
|
||||
return this.media.audioFiles || []
|
||||
},
|
||||
audioTracks() {
|
||||
@ -207,6 +264,13 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkForOverdriveMediaMarkers() {
|
||||
if (this.overdriveMediaMarkersExist) {
|
||||
this.$toast.success('Your book has overdrive media markers!')
|
||||
} else {
|
||||
this.$toast.error('Your book DOES NOT have overdrive media markers!')
|
||||
}
|
||||
},
|
||||
editItem() {
|
||||
this.$store.commit('showEditModal', this.libraryItem)
|
||||
},
|
||||
@ -392,7 +456,7 @@ export default {
|
||||
this.$toast.error(data.error)
|
||||
this.showFindChaptersModal = false
|
||||
} else {
|
||||
console.log('Chapter data', data)
|
||||
console.log('Chapter data', JSON.stringify(data))
|
||||
this.chapterData = data
|
||||
}
|
||||
})
|
||||
@ -402,9 +466,41 @@ export default {
|
||||
this.$toast.error('Failed to find chapters')
|
||||
this.showFindChaptersModal = false
|
||||
})
|
||||
},
|
||||
// overdrive
|
||||
generateChaptersFromOverdriveMediaMarkers() {
|
||||
var parseString = require('xml2js').parseString;
|
||||
var xml = this.overdriveMediaMarkers[0]
|
||||
var parsedXML = {}
|
||||
parseString(xml, function (err, result) {
|
||||
parsedXML = result
|
||||
});
|
||||
|
||||
var index = 0
|
||||
var newOChapters = parsedXML.Markers.Marker.map((marker) => {
|
||||
return {
|
||||
id: index++,
|
||||
start: marker.Time[0],
|
||||
end: 0,
|
||||
title: marker.Name[0]
|
||||
}
|
||||
})
|
||||
console.log(newOChapters)
|
||||
//console.log(this.overdriveMediaMarkers[0])
|
||||
// console.log(JSON.stringify(x))
|
||||
//console.log(parseString(this.overdriveMediaMarkers[0]))
|
||||
// {
|
||||
// id:,
|
||||
// start:
|
||||
// end:
|
||||
// title:
|
||||
// }
|
||||
this.overdriveMediaMarkers
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.checkForOverdriveMediaMarkers()
|
||||
var dismissed = false
|
||||
this.asinInput = this.mediaMetadata.asin || null
|
||||
this.newChapters = this.chapters.map((c) => ({ ...c }))
|
||||
if (!this.newChapters.length) {
|
||||
|
Loading…
Reference in New Issue
Block a user