mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-20 18:59:37 +00:00
Adding files tables, fixing loading when switching streams
This commit is contained in:
parent
30ca0bb95f
commit
a89d2e71cc
18 changed files with 233 additions and 76 deletions
|
|
@ -42,11 +42,12 @@
|
|||
</div>
|
||||
<div class="relative">
|
||||
<!-- Track -->
|
||||
<div ref="track" class="w-full h-2 bg-gray-700 relative cursor-pointer transform duration-100 hover:scale-y-125" :class="loading ? 'animate-pulse' : ''" @mousemove="mousemoveTrack" @mouseleave="mouseleaveTrack" @click.stop="clickTrack">
|
||||
<div ref="readyTrack" class="h-full bg-gray-600 absolute top-0 left-0 pointer-events-none" />
|
||||
<div ref="track" class="w-full h-2 bg-gray-700 relative cursor-pointer transform duration-100 hover:scale-y-125 overflow-hidden" @mousemove="mousemoveTrack" @mouseleave="mouseleaveTrack" @click.stop="clickTrack">
|
||||
<div ref="readyTrack" class="h-full bg-gray-500 absolute top-0 left-0 pointer-events-none" />
|
||||
<div ref="bufferTrack" class="h-full bg-gray-400 absolute top-0 left-0 pointer-events-none" />
|
||||
<div ref="playedTrack" class="h-full bg-gray-200 absolute top-0 left-0 pointer-events-none" />
|
||||
<div ref="trackCursor" class="h-full w-0.5 bg-gray-50 absolute top-0 left-0 opacity-0 pointer-events-none" />
|
||||
<div v-if="loading" class="h-full w-1/4 absolute left-0 top-0 loadingTrack pointer-events-none bg-white bg-opacity-25" />
|
||||
</div>
|
||||
|
||||
<!-- Hover timestamp -->
|
||||
|
|
@ -97,6 +98,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
seek(time) {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
if (this.seekLoading) {
|
||||
console.error('Already seek loading', this.seekedTime)
|
||||
return
|
||||
|
|
@ -169,6 +173,7 @@ export default {
|
|||
setStreamReady() {
|
||||
this.readyTrackWidth = this.trackWidth
|
||||
this.$refs.readyTrack.style.width = this.trackWidth + 'px'
|
||||
console.warn('SET STREAM READY', this.readyTrackWidth)
|
||||
},
|
||||
setChunksReady(chunks, numSegments) {
|
||||
var largestSeg = 0
|
||||
|
|
@ -307,7 +312,6 @@ export default {
|
|||
console.error('No audio on paused()')
|
||||
return
|
||||
}
|
||||
console.log('Paused')
|
||||
this.isPaused = this.$refs.audio.paused
|
||||
},
|
||||
playing() {
|
||||
|
|
@ -321,7 +325,6 @@ export default {
|
|||
this.totalDuration = this.audioEl.duration
|
||||
},
|
||||
set(url, currentTime, playOnLoad = false) {
|
||||
console.log('[AudioPlayer] SET PlayOnLoad ', playOnLoad)
|
||||
if (this.hlsInstance) {
|
||||
this.terminateStream()
|
||||
}
|
||||
|
|
@ -342,13 +345,13 @@ export default {
|
|||
xhr.setRequestHeader('Authorization', `Bearer ${this.token}`)
|
||||
}
|
||||
}
|
||||
console.log('[AudioPlayer-Set] HLS Config', hlsOptions, this.$secondsToTimestamp(hlsOptions.startPosition))
|
||||
console.log('[AudioPlayer-Set] HLS Config', hlsOptions)
|
||||
this.hlsInstance = new Hls(hlsOptions)
|
||||
var audio = this.$refs.audio
|
||||
audio.volume = this.volume
|
||||
this.hlsInstance.attachMedia(audio)
|
||||
this.hlsInstance.on(Hls.Events.MEDIA_ATTACHED, () => {
|
||||
console.log('[HLS] MEDIA ATTACHED')
|
||||
// console.log('[HLS] MEDIA ATTACHED')
|
||||
this.hlsInstance.loadSource(url)
|
||||
|
||||
this.hlsInstance.on(Hls.Events.MANIFEST_PARSED, function () {
|
||||
|
|
@ -366,10 +369,7 @@ export default {
|
|||
})
|
||||
this.hlsInstance.on(Hls.Events.FRAG_LOADED, (e, data) => {
|
||||
var frag = data.frag
|
||||
console.log('[HLS] Frag Loaded', frag.sn, this.$secondsToTimestamp(frag.start), frag)
|
||||
})
|
||||
this.hlsInstance.on(Hls.Events.STREAM_STATE_TRANSITION, (e, data) => {
|
||||
console.log('[HLS] Stream State Transition', data)
|
||||
// console.log('[HLS] Frag Loaded', frag.sn, this.$secondsToTimestamp(frag.start), frag)
|
||||
})
|
||||
this.hlsInstance.on(Hls.Events.BUFFER_APPENDED, (e, data) => {
|
||||
// console.log('[HLS] BUFFER', data)
|
||||
|
|
@ -419,7 +419,8 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(this.init)
|
||||
// this.$nextTick(this.init)
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -432,4 +433,17 @@ export default {
|
|||
border-right: 6px solid transparent;
|
||||
border-top: 6px solid white;
|
||||
}
|
||||
.loadingTrack {
|
||||
animation-name: loadingTrack;
|
||||
animation-duration: 1s;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
@keyframes loadingTrack {
|
||||
0% {
|
||||
left: -25%;
|
||||
}
|
||||
100% {
|
||||
left: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="w-full h-16 bg-primary relative">
|
||||
<div id="appbar" class="absolute top-0 bottom-0 left-0 w-full h-full px-6 py-1 z-10">
|
||||
<div id="appbar" class="absolute top-0 bottom-0 left-0 w-full h-full px-6 py-1 z-20">
|
||||
<div class="flex h-full items-center">
|
||||
<img v-if="!showBack" src="/LogoTransparent.png" class="w-12 h-12 mr-4" />
|
||||
<a v-if="showBack" @click="back" class="rounded-full h-12 w-12 flex items-center justify-center hover:bg-white hover:bg-opacity-10 mr-4 cursor-pointer">
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
<span v-if="stream" class="material-icons px-4 cursor-pointer" @click="cancelStream">close</span>
|
||||
</div>
|
||||
|
||||
<audio-player ref="audioPlayer" :loading="!stream" @updateTime="updateTime" @hook:mounted="audioPlayerMounted" />
|
||||
<audio-player ref="audioPlayer" :loading="isLoading" @updateTime="updateTime" @hook:mounted="audioPlayerMounted" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -34,6 +34,14 @@ export default {
|
|||
user() {
|
||||
return this.$store.state.user
|
||||
},
|
||||
isLoading() {
|
||||
if (!this.streamAudiobook) return false
|
||||
if (this.stream) {
|
||||
// IF Stream exists, set loading if stream is diff from next stream
|
||||
return this.stream.audiobook.id !== this.streamAudiobook.id
|
||||
}
|
||||
return true
|
||||
},
|
||||
streamAudiobook() {
|
||||
return this.$store.state.streamAudiobook
|
||||
},
|
||||
|
|
@ -56,7 +64,7 @@ export default {
|
|||
methods: {
|
||||
audioPlayerMounted() {
|
||||
if (this.stream) {
|
||||
// this.$refs.audioPlayer.set(this.playlistUrl)
|
||||
console.log('[STREAM-CONTAINER] audioPlayerMounted w/ Stream', this.stream)
|
||||
this.openStream()
|
||||
}
|
||||
},
|
||||
|
|
@ -77,6 +85,9 @@ export default {
|
|||
}
|
||||
var currentTime = this.stream.clientCurrentTime || 0
|
||||
this.$refs.audioPlayer.set(this.playlistUrl, currentTime, playOnLoad)
|
||||
if (this.stream.isTranscodeComplete) {
|
||||
this.$refs.audioPlayer.setStreamReady()
|
||||
}
|
||||
},
|
||||
streamProgress(data) {
|
||||
if (!data.numSegments) return
|
||||
|
|
@ -87,14 +98,16 @@ export default {
|
|||
},
|
||||
streamOpen(stream) {
|
||||
this.stream = stream
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.audioPlayer) {
|
||||
console.log('[STREAM-CONTAINER] streamOpen', stream)
|
||||
this.openStream()
|
||||
})
|
||||
}
|
||||
},
|
||||
streamClosed(streamId) {
|
||||
if (this.stream && this.stream.id === streamId) {
|
||||
this.terminateStream()
|
||||
this.$store.commit('clearStreamAudiobook', this.stream.audiobook.id)
|
||||
this.stream = null
|
||||
}
|
||||
},
|
||||
streamReady() {
|
||||
|
|
@ -123,14 +136,6 @@ export default {
|
|||
this.$refs.audioPlayer.resetStream(startTime)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.stream) {
|
||||
console.log('[STREAM_CONTAINER] Mounted with STREAM', this.stream)
|
||||
this.$nextTick(() => {
|
||||
this.openStream()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
67
client/components/tables/AudioFilesTable.vue
Normal file
67
client/components/tables/AudioFilesTable.vue
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<div class="w-full my-2">
|
||||
<div class="w-full bg-primary px-6 py-2 flex items-center cursor-pointer" @click.stop="clickBar">
|
||||
<p class="pr-4">Other Audio Files</p>
|
||||
<span class="bg-black-400 rounded-xl py-1 px-2 text-sm font-mono">{{ files.length }}</span>
|
||||
<div class="flex-grow" />
|
||||
<nuxt-link :to="`/audiobook/${audiobookId}/edit`" class="mr-4">
|
||||
<ui-btn small color="primary">Manage Tracks</ui-btn>
|
||||
</nuxt-link>
|
||||
<div class="cursor-pointer h-10 w-10 rounded-full hover:bg-black-400 flex justify-center items-center duration-500" :class="showTracks ? 'transform rotate-180' : ''">
|
||||
<span class="material-icons text-4xl">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<div class="w-full" v-show="showTracks">
|
||||
<table class="text-sm tracksTable">
|
||||
<tr class="font-book">
|
||||
<th class="text-left">Filename</th>
|
||||
<th class="text-left">Size</th>
|
||||
<th class="text-left">Duration</th>
|
||||
<th class="text-left">Notes</th>
|
||||
</tr>
|
||||
<template v-for="track in files">
|
||||
<tr :key="track.path">
|
||||
<td class="font-book pl-2">
|
||||
{{ track.filename }}
|
||||
</td>
|
||||
<td class="font-mono">
|
||||
{{ $bytesPretty(track.size) }}
|
||||
</td>
|
||||
<td class="font-mono">
|
||||
{{ $secondsToTimestamp(track.duration) }}
|
||||
</td>
|
||||
<td class="text-xs">
|
||||
<p>{{ track.error || '' }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
audiobookId: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showTracks: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
clickBar() {
|
||||
this.showTracks = !this.showTracks
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
59
client/components/tables/OtherFilesTable.vue
Normal file
59
client/components/tables/OtherFilesTable.vue
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<div class="w-full my-2">
|
||||
<div class="w-full bg-primary px-6 py-2 flex items-center cursor-pointer" @click.stop="clickBar">
|
||||
<p class="pr-4">Other Files</p>
|
||||
<span class="bg-black-400 rounded-xl py-1 px-2 text-sm font-mono">{{ files.length }}</span>
|
||||
<div class="flex-grow" />
|
||||
<!-- <nuxt-link :to="`/audiobook/${audiobookId}/edit`" class="mr-4">
|
||||
<ui-btn small color="primary">Manage Tracks</ui-btn>
|
||||
</nuxt-link> -->
|
||||
<div class="cursor-pointer h-10 w-10 rounded-full hover:bg-black-400 flex justify-center items-center duration-500" :class="showFiles ? 'transform rotate-180' : ''">
|
||||
<span class="material-icons text-4xl">expand_more</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="slide">
|
||||
<div class="w-full" v-show="showFiles">
|
||||
<table class="text-sm tracksTable">
|
||||
<tr class="font-book">
|
||||
<th class="text-left">Path</th>
|
||||
<th class="text-left">Filetype</th>
|
||||
</tr>
|
||||
<template v-for="file in files">
|
||||
<tr :key="file.path">
|
||||
<td class="font-book pl-2">
|
||||
{{ file.path }}
|
||||
</td>
|
||||
<td class="text-xs">
|
||||
<p>{{ file.filetype }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
files: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
audiobookId: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showFiles: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
clickBar() {
|
||||
this.showFiles = !this.showFiles
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
<span class="bg-black-400 rounded-xl py-1 px-2 text-sm font-mono">{{ tracks.length }}</span>
|
||||
<div class="flex-grow" />
|
||||
<nuxt-link :to="`/audiobook/${audiobookId}/edit`" class="mr-4">
|
||||
<ui-btn small color="primary">Edit Track Order</ui-btn>
|
||||
<ui-btn small color="primary">Manage Tracks</ui-btn>
|
||||
</nuxt-link>
|
||||
<div class="cursor-pointer h-10 w-10 rounded-full hover:bg-black-400 flex justify-center items-center duration-500" :class="showTracks ? 'transform rotate-180' : ''">
|
||||
<span class="material-icons text-4xl">expand_more</span>
|
||||
Loading…
Add table
Add a link
Reference in a new issue