zombiebox-platform-pc
Version:
ZombieBox platform for desktop browsers.
170 lines (142 loc) • 2.8 kB
JavaScript
/*
* This file is part of the ZombieBox package.
*
* Copyright © 2015-2021, Interfaced
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import HTML5Video from 'zb/device/common/HTML5-video';
import {State} from 'zb/device/interfaces/i-video';
import Rect from 'zb/geometry/rect';
/**
*/
export default class Html5HlsVideo extends HTML5Video {
/**
* @param {Rect} rect
*/
constructor(rect) {
super(rect);
/**
* @type {?Hls}
* @protected
*/
this._hls = null;
/**
* @type {Array<string>}
* @protected
*/
this._hlsEvents = [];
this._onHlsEventBound = this._onHlsEvent.bind(this);
}
/**
* @override
*/
play(url, startFrom) {
if (!url.endsWith('.m3u8')) {
return super.play(url, startFrom);
}
this._startTime = startFrom || NaN;
this._initVideoObject(url);
this._setState(State.LOADING);
this._hls.loadSource(url);
}
/**
* @override
*/
getUrl() {
if (this._hls) {
return this._hls.url;
}
return super.getUrl();
}
/**
* @override
*/
destroy() {
if (this._hls) {
this._hls.destroy();
this._hls = null;
}
super.destroy();
}
/**
* @override
*/
_initVideoObject(url) {
if (!url.endsWith('.m3u8')) {
return super._initVideoObject(url);
}
this._removeVideoObject();
this._video = this._createVideoObject();
this._hls = new Hls();
this._hls.attachMedia(this._video);
this._container.appendChild(this._video);
this._viewport.setVideoObject(this._video);
this._initEvents();
}
/**
* @override
*/
_removeVideoObject() {
super._removeVideoObject();
if (this._hls) {
this._hls.destroy();
this._hls = null;
}
}
/**
* @override
*/
_initEvents() {
if (this._hls) {
this._hlsEvents = [
Hls.Events.MANIFEST_PARSED,
Hls.Events.ERROR
];
this._hlsEvents.forEach((eventName) => this._hls.on(eventName, this._onHlsEventBound));
}
super._initEvents();
}
/**
* @override
*/
_destroyEvents() {
if (this._hls) {
this._hlsEvents.forEach((eventName) => this._hls.off(eventName, this._onHlsEventBound));
this._hlsEvents = [];
}
super._destroyEvents();
}
/**
* @param {string} event
* @param {HlsEventData} data
* @protected
*/
_onHlsEvent(event, data) {
switch (event) {
case Hls.Events.MANIFEST_PARSED:
this._video.play();
break;
case Hls.Events.ERROR:
this._onHlsError(data);
break;
}
}
/**
* @param {HlsEventData} errorObject
* @protected
*/
_onHlsError(errorObject) {
if (!errorObject.fatal) {
return;
}
const message = [
'HLS error:',
errorObject.type,
errorObject.details,
errorObject.reason
].filter(Boolean).join(' ');
this._fireError(message);
}
}