videojs / http-streaming

HLS, DASH, and future HTTP streaming protocols library for video.js
https://videojs-http-streaming.netlify.app/
Other
2.45k stars 419 forks source link

How to actually reload/replace the video source (hls playlist) when the link expires? #1417

Open raivil opened 11 months ago

raivil commented 11 months ago

Description

Videojs is configured to serve m3u8 playlists that have expiration time configured and need a token (query param) to work.

Ex: https://example.com/index.m3u8?token=abc123ef789

During video playback, the url might expire and I'd like to refresh it, so the user can keep watching.

After an extensive research, I've found about reloadSourceOnError.

From my experiments, if the video url is invalid before the player starts downloading the playlist and chunks, the code will trigger errors and reloadSourceOnError will be called. Example error:

VIDEOJS: ERROR: (CODE:4 MEDIA_ERR_SRC_NOT_SUPPORTED) The media could not be loaded, either because the server or network failed or because the format is not supported. 

If the url expires while the user is watching and the player tries to get new chunks, the reload source doesn't seem to work. The event triggered are vhs-rendition-excluded and vhs-rendition-change-exclude. The errors are:

video.es.js:218 VIDEOJS: WARN: Problem encountered with playlist 3-1280x720/video.m3u8. HLS request errored at URL: https://the-video-url.net/token=abc&expires=1692052679/video1.ts Switching to playlist 2-842x480/video.m3u8.
VIDEOJS: WARN: Problem encountered with playlist 2-842x480/video.m3u8. HLS playlist request error at URL: 842x480/video.m3u8. Switching to playlist 1-640x360/video.m3u8.
VIDEOJS: WARN: Problem encountered with playlist 1-640x360/video.m3u8. HLS playlist request error at URL: 640x360/video.m3u8. Switching to playlist 0-352x240/video.m3u8.
VIDEOJS: WARN: Removing other playlists from the exclusion list because the last rendition is about to be excluded.
VIDEOJS: WARN: Problem encountered with playlist 0-352x240/video.m3u8. HLS playlist request error at URL: 352x240/video.m3u8. Switching to playlist 3-1280x720/video.m3u8.

What is a proper way to refresh the video source and keep the video playing and maintaining a good user experience?

Sources

this.player = videojs(this.videoPlayerTarget, {
      controls: true,
      fluid: true,
      autoplay: false,
      retryOnError: true,
      playbackRates: [0.5, 1, 1.5, 2],
      controlBar: {
        pictureInPictureToggle: false,
      },
      plugins: {
        seekButtons: {
          forward: 30,
          back: 30,
        },
      },
    });

    this.player.reloadSourceOnError({
      getSource(reload) {
        const response = post(this.streamUrlValue, {
          responseKind: "json",
        });
        if (response.ok) {
          const data = response.json;
          reload(data.streams);
        }
      },
      errorInterval: 30,
    });

// this also doesn't work  well.
this.player.on("error", () => {
      const error = this.player.error();
      if (error.code === 2) {
        const response = post(this.streamUrlValue, {
          responseKind: "json",
        });
        if (response.ok) {
          const data = response.json;
          this.player.src(data.streams);
        }
      }
    });

Steps to reproduce

Explain in detail the exact steps necessary to reproduce the issue.

Results

Expected

Expeted to be able to get a new valid url and update the video player so the user experience is still good.

Error output

see issue description

Additional Information

Please include any additional information necessary here. Including the following:

videojs-http-streaming version

what version of videojs-http-streaming does this occur with?

├─ video.js@8.5.1
│  ├─ @videojs/http-streaming@3.3.1
│  ├─ @videojs/vhs-utils@^4.0.0
│  ├─ @videojs/xhr@2.6.0
│  ├─ videojs-contrib-quality-levels@4.0.0
│  ├─ videojs-font@4.1.0
│  └─ videojs-vtt.js@0.15.5

videojs version

what version of videojs does this occur with?

├─ video.js@8.5.1
│  ├─ @videojs/http-streaming@3.3.1
│  ├─ @videojs/vhs-utils@^4.0.0
│  ├─ @videojs/xhr@2.6.0
│  ├─ videojs-contrib-quality-levels@4.0.0
│  ├─ videojs-font@4.1.0
│  └─ videojs-vtt.js@0.15.5

Browsers

what browsers are affected? please include browser and version for each

Platforms

what platforms are affected? please include operating system and version or device and version for each *mac

Other Plugins

are any other videojs plugins being used on the page? If so, please list them with version below.

Other JavaScript

are you using any other javascript libraries or frameworks on the page? if so please list them below. *

video-archivist-bot commented 11 months ago

Hey! We've detected some video files in a comment on this issue. If you'd like to permanently archive these videos and tie them to this project, a maintainer of the project can reply to this issue with the following commands:

welcome[bot] commented 11 months ago

👋 Thanks for opening your first issue here! 👋

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

nathantamblyn commented 7 months ago

I'm not sure if this would be the correct way but I'm doing something similar using

player.tech().vhs.playlists.master.playlists

With this I update the uris/resolvedUri so on the next manifest get it will make a request with the new updated params