mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Update:Adjust timestamps in player for playback speed #1647
This commit is contained in:
		
							parent
							
								
									042c89039c
								
							
						
					
					
						commit
						a59311f795
					
				| @ -81,7 +81,7 @@ export default { | ||||
|       sleepTimerRemaining: 0, | ||||
|       sleepTimer: null, | ||||
|       displayTitle: null, | ||||
|       initialPlaybackRate: 1, | ||||
|       currentPlaybackRate: 1, | ||||
|       syncFailedToast: null | ||||
|     } | ||||
|   }, | ||||
| @ -152,7 +152,8 @@ export default { | ||||
|       return this.streamLibraryItem ? this.streamLibraryItem.libraryId : null | ||||
|     }, | ||||
|     totalDurationPretty() { | ||||
|       return this.$secondsToTimestamp(this.totalDuration) | ||||
|       // Adjusted by playback rate | ||||
|       return this.$secondsToTimestamp(this.totalDuration / this.currentPlaybackRate) | ||||
|     }, | ||||
|     podcastAuthor() { | ||||
|       if (!this.isPodcast) return null | ||||
| @ -255,7 +256,7 @@ export default { | ||||
|       this.playerHandler.setVolume(volume) | ||||
|     }, | ||||
|     setPlaybackRate(playbackRate) { | ||||
|       this.initialPlaybackRate = playbackRate | ||||
|       this.currentPlaybackRate = playbackRate | ||||
|       this.playerHandler.setPlaybackRate(playbackRate) | ||||
|     }, | ||||
|     seek(time) { | ||||
| @ -384,7 +385,7 @@ export default { | ||||
|         libraryItem: session.libraryItem, | ||||
|         episodeId: session.episodeId | ||||
|       }) | ||||
|       this.playerHandler.prepareOpenSession(session, this.initialPlaybackRate) | ||||
|       this.playerHandler.prepareOpenSession(session, this.currentPlaybackRate) | ||||
|     }, | ||||
|     streamOpen(session) { | ||||
|       console.log(`[StreamContainer] Stream session open`, session) | ||||
| @ -451,7 +452,7 @@ export default { | ||||
|         if (this.$refs.audioPlayer) this.$refs.audioPlayer.checkUpdateChapterTrack() | ||||
|       }) | ||||
| 
 | ||||
|       this.playerHandler.load(libraryItem, episodeId, true, this.initialPlaybackRate, payload.startTime) | ||||
|       this.playerHandler.load(libraryItem, episodeId, true, this.currentPlaybackRate, payload.startTime) | ||||
|     }, | ||||
|     pauseItem() { | ||||
|       this.playerHandler.pause() | ||||
|  | ||||
| @ -2,13 +2,13 @@ | ||||
|   <modals-modal v-model="show" name="chapters" :width="600" :height="'unset'"> | ||||
|     <div id="chapter-modal-wrapper" ref="container" class="w-full rounded-lg bg-primary box-shadow-md overflow-y-auto overflow-x-hidden" style="max-height: 80vh"> | ||||
|       <template v-for="chap in chapters"> | ||||
|         <div :key="chap.id" :id="`chapter-row-${chap.id}`" class="flex items-center px-6 py-3 justify-start cursor-pointer hover:bg-bg relative" :class="chap.id === currentChapterId ? 'bg-yellow-400 bg-opacity-10' : chap.end <= currentChapterStart ? 'bg-success bg-opacity-5' : 'bg-opacity-20'" @click="clickChapter(chap)"> | ||||
|         <div :key="chap.id" :id="`chapter-row-${chap.id}`" class="flex items-center px-6 py-3 justify-start cursor-pointer hover:bg-bg relative" :class="chap.id === currentChapterId ? 'bg-yellow-400 bg-opacity-10' : chap.end / _playbackRate <= currentChapterStart ? 'bg-success bg-opacity-5' : 'bg-opacity-20'" @click="clickChapter(chap)"> | ||||
|           <p class="chapter-title truncate text-sm md:text-base"> | ||||
|             {{ chap.title }} | ||||
|           </p> | ||||
|           <span class="font-mono text-xxs sm:text-xs text-gray-400 pl-2 whitespace-nowrap">{{ $elapsedPrettyExtended(chap.end - chap.start) }}</span> | ||||
|           <span class="font-mono text-xxs sm:text-xs text-gray-400 pl-2 whitespace-nowrap">{{ $elapsedPrettyExtended((chap.end - chap.start) / _playbackRate) }}</span> | ||||
|           <span class="flex-grow" /> | ||||
|           <span class="font-mono text-xs sm:text-sm text-gray-300">{{ $secondsToTimestamp(chap.start) }}</span> | ||||
|           <span class="font-mono text-xs sm:text-sm text-gray-300">{{ $secondsToTimestamp(chap.start / _playbackRate) }}</span> | ||||
| 
 | ||||
|           <div v-show="chap.id === currentChapterId" class="w-0.5 h-full absolute top-0 left-0 bg-yellow-400" /> | ||||
|         </div> | ||||
| @ -28,7 +28,8 @@ export default { | ||||
|     currentChapter: { | ||||
|       type: Object, | ||||
|       default: () => null | ||||
|     } | ||||
|     }, | ||||
|     playbackRate: Number | ||||
|   }, | ||||
|   data() { | ||||
|     return {} | ||||
| @ -47,11 +48,15 @@ export default { | ||||
|         this.$emit('input', val) | ||||
|       } | ||||
|     }, | ||||
|     _playbackRate() { | ||||
|       if (!this.playbackRate || isNaN(this.playbackRate)) return 1 | ||||
|       return this.playbackRate | ||||
|     }, | ||||
|     currentChapterId() { | ||||
|       return this.currentChapter ? this.currentChapter.id : null | ||||
|     }, | ||||
|     currentChapterStart() { | ||||
|       return this.currentChapter ? this.currentChapter.start : 0 | ||||
|       return (this.currentChapter?.start || 0) / this._playbackRate | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
| @ -61,13 +66,11 @@ export default { | ||||
|     scrollToChapter() { | ||||
|       if (!this.currentChapterId) return | ||||
| 
 | ||||
|       var container = this.$refs.container | ||||
|       if (container) { | ||||
|         var currChapterEl = document.getElementById(`chapter-row-${this.currentChapterId}`) | ||||
|       if (this.$refs.container) { | ||||
|         const currChapterEl = document.getElementById(`chapter-row-${this.currentChapterId}`) | ||||
|         if (currChapterEl) { | ||||
|           var offsetTop = currChapterEl.offsetTop | ||||
|           var containerHeight = container.clientHeight | ||||
|           container.scrollTo({ top: offsetTop - containerHeight / 2 }) | ||||
|           const containerHeight = this.$refs.container.clientHeight | ||||
|           this.$refs.container.scrollTo({ top: currChapterEl.offsetTop - containerHeight / 2 }) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @ -38,7 +38,8 @@ export default { | ||||
|     currentChapter: { | ||||
|       type: Object, | ||||
|       default: () => {} | ||||
|     } | ||||
|     }, | ||||
|     playbackRate: Number | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
| @ -63,6 +64,10 @@ export default { | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     _playbackRate() { | ||||
|       if (!this.playbackRate || isNaN(this.playbackRate)) return 1 | ||||
|       return this.playbackRate | ||||
|     }, | ||||
|     currentChapterDuration() { | ||||
|       if (!this.currentChapter) return 0 | ||||
|       return this.currentChapter.end - this.currentChapter.start | ||||
| @ -81,8 +86,8 @@ export default { | ||||
|     clickTrack(e) { | ||||
|       if (this.loading) return | ||||
| 
 | ||||
|       var offsetX = e.offsetX | ||||
|       var perc = offsetX / this.trackWidth | ||||
|       const offsetX = e.offsetX | ||||
|       const perc = offsetX / this.trackWidth | ||||
|       const baseTime = this.useChapterTrack ? this.currentChapterStart : 0 | ||||
|       const duration = this.useChapterTrack ? this.currentChapterDuration : this.duration | ||||
|       const time = baseTime + perc * duration | ||||
| @ -111,7 +116,7 @@ export default { | ||||
|       this.updateReadyTrack() | ||||
|     }, | ||||
|     updateReadyTrack() { | ||||
|       var widthReady = Math.round(this.trackWidth * this.percentReady) | ||||
|       const widthReady = Math.round(this.trackWidth * this.percentReady) | ||||
|       if (this.readyTrackWidth === widthReady) return | ||||
|       this.readyTrackWidth = widthReady | ||||
|       if (this.$refs.readyTrack) this.$refs.readyTrack.style.width = widthReady + 'px' | ||||
| @ -124,7 +129,7 @@ export default { | ||||
|       const time = this.useChapterTrack ? Math.max(0, this.currentTime - this.currentChapterStart) : this.currentTime | ||||
|       const duration = this.useChapterTrack ? this.currentChapterDuration : this.duration | ||||
| 
 | ||||
|       var ptWidth = Math.round((time / duration) * this.trackWidth) | ||||
|       const ptWidth = Math.round((time / duration) * this.trackWidth) | ||||
|       if (this.playedTrackWidth === ptWidth) { | ||||
|         return | ||||
|       } | ||||
| @ -133,7 +138,7 @@ export default { | ||||
|     }, | ||||
|     setChapterTicks() { | ||||
|       this.chapterTicks = this.chapters.map((chap) => { | ||||
|         var perc = chap.start / this.duration | ||||
|         const perc = chap.start / this.duration | ||||
|         return { | ||||
|           title: chap.title, | ||||
|           left: perc * this.trackWidth | ||||
| @ -141,7 +146,7 @@ export default { | ||||
|       }) | ||||
|     }, | ||||
|     mousemoveTrack(e) { | ||||
|       var offsetX = e.offsetX | ||||
|       const offsetX = e.offsetX | ||||
| 
 | ||||
|       const baseTime = this.useChapterTrack ? this.currentChapterStart : 0 | ||||
|       const duration = this.useChapterTrack ? this.currentChapterDuration : this.duration | ||||
| @ -167,7 +172,7 @@ export default { | ||||
|         this.$refs.hoverTimestampArrow.style.left = posLeft + 'px' | ||||
|       } | ||||
|       if (this.$refs.hoverTimestampText) { | ||||
|         var hoverText = this.$secondsToTimestamp(progressTime) | ||||
|         var hoverText = this.$secondsToTimestamp(progressTime / this._playbackRate) | ||||
| 
 | ||||
|         var chapter = this.chapters.find((chapter) => chapter.start <= totalTime && totalTime < chapter.end) | ||||
|         if (chapter && chapter.title) { | ||||
|  | ||||
| @ -46,7 +46,7 @@ | ||||
|       <player-playback-controls :loading="loading" :seek-loading="seekLoading" :playback-rate.sync="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" :current-chapter="currentChapter" @seek="seek" /> | ||||
|     <player-track-bar ref="trackbar" :loading="loading" :chapters="chapters" :duration="duration" :current-chapter="currentChapter" :playback-rate="playbackRate" @seek="seek" /> | ||||
| 
 | ||||
|     <div class="flex"> | ||||
|       <p ref="currentTimestamp" class="font-mono text-xxs sm:text-sm text-gray-100 pointer-events-auto">00:00:00</p> | ||||
| @ -59,7 +59,7 @@ | ||||
|       <p class="font-mono text-xxs sm:text-sm text-gray-100 pointer-events-auto">{{ timeRemainingPretty }}</p> | ||||
|     </div> | ||||
| 
 | ||||
|     <modals-chapters-modal v-model="showChaptersModal" :current-chapter="currentChapter" :chapters="chapters" @select="selectChapter" /> | ||||
|     <modals-chapters-modal v-model="showChaptersModal" :current-chapter="currentChapter" :playback-rate="playbackRate" :chapters="chapters" @select="selectChapter" /> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| @ -92,6 +92,11 @@ export default { | ||||
|       useChapterTrack: false | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     playbackRate() { | ||||
|       this.updateTimestamp() | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     sleepTimerRemainingString() { | ||||
|       var rounded = Math.round(this.sleepTimerRemaining) | ||||
| @ -289,14 +294,13 @@ export default { | ||||
|       if (this.$refs.trackbar) this.$refs.trackbar.setPercentageReady(percentageReady) | ||||
|     }, | ||||
|     updateTimestamp() { | ||||
|       var ts = this.$refs.currentTimestamp | ||||
|       const ts = this.$refs.currentTimestamp | ||||
|       if (!ts) { | ||||
|         console.error('No timestamp el') | ||||
|         return | ||||
|       } | ||||
|       const time = this.useChapterTrack ? Math.max(0, this.currentTime - this.currentChapterStart) : this.currentTime | ||||
|       var currTimeClean = this.$secondsToTimestamp(time) | ||||
|       ts.innerText = currTimeClean | ||||
|       ts.innerText = this.$secondsToTimestamp(time / this.playbackRate) | ||||
|     }, | ||||
|     setBufferTime(bufferTime) { | ||||
|       if (this.$refs.trackbar) this.$refs.trackbar.setBufferTime(bufferTime) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user