Add:Audio player next/prev chapter buttons

This commit is contained in:
advplyr 2022-06-04 12:07:38 -05:00
parent 3171ce5aba
commit 2d5e4ebcf0
6 changed files with 61 additions and 12 deletions

View File

@ -38,6 +38,12 @@ export default {
userIsAdminOrUp() {
return this.$store.getters['user/getIsAdminOrUp']
},
user() {
return this.$store.state.user.user || {}
},
userId() {
return this.user.id
},
configRoutes() {
if (!this.userIsAdminOrUp) {
return [
@ -87,6 +93,11 @@ export default {
title: 'Your Stats',
path: '/config/stats'
})
configRoutes.push({
id: 'config-users-id-sessions',
title: 'Your Sessions',
path: `/config/users/${this.userId}/sessions`
})
}
return configRoutes

View File

@ -2,18 +2,21 @@
<div class="flex pt-4 pb-2 md:pt-0 md:pb-2">
<div class="flex-grow" />
<template v-if="!loading">
<div class="cursor-pointer flex items-center justify-center text-gray-300 mr-8" @mousedown.prevent @mouseup.prevent @click.stop="restart">
<div class="cursor-pointer flex items-center justify-center text-gray-300 mr-4 md:mr-8" @mousedown.prevent @mouseup.prevent @click.stop="prevChapter">
<span class="material-icons text-3xl">first_page</span>
</div>
<div class="cursor-pointer flex items-center justify-center text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpBackward">
<span class="material-icons text-3xl">replay_10</span>
</div>
<div class="cursor-pointer p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-8" :class="seekLoading ? 'animate-spin' : ''" @mousedown.prevent @mouseup.prevent @click.stop="playPause">
<div class="cursor-pointer p-2 shadow-sm bg-accent flex items-center justify-center rounded-full text-primary mx-4 md:mx-8" :class="seekLoading ? 'animate-spin' : ''" @mousedown.prevent @mouseup.prevent @click.stop="playPause">
<span class="material-icons">{{ seekLoading ? 'autorenew' : paused ? 'play_arrow' : 'pause' }}</span>
</div>
<div class="cursor-pointer flex items-center justify-center text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="jumpForward">
<span class="material-icons text-3xl">forward_10</span>
</div>
<div class="flex items-center justify-center ml-4 md:ml-8" :class="hasNextChapter ? 'text-gray-300 cursor-pointer' : 'text-gray-500'" @mousedown.prevent @mouseup.prevent @click.stop="nextChapter">
<span class="material-icons text-3xl">last_page</span>
</div>
<controls-playback-speed-control v-model="playbackRate" @input="playbackRateUpdated" @change="playbackRateChanged" />
</template>
<template v-else>
@ -31,7 +34,8 @@ export default {
loading: Boolean,
seekLoading: Boolean,
playbackRate: Number,
paused: Boolean
paused: Boolean,
hasNextChapter: Boolean
},
data() {
return {}
@ -41,8 +45,12 @@ export default {
playPause() {
this.$emit('playPause')
},
restart() {
this.$emit('restart')
prevChapter() {
this.$emit('prevChapter')
},
nextChapter() {
if (!this.hasNextChapter) return
this.$emit('nextChapter')
},
jumpBackward() {
this.$emit('jumpBackward')

View File

@ -23,7 +23,7 @@
</div>
</div>
<player-playback-controls :loading="loading" :seek-loading="seekLoading" :playback-rate="playbackRate" :paused="paused" @restart="restart" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setPlaybackRate="setPlaybackRate" @playPause="playPause" />
<player-playback-controls :loading="loading" :seek-loading="seekLoading" :playback-rate="playbackRate" :paused="paused" :has-next-chapter="hasNextChapter" @prevChapter="prevChapter" @nextChapter="nextChapter" @jumpForward="jumpForward" @jumpBackward="jumpBackward" @setPlaybackRate="setPlaybackRate" @playPause="playPause" />
</div>
<player-track-bar ref="trackbar" :loading="loading" :chapters="chapters" :duration="duration" @seek="seek" />
@ -106,6 +106,14 @@ export default {
},
isFullscreen() {
return this.$store.state.playerIsFullscreen
},
currentChapterIndex() {
if (!this.currentChapter) return 0
return this.chapters.findIndex((ch) => ch.id === this.currentChapter.id)
},
hasNextChapter() {
if (!this.chapters.length) return false
return this.currentChapterIndex < this.chapters.length - 1
}
},
methods: {
@ -190,6 +198,23 @@ export default {
restart() {
this.seek(0)
},
prevChapter() {
if (!this.currentChapter || this.currentChapterIndex === 0) {
return this.restart()
}
var timeInCurrentChapter = this.currentTime - this.currentChapter.start
if (timeInCurrentChapter <= 3 && this.chapters[this.currentChapterIndex - 1]) {
var prevChapter = this.chapters[this.currentChapterIndex - 1]
this.seek(prevChapter.start)
} else {
this.seek(this.currentChapter.start)
}
},
nextChapter() {
if (!this.currentChapter || !this.hasNextChapter) return
var nextChapter = this.chapters[this.currentChapterIndex + 1]
this.seek(nextChapter.start)
},
setStreamReady() {
if (this.$refs.trackbar) this.$refs.trackbar.setPercentageReady(1)
},

View File

@ -1,13 +1,13 @@
<template>
<div id="page-wrapper" class="bg-bg page overflow-y-auto p-8" :class="streamLibraryItem ? 'streaming' : ''">
<div id="page-wrapper" class="bg-bg page overflow-y-auto p-4 md:p-8" :class="streamLibraryItem ? 'streaming' : ''">
<div class="max-w-6xl mx-auto">
<div class="flex mb-6">
<div class="flex flex-wrap sm:flex-nowrap justify-center mb-6">
<div class="w-48 min-w-48">
<div class="w-full h-52">
<covers-author-image :author="author" rounded="0" />
</div>
</div>
<div class="flex-grow px-8">
<div class="flex-grow py-4 sm:py-0 px-4 md:px-8">
<div class="flex items-center mb-8">
<h1 class="text-2xl">{{ author.name }}</h1>

View File

@ -124,6 +124,8 @@ export default class CastPlayer extends EventEmitter {
async seek(time, playWhenReady) {
if (!this.player) return
this.playWhenReady = playWhenReady
if (time < this.currentTrack.startOffset || time > this.currentTrack.startOffset + this.currentTrack.duration) {
// Change Track
var request = buildCastLoadRequest(this.libraryItem, this.coverUrl, this.audioTracks, time, playWhenReady, this.defaultPlaybackRate)

View File

@ -71,7 +71,7 @@ export default class LocalAudioPlayer extends EventEmitter {
console.log(`[LocalPlayer] Track ended - loading next track ${this.currentTrackIndex + 1}`)
// Has next track
this.currentTrackIndex++
this.playWhenReady = true
this.playWhenReady = !this.player.paused
this.startTime = this.currentTrack.startOffset
this.loadCurrentTrack()
} else {
@ -89,6 +89,7 @@ export default class LocalAudioPlayer extends EventEmitter {
}
this.emit('stateChange', 'LOADED')
if (this.playWhenReady) {
this.playWhenReady = false
this.play()
@ -229,8 +230,11 @@ export default class LocalAudioPlayer extends EventEmitter {
this.player.playbackRate = playbackRate
}
seek(time) {
seek(time, playWhenReady) {
if (!this.player) return
this.playWhenReady = playWhenReady
if (this.isHlsTranscode) {
// Seeking HLS stream
var offsetTime = time - (this.currentTrack.startOffset || 0)
@ -255,7 +259,6 @@ export default class LocalAudioPlayer extends EventEmitter {
this.player.currentTime = Math.max(0, offsetTime)
}
}
}
setVolume(volume) {