gilbarbara / react-spotify-web-playback

A simple player for Spotify's web playback

Home Page:https://react-spotify-web-playback.gilbarbara.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Properly check end of songs

zluo01 opened this issue · comments

Hi,
I try to modify the code to allow explicit controls for the player (i.e. random shuffles on songs). I currently use progressMs, track durationMs and position within updateSeekBar() to determine when is the end of the song. However, I notice sometimes song ended with position less than 100 or duration - progress > 3000ms.l I wonder if there is anyway to better determine the end of the song?

Also, in some cases (i.e.) when mac's screen off and the player is running in the background, the player progressMs will not update anymore when log back in the system. I wonder what can be the cause.

Thank you.

hey @zluo01

Modify which code?
Anyway, this component is just a wrapper on top of Spotify's Web Playback SDK. You can try their forum for this problem.

About the screen saver, the callback is triggered or not?

I modified the function updateSeekBar() like following

 private updateSeekBar = async () => {
    if (!this.isActive) {
      return;
    }

    const { position, progressMs, track, finish } = this.state;
    const { onDuration, onProgress, onEnded } = this.props;
    if (finish == 1) {
      onEnded();
    }

    // To seconds
    onDuration(track.durationMs / 1000);
    // convert to decimal format
    onProgress(position / 100);

    try {
      /* istanbul ignore else */
      if (this.isExternalPlayer) {
        let position = progressMs / track.durationMs;
        position = Number(
          ((Number.isFinite(position) ? position : 0) * 100).toFixed(1)
        );

        const p = progressMs + this.seekUpdateInterval;
        const inRange =
          withinRange(p, track.durationMs, 1000) ||
          withinRange(position, 100, 0.02);
        this.updateState({
          position,
          progressMs: p,
          finish: inRange ? finish + 1 : 0,
        });
      } else if (this.player) {
        const state = (await this.player.getCurrentState()) as WebPlaybackState;

        /* istanbul ignore else */
        if (state) {
          const progress = state.position;
          const position = Number(
            (
              (progress / state.track_window.current_track.duration_ms) *
              100
            ).toFixed(1)
          );

          const p = progressMs + this.seekUpdateInterval;
          const inRange =
            withinRange(p, track.durationMs, 1000) ||
            withinRange(position, 100, 0.02);
          this.updateState({
            position,
            progressMs: p,
            finish: inRange ? finish + 1 : 0,
          });
        }
      }
    } catch (error) {
      // eslint-disable-next-line no-console
      console.error(error);
    }
  };

By simply adding some callback function to get the update data. When exist the screen saver, there is no update from this function. I am not sure which part of the code handling this issues.

Thank you.

I couldn't replicate the behavior you've mentioned, after waking up from the screen saver the callback was still firing.

If you have some new evidence, feel free to re-open this