From c901fc21f7d493d08655ff8c75b4bc95572af433 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 24 Jan 2024 09:15:34 +0100 Subject: [PATCH] Feat: support seeking with no audio loaded (#3512) --- src/player.ts | 8 +++++++- src/renderer.ts | 2 +- src/wavesurfer.ts | 23 +++++++++++++++++------ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/player.ts b/src/player.ts index f9f1228d9..08c12e3f2 100644 --- a/src/player.ts +++ b/src/player.ts @@ -91,7 +91,8 @@ class Player extends EventEmitter { } /** Start playing the audio */ - public play(): Promise { + public async play(): Promise { + if (!this.media.src) return return this.media.play() } @@ -145,6 +146,11 @@ class Player extends EventEmitter { return this.media.playbackRate } + /** Check if the audio is seeking */ + public isSeeking(): boolean { + return this.media.seeking + } + /** Set the playback speed, pass an optional false to NOT preserve the pitch */ public setPlaybackRate(rate: number, preservePitch?: boolean) { // preservePitch is true by default in most browsers diff --git a/src/renderer.ts b/src/renderer.ts index 20909e02b..655f1c8a0 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -684,7 +684,7 @@ class Renderer extends EventEmitter { this.canvasWrapper.style.clipPath = `polygon(${percents}% 0, 100% 0, 100% 100%, ${percents}% 100%)` this.progressWrapper.style.width = `${percents}%` this.cursor.style.left = `${percents}%` - this.cursor.style.marginLeft = Math.round(percents) === 100 ? `-${this.options.cursorWidth}px` : '' + this.cursor.style.transform = `translateX(-${Math.round(percents) === 100 ? this.options.cursorWidth : 0}px)` if (this.isScrollable && this.options.autoScroll) { this.scrollIntoView(progress, isPlaying) diff --git a/src/wavesurfer.ts b/src/wavesurfer.ts index b7d19ae6c..784aad722 100644 --- a/src/wavesurfer.ts +++ b/src/wavesurfer.ts @@ -186,14 +186,20 @@ class WaveSurfer extends Player { }) } + private updateProgress(currentTime = this.getCurrentTime()): number { + this.renderer.renderProgress(currentTime / this.getDuration(), this.isPlaying()) + return currentTime + } + private initTimerEvents() { // The timer fires every 16ms for a smooth progress animation this.subscriptions.push( this.timer.on('tick', () => { - const currentTime = this.getCurrentTime() - this.renderer.renderProgress(currentTime / this.getDuration(), true) - this.emit('timeupdate', currentTime) - this.emit('audioprocess', currentTime) + if (!this.isSeeking()) { + const currentTime = this.updateProgress() + this.emit('timeupdate', currentTime) + this.emit('audioprocess', currentTime) + } }), ) } @@ -206,8 +212,7 @@ class WaveSurfer extends Player { this.mediaSubscriptions.push( this.onMediaEvent('timeupdate', () => { - const currentTime = this.getCurrentTime() - this.renderer.renderProgress(currentTime / this.getDuration(), this.isPlaying()) + const currentTime = this.updateProgress() this.emit('timeupdate', currentTime) }), @@ -454,6 +459,12 @@ class WaveSurfer extends Player { this.options.interact = isInteractive } + /** Jumpt to a specific time in the audio (in seconds) */ + public setTime(time: number) { + super.setTime(time) + this.updateProgress(time) + } + /** Seek to a percentage of audio as [0..1] (0 = beginning, 1 = end) */ public seekTo(progress: number) { const time = this.getDuration() * progress