Add per-book playback rate to web client #1173

Save playbackRate to mediaProgress via PATCH on speed change.
Init from per-book rate with fallback to global user setting.
Guard settingsUpdated from overwriting per-book rates.
Resolve per-book rate in playLibraryItem before loading.
This commit is contained in:
Eyad 2026-03-05 00:22:57 +00:00
parent 8bd99a459e
commit df2db634a7
2 changed files with 35 additions and 4 deletions

View file

@ -528,7 +528,11 @@ export default {
if (this.$refs.audioPlayer) this.$refs.audioPlayer.checkUpdateChapterTrack()
})
this.playerHandler.load(libraryItem, episodeId, true, this.currentPlaybackRate, payload.startTime)
// Resolve per-book playback rate for the new item, falling back to current rate
const mediaProgress = this.$store.getters['user/getUserMediaProgress'](libraryItemId, episodeId)
const playbackRate = mediaProgress?.playbackRate || this.currentPlaybackRate
this.playerHandler.load(libraryItem, episodeId, true, playbackRate, payload.startTime)
},
pauseItem() {
this.playerHandler.pause()

View file

@ -110,6 +110,12 @@ export default {
useChapterTrack() {
if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(this.useChapterTrack)
this.updateTimestamp()
},
'$store.state.streamLibraryItem'() {
this.initPlaybackRate()
},
'$store.state.streamEpisodeId'() {
this.initPlaybackRate()
}
},
computed: {
@ -236,6 +242,15 @@ export default {
this.$store.dispatch('user/updateUserSettings', { playbackRate }).catch((err) => {
console.error('Failed to update settings', err)
})
// Save per-book playback rate to mediaProgress
const libraryItemId = this.$store.state.streamLibraryItem?.id
if (!libraryItemId) return
const episodeId = this.$store.state.streamEpisodeId
const progressId = episodeId ? `${libraryItemId}-${episodeId}` : libraryItemId
this.$axios.$patch(`/api/me/progress/${progressId}`, { playbackRate }).catch((err) => {
console.error('Failed to save playback rate to progress', err)
})
},
setPlaybackRate(playbackRate) {
this.$emit('setPlaybackRate', playbackRate)
@ -321,15 +336,27 @@ export default {
showPlayerSettings() {
this.showPlayerSettingsModal = !this.showPlayerSettingsModal
},
initPlaybackRate() {
const libraryItemId = this.$store.state.streamLibraryItem?.id
const episodeId = this.$store.state.streamEpisodeId
const mediaProgress = this.$store.getters['user/getUserMediaProgress'](libraryItemId, episodeId)
this.playbackRate = mediaProgress?.playbackRate || this.$store.getters['user/getUserSetting']('playbackRate') || 1
this.setPlaybackRate(this.playbackRate)
},
init() {
this.playbackRate = this.$store.getters['user/getUserSetting']('playbackRate') || 1
this.initPlaybackRate()
if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(this.useChapterTrack)
this.setPlaybackRate(this.playbackRate)
},
settingsUpdated(settings) {
if (settings.playbackRate && this.playbackRate !== settings.playbackRate) {
this.setPlaybackRate(settings.playbackRate)
// Don't let global setting override a per-book rate
const libraryItemId = this.$store.state.streamLibraryItem?.id
const episodeId = this.$store.state.streamEpisodeId
const mediaProgress = this.$store.getters['user/getUserMediaProgress'](libraryItemId, episodeId)
if (!mediaProgress?.playbackRate) {
this.setPlaybackRate(settings.playbackRate)
}
}
},
closePlayer() {