@larva.io/webcomponents
Version:
Fentrica SmartUnits WebComponents package
687 lines (686 loc) • 26.3 kB
JavaScript
/*!
* (C) Fentrica http://fentrica.com - Seee LICENSE.md
*/
import { Host, h } from "@stencil/core";
import has from "lodash-es/has";
import { createColorClasses } from "../../utils/theme";
import Swiper from "swiper";
import { Pagination, Manipulation } from "swiper/modules";
import { createNotify } from "../internal/notify/notify-controller";
import { createVideoModal } from "../internal/video-modal/video-modal-controller";
import { Camera, DEFAULT_UPLINK } from "./camera";
export class LarRTSPH264MJPEG {
constructor() {
/**
* Hide camera names top of streams
*/
this.hideCameraNames = false;
/**
* Hide node titles
*/
this.hideTitles = false;
/**
* Is logging for this component enabled (lar-log subcomponent loaded)
*/
this.log = false;
/**
* Use upstream proxy for cameras
*/
this.useUplinkProxy = true;
/**
* Node size
*/
this.nodeSize = 'default';
/////// LarvaNode base properties and events - end
this.loading = true;
this.showPager = false;
this.cameras = [];
}
normalizeSwiperOptions() {
const swiperOptions = {
modules: [Pagination, Manipulation],
effect: 'slide',
direction: 'horizontal',
initialSlide: 0,
loop: false,
parallax: false,
slidesPerView: 1,
spaceBetween: 5,
speed: 300,
touchEventsTarget: 'container',
autoplay: false,
pagination: {
el: this.paginationEl,
type: 'bullets',
bulletElement: 'span',
dynamicBullets: false,
clickable: true,
hideOnClick: false,
},
};
return swiperOptions;
}
componentWillLoad() {
this.close(); // dynamic update
this.videoElementLoading = this.videoElementLoading.bind(this);
if (!this.server && !this.useUplinkProxy) { // we dont have to use uplink proxy and we dont have device url defined; generate from current host
this.server = Camera.getLocalVideoServer();
}
else if (!this.server) { // we do have to use uplink, but no server defined, use default
this.server = DEFAULT_UPLINK;
}
}
componentDidLoad() {
const el = this.el.shadowRoot || this.el;
const swiperel = el.querySelector('.swiper');
const swiperOptions = this.normalizeSwiperOptions();
this.swiper = new Swiper(swiperel, swiperOptions);
// start stream if slide shown
this.swiper.on('slideChange', () => this.startActiveSlideStream());
this.output.emit(); // read camera list
}
disconnectedCallback() {
try {
this.close();
}
catch (err) {
console.warn(err);
}
}
/**
* Larva error input
*/
async error(data, timeout = 5000) {
let msg;
if (typeof data === 'string') {
msg = data;
}
else if (data && data.message && typeof data.message === 'string') {
msg = data.message;
}
else {
msg = 'error_messages.UNKNOWN_ERROR';
}
const translate = h("lar-translate", { t: msg });
const notify = await createNotify({ message: translate, color: 'danger', autoHide: timeout });
await notify.present();
this.loading = false;
}
/**
* Input Larva event message (see above)
*/
async input(data) {
var _a;
const el = this.el.shadowRoot || this.el;
if (has(data, 'cameras')) {
this.closeCameras();
const cameras = Array.isArray(data.cameras) ? data.cameras : [];
this.cameras = cameras.map(camera => new Camera(camera, this.server));
this.showPager = this.cameras.length > 1;
this.updateSwiper();
}
else if (has(data, 'upstream')) {
// asked upstream ready message
// start camerastream via uplink proxy
await ((_a = this.cameras.find(cam => cam.wsurl === data.upstream)) === null || _a === void 0 ? void 0 : _a.open().catch(err => this.error(err)));
}
}
close() {
var _a, _b, _c, _d;
this.closeCameras();
(_a = this.swiper) === null || _a === void 0 ? void 0 : _a.off('click');
(_b = this.swiper) === null || _b === void 0 ? void 0 : _b.off('slideChange');
(_c = this.swiper) === null || _c === void 0 ? void 0 : _c.removeAllSlides();
(_d = this.swiper) === null || _d === void 0 ? void 0 : _d.destroy();
}
closeCameras() {
this.cameras.forEach(camera => camera.close()); // close all cameras
this.cameras = [];
}
async openActiveSlideCameraModal() {
var _a, _b, _c;
try {
if (!((_a = this.swiper) === null || _a === void 0 ? void 0 : _a.activeIndex) === undefined) {
throw new Error('Swiper not found');
}
const slide = (_b = this.swiper) === null || _b === void 0 ? void 0 : _b.slides[(_c = this.swiper) === null || _c === void 0 ? void 0 : _c.activeIndex];
const element = slide === null || slide === void 0 ? void 0 : slide.querySelector('canvas,video');
const cameraId = element === null || element === void 0 ? void 0 : element.getAttribute(Camera.elementCameraIdAttribute);
if (!cameraId) {
throw new Error('Camera ID not found');
}
const camera = this.cameras.find(cam => cam.id === cameraId);
if (camera && !camera.loading) {
camera.volume();
const modal = await createVideoModal({
color: this.colorModal || this.color,
mainTitle: camera.options.name,
onLarmodalwillpresent: () => { this.willPresent.emit(); },
onLarmodaldidpresent: () => { this.didPresent.emit(); },
onLarmodalwilldismiss: () => {
this.willDismiss.emit();
camera.mute();
slide.appendChild(camera.$el);
},
onLarmodaldiddismiss: () => { this.didDismiss.emit(); },
});
modal.present(camera.$el);
}
else {
throw new Error('Camera not found');
}
}
catch (err) {
console.warn(err);
}
}
videoElementLoading(event) {
var _a;
this.loading = event.detail;
// tslint:disable-next-line: no-unbound-method
(_a = this.loadingListenerElement) === null || _a === void 0 ? void 0 : _a.removeEventListener('larvideoloading', this.videoElementLoading);
this.loadingListenerElement = undefined;
}
startActiveSlideStream() {
var _a, _b, _c, _d, _e;
try {
// tslint:disable-next-line: no-unbound-method
(_a = this.loadingListenerElement) === null || _a === void 0 ? void 0 : _a.removeEventListener('larvideoloading', this.videoElementLoading);
this.loadingListenerElement = undefined;
if (!((_b = this.swiper) === null || _b === void 0 ? void 0 : _b.activeIndex) === undefined) {
throw new Error('Swiper not found');
}
const slide = (_c = this.swiper) === null || _c === void 0 ? void 0 : _c.slides[(_d = this.swiper) === null || _d === void 0 ? void 0 : _d.activeIndex];
const element = slide === null || slide === void 0 ? void 0 : slide.querySelector('canvas,video');
const cameraId = element === null || element === void 0 ? void 0 : element.getAttribute(Camera.elementCameraIdAttribute);
if (!cameraId) {
throw new Error('Camera ID not found');
}
const camera = this.cameras.find(cam => cam.id === cameraId);
this.loading = camera.loading;
if (this.loading) {
this.loadingListenerElement = camera.$el;
// tslint:disable-next-line: no-unbound-method
(_e = this.loadingListenerElement) === null || _e === void 0 ? void 0 : _e.addEventListener('larvideoloading', this.videoElementLoading);
}
if (camera && !camera.opened) {
if (this.useUplinkProxy === true) {
// we need to use uplinx proxy, ask for upstream
this.output.emit({ upstream: camera.wsurl });
}
else if (camera) {
// start streamming right away
camera.open().catch(err => this.error(err));
}
else {
throw new Error('Camera not found from list');
}
}
}
catch (err) {
console.warn(err);
}
}
updateSwiper() {
var _a, _b, _c, _d, _e;
const slides = this.cameras.map(camera => {
const container = document.createElement('div');
const title = document.createElement('div');
container.className = 'swiper-slide';
title.className = 'swiper-slide-title';
title.innerHTML = camera.options.name;
container.appendChild(camera.$el);
container.appendChild(title);
return container;
});
(_a = this.swiper) === null || _a === void 0 ? void 0 : _a.removeAllSlides();
if (slides.length > 0) {
(_b = this.swiper) === null || _b === void 0 ? void 0 : _b.appendSlide(slides);
this.startActiveSlideStream();
}
(_c = this.swiper) === null || _c === void 0 ? void 0 : _c.update();
(_e = (_d = this.swiper) === null || _d === void 0 ? void 0 : _d.pagination) === null || _e === void 0 ? void 0 : _e.update();
}
render() {
const iconSmall = this.loading ? h("lar-icon", { color: this.colorIconSmall || '', icon: "loading" }) : undefined;
return (h(Host, { key: 'bb864fb81d94e7a92d44159d7b6a334982ac8adc', class: createColorClasses(this.color) }, this.nodeSize === 'small' && h("h3", { key: 'e7822cba3b328cc5bd4f76a43b2c396e6d8ff037' }, "Camera small node not available"), this.nodeSize !== 'small' && h("div", { key: '29e0744ba5ee8fc9d7f6b65356438f2e3b9e89bb', class: "lar-node-box", onClick: () => this.openActiveSlideCameraModal() }, h("div", { key: 'f30d5883c1444d015441b3b4e4b3e6c588f7cad1', class: "swiper" }, h("div", { key: 'e863204ec51b748675d5fab315728d336027eac7', class: "swiper-wrapper" }), h("div", { key: '0822f0e16e34a27d08aa7c16bfbe4d55c8e4c580', class: {
'swiper-pagination': true,
'swiper-pagination-hidden': !this.showPager
}, ref: el => this.paginationEl = el })), iconSmall && h("div", { key: '740ffd54190c941c8343ceafdda8560091b8e264', class: "lar-icon-small" }, iconSmall))));
}
static get is() { return "lar-rtsp-h264-mjpeg"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"$": ["rtsp-h264-mjpeg.scss"]
};
}
static get styleUrls() {
return {
"$": ["rtsp-h264-mjpeg.css"]
};
}
static get properties() {
return {
"color": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Color",
"resolved": "string",
"references": {
"Color": {
"location": "import",
"path": "../../interface",
"id": "src/interface.d.ts::Color"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The color to use from your application's color palette.\nDetrouble options are: `\"primary\"`, `\"secondary\"`, `\"tertiary\"`, `\"success\"`, `\"warning\"`, `\"danger\"`, `\"light\"`, `\"medium\"`, and `\"dark\"`."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "color"
},
"colorModal": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Color",
"resolved": "string",
"references": {
"Color": {
"location": "import",
"path": "../../interface",
"id": "src/interface.d.ts::Color"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The color to use from your application's color palette for Components modal window."
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "color-modal"
},
"colorIconSmall": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Color",
"resolved": "string",
"references": {
"Color": {
"location": "import",
"path": "../../interface",
"id": "src/interface.d.ts::Color"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The color to use from your application's color palette for small icon"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "color-icon-small"
},
"hideCameraNames": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Hide camera names top of streams"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "hide-camera-names",
"defaultValue": "false"
},
"hideTitles": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Hide node titles"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "hide-titles",
"defaultValue": "false"
},
"supTitle": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Component superscript title"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "sup-title"
},
"subTitle": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Component subtitle"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "sub-title"
},
"log": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Is logging for this component enabled (lar-log subcomponent loaded)"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "log",
"defaultValue": "false"
},
"useUplinkProxy": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Use upstream proxy for cameras"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "use-uplink-proxy",
"defaultValue": "true"
},
"server": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": true,
"optional": false,
"docs": {
"tags": [],
"text": "server for cameras"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "server"
},
"mainTitle": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": true,
"optional": false,
"docs": {
"tags": [],
"text": "Component main title"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "main-title"
},
"nodeSize": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Size",
"resolved": "\"default\" | \"small\"",
"references": {
"Size": {
"location": "import",
"path": "../../interface",
"id": "src/interface.d.ts::Size"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Node size"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "node-size",
"defaultValue": "'default'"
}
};
}
static get states() {
return {
"loading": {},
"showPager": {}
};
}
static get events() {
return [{
"method": "output",
"name": "output",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [{
"name": "see",
"text": "{@link ../readme.md} chapter \"Components input and output\" for further information."
}],
"text": ""
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "request",
"name": "request",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [{
"name": "see",
"text": "{@link ../readme.md} chapter \"Sub-Components requests and responses\" for further information."
}],
"text": ""
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "willPresent",
"name": "larnodewillpresent",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted before the modal has presented."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "didPresent",
"name": "larnodedidpresent",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted after the modal has presented."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "willDismiss",
"name": "larnodewilldismiss",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted before the modal has dismissed."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "didDismiss",
"name": "larnodediddismiss",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Emitted after the modal has dismissed."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}];
}
static get methods() {
return {
"error": {
"complexType": {
"signature": "(data: any, timeout?: number) => Promise<void>",
"parameters": [{
"name": "data",
"type": "any",
"docs": ""
}, {
"name": "timeout",
"type": "number",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Larva error input",
"tags": []
}
},
"input": {
"complexType": {
"signature": "(data: DataIn) => Promise<void>",
"parameters": [{
"name": "data",
"type": "DataIn",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"DataIn": {
"location": "import",
"path": "./rtsp-h264-mjpeg-interface",
"id": "src/components/rtsp-h264-mjpeg/rtsp-h264-mjpeg-interface.tsx::DataIn"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Input Larva event message (see above)",
"tags": []
}
}
};
}
static get elementRef() { return "el"; }
}
//# sourceMappingURL=rtsp-h264-mjpeg.js.map