@larva.io/webcomponents
Version:
Fentrica SmartUnits WebComponents package
109 lines (108 loc) • 4.52 kB
JavaScript
/*!
* (C) Fentrica http://fentrica.com - Seee LICENSE.md
*/
import { Html5VideoPipeline, Html5CanvasPipeline } from "media-stream-library";
import { v4 } from "uuid";
export const DEFAULT_UPLINK = 'wss://video-broker.larva.io/';
export class Camera {
constructor(opts, server) {
this.isLoading = true;
this.isOpened = false;
this.options = opts;
this.id = v4();
this.isH264 = !!window.MediaSource && !!opts.h264;
this.$el = this.isH264 ? document.createElement('video') : document.createElement('canvas');
this.$el.setAttribute(Camera.elementCameraIdAttribute, this.id);
if (this.isH264) {
// !important, do not use poster attribute,
// it's not working on ios 15 properly
// https://developer.apple.com/forums/thread/690523
this.$el.autoplay = true;
this.$el.preload = 'none';
this.$el.playsInline = true;
this.$el.style.background = 'transparent';
this.mute();
}
// impoprtant
this.$el.style.width = '100%';
this.server = server;
const url = new URL(this.server);
url.pathname = `${url.pathname.replace(/\/$/, '')}/${this.id}`;
this.wsurl = url.href;
}
static getLocalVideoServer() {
const protocol = location.protocol === 'http:' ? 'ws://' : 'wss://';
const port = window.location.port !== '' ? (':' + window.location.port) : '';
const host = window.location.hostname;
const path = '/video-proxy';
return `${protocol}${host}${port}${path}`;
}
static get elementCameraIdAttribute() {
return 'camera-id';
}
async open() {
if (this.isOpened) {
// opened
return;
}
try {
this.isOpened = true;
const options = Object.assign(Object.assign({}, (!!this.options.username || !!this.options.password) ? { auth: { username: this.options.username, password: this.options.password } } : {}), { ws: { uri: this.wsurl, tokenUri: null, timeout: 5000 }, rtsp: { uri: this.isH264 ? this.options.h264 : this.options.mjpeg }, mediaElement: this.$el });
this.pipeline = this.isH264 ?
new Html5VideoPipeline(Object.assign(Object.assign({}, options), { mediaElement: options.mediaElement })) :
new Html5CanvasPipeline(Object.assign(Object.assign({}, options), { mediaElement: options.mediaElement }));
// cancvas element does now know about drawing events or what so ever
// so lets see if time has started running
const interval = setInterval(() => {
const currentTime = Array.isArray(this.pipeline.currentTime) ? this.pipeline.currentTime[0] : this.pipeline.currentTime;
const bitrate = Array.isArray(this.pipeline.bitrate) ? this.pipeline.bitrate[0] : this.pipeline.bitrate;
const framerate = Array.isArray(this.pipeline.framerate) ? this.pipeline.framerate[0] : this.pipeline.framerate;
if (currentTime > 0 || bitrate > 0 || framerate > 0) {
this.loading = false;
clearInterval(interval);
}
}, 500);
await this.pipeline.ready;
this.pipeline.rtsp.play();
// fixes: https://developer.apple.com/forums/thread/129377
if (this.isH264) {
this.$el.pause();
this.$el.play();
}
}
catch (err) { // supress
console.error(err);
throw new Error('Failed to connect to video server');
}
}
mute() {
if (this.isH264) {
this.$el.muted = true;
this.$el.volume = 0;
}
}
volume(volume = 1) {
if (this.isH264) {
this.$el.muted = false;
this.$el.volume = volume;
}
}
close() {
var _a, _b;
(_a = this.pipeline) === null || _a === void 0 ? void 0 : _a.close();
(_b = this.$el) === null || _b === void 0 ? void 0 : _b.remove();
}
set loading(val) {
var _a;
const event = new CustomEvent('larvideoloading', { detail: val });
(_a = this.$el) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
this.isLoading = val;
}
get loading() {
return this.isLoading;
}
get opened() {
return this.isOpened;
}
}
//# sourceMappingURL=camera.js.map