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:
jmt-gh 2022-06-11 02:01:37 -07:00
parent fc614b9833
commit 27e6b9ce0d

View File

@ -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) {