muxinc / hls-video-element

A custom element (web component) for playing HTTP Live Streaming (HLS) videos.
https://hls-video-element-mux.vercel.app
MIT License
38 stars 18 forks source link

Added option for passing hls.js config #9

Open heff opened 2 years ago

heff commented 2 years ago

Addresses #3

With this change you can now set element.hlsjsConfig, and that object will be used when the source is loaded.

For example.

<hls-video
  controls
  src="https://stream.mux.com/DS00Spx1CV902MCtPj5WknGlR102V5HFkDe.m3u8"
>
  <track label="thumbnails" id="customTrack" default kind="metadata" src="https://image.mux.com/DS00Spx1CV902MCtPj5WknGlR102V5HFkDe/storyboard.vtt"></track>
</hls-video>

<script>
  customElements.whenDefined('hls-video').then(()=>{
    const hlsVideo = document.querySelector('hls-video');
    // Update the config object as desired
    hlsVideo.hlsjsConfig = {
      debug: true
    };
    hlsVideo.load();
  });
</script>
mmcc commented 2 years ago

At the risk of sounding like a dummy, are there any race conditions we need to account for here? The one that comes to mind is, does this script tag need to be before the media-chrome import? It seems incredible improbable that it would ever be an issue in practice, but it would also be a monster to debug.

heff commented 2 years ago

Not dumb, I was actually surprised this example worked. :) Technically we should document calling load() after setting the config. But can't move the script before the hls-video tag, at least not as is, because the tag wouldn't exist yet.

I can add that to the docs.

heff commented 2 years ago

@mmcc turned out to be a little more complicated than expected. Review again please?

mmcc commented 2 years ago

Hmm does this potentially have the same or similar issue?

I almost wonder if we might be better off just specifying the config before everything. i.e.:

window.HLSJS_CONFIG = { }
// import hls-video

The other option is we could expose a config setter, so it would be something like:

import HlsVideo from 'blah';
HlsVideo.hlsConfig = {}

The other option is that we update the tag to be able to declare you don't want to preload so that you could manually update the config before its use and just short-circuit the race altogether.

heff commented 2 years ago

Hmm does this potentially have the same or similar issue?

Yes from the standpoint of HLS loading without a config first, but no from that having any real consequence. I guess it'd be nice if you didn't have to call load.

window.HLSJS_CONFIG = { }

That would solve any async issue, but it doesn't feel quite right to have a window var config for a nicely packaged custom element. There might be some complication with a window config in the world of shadow roots. And the minor downside of if you wanted two different configurations on the same page.

The other option is that we update the tag to be able to declare you don't want to preload so that you could manually update the config before its use and just short-circuit the race altogether

🤔 Would it be terrible to just use preload="none"? It's kind of overloading that, but conceptually it seems to make sense.

heff commented 2 years ago

Ha, apparently I've already explored this some.

Nodalailama commented 2 years ago

Hi,

Let imagine you have an app that allow user to stream live. Now, there is livestream and old livestream, like 2 days after livestream you can re-watch them.

I will not have the same hls config for live stream (real live) and old livestream. Secondly, based on the bandwidth of the user or based on the device he use, I will define custom hls settings: if the user use a desktop/laptop, I guess he have a good internet connexion like an optical fiber ... if he use a mobile device, I guess he have 4g ... and based on that, I will fine tuned hls (I will try).

So, in my opinion, newbie opinion compared to you, I will be happy to have two mode for hls-element: one is the default state and the other is a fully configurable hls.

If no data-attribute is set then it's default, it startload directly .... etc. If I declared <hls-video data-mode="custom" ... then it expose hls to extern conf and I have to manually (by js) pass my custom config, my custom behavior.

So, my solution is to have 2 behaviors: default and custom. Custom mean attach hls to the html element (this.hls) so I can do what I want. And each hls element could have his own conf, his own beahvior, his own way to be controlled.

evoactivity commented 11 months ago

On my custom element I've added support for a defer attribute <mpegts-video defer src="..."></mpegts-video>.

I know it doesn't exist on the native <video> element but I think it communicates intent quite clearly. I can put together a PR if that sounds acceptable, you can check this repo for an example implementation.

bubbleheadinc commented 4 months ago

Just checking in on this PR. I am attempting to use signed cookies, but can't play them in the hls-video-element due the xhr not sending the cookies. Would be great to be able to set the config. Unless there is another way to set the xhr config, I think I'm stuck on this. Thanks.

luwes commented 4 months ago

@bubbleheadinc there are workarounds to change the hls.js config. see this example: https://codesandbox.io/p/devbox/hls-video-element-config-424wlf?file=%2Findex.html%3A25%2C40

if you would run into race conditions with the workaround above, there is a sure way to set the config and that is to hold off on setting the src attribute in the HTML (maybe change it to data-src) and then set it in JS, then right after having set the src you can manipulate the hls.js config because the code always waits one tick (see https://github.com/muxinc/hls-video-element/blob/master/hls-video-element.js#L42-L43) before calling hls.loadSource().