Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

fix: fix loading new src #26

Merged
merged 1 commit into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,38 @@
<html lang="en" dir="ltr">
<head>
<title>HLS Video Element</title>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css" />
<style>
hls-video {
display: block;
width: 100%;
aspect-ratio: 16 / 9;
background: #000;
}
</style>

<script type="module" src="./dist/hls-video-element.js"></script>
</head>
<body>

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

<button id="loadbtn">Load new clip</button>
<script type="module">
loadbtn.onclick = () => {
video1.src = 'https://stream.mux.com/1EFcsL5JET00t00mBv01t00xt00T4QeNQtsXx2cKY6DLd7RM.m3u8';
};
</script>

<h2>Live</h2>
<hls-video
Expand Down
74 changes: 27 additions & 47 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,52 @@
// Web Components: Extending Native Elements, A working example

import { CustomVideoElement } from 'custom-media-element';
import Hls from 'hls.js';

class HLSVideoElement extends CustomVideoElement {
constructor() {
super();
}

get src() {
// Use the attribute value as the source of truth.
// No need to store it in two places.
// This avoids needing a to read the attribute initially and update the src.
return this.getAttribute('src');
attributeChangedCallback(attrName, oldValue, newValue) {
if (attrName !== 'src') {
super.attributeChangedCallback(attrName, oldValue, newValue);
}

if (attrName === 'src' && oldValue != newValue) {
this.load();
}
}

set src(val) {
// If being set by attributeChangedCallback,
// dont' cause an infinite loop
if (val !== this.src) {
this.setAttribute('src', val);
#destroy() {
if (this.api) {
this.api.detachMedia();
this.api.destroy();
this.api = null;
}
}

load() {
this.#destroy();

if (!this.src) {
return;
}

if (Hls.isSupported()) {
var hls = new Hls({
// Kind of like preload metadata, but causes spinner.
// autoStartLoad: false,

// Mimic the media element with an Infinity duration
// for live streams
this.api = new Hls({
// Mimic the media element with an Infinity duration for live streams.
liveDurationInfinity: true
});

hls.loadSource(this.src);
hls.attachMedia(this.nativeEl);
this.api.loadSource(this.src);
this.api.attachMedia(this.nativeEl);

} else if (this.nativeEl.canPlayType('application/vnd.apple.mpegurl')) {

this.nativeEl.src = this.src;
}
}

// play() {
// if (this.readyState === 0 && this.networkState < 2) {
// this.load();
// this.hls.on(Hls.Events.MANIFEST_PARSED,function() {
// video.play();
//
// return this.nativeEl.play();
// }
// }

connectedCallback() {
this.load();

// Not preloading might require faking the play() promise
// so that you can call play(), call load() within that
// But wait until MANIFEST_PARSED to actually call play()
// on the nativeEl.
// if (this.preload === 'auto') {
// this.load();
// }
}
}

if (!window.customElements.get('hls-video')) {
window.customElements.define('hls-video', HLSVideoElement);
window.HLSVideoElement = HLSVideoElement;
if (globalThis.customElements && !globalThis.customElements.get('hls-video')) {
globalThis.customElements.define('hls-video', HLSVideoElement);
}

export default HLSVideoElement;