UNPKG

paella-core

Version:
380 lines (346 loc) 14.5 kB
import VideoLayout from 'paella-core/js/core/VideoLayout'; import { getCookie, setCookie } from 'paella-core/js/core/utils'; import { CanvasButtonPosition } from '../core/CanvasPlugin'; import defaultIconRotate from 'paella-core/icons/icon_rotate.svg'; import defaultIconMinimize from 'paella-core/icons/minimize-3.svg'; import defaultIconSwitchSide from 'paella-core/icons/icon_switch_side.svg'; import defaultIconMaximize from 'paella-core/icons/maximize.svg'; import defaultIconClose from 'paella-core/icons/close.svg'; import defaultIconSideBySide from 'paella-core/icons/icon_side_by_side.svg'; import PaellaCoreLayouts from './PaellaCoreLayouts'; let layout = 0; /** * in pip mode, the minimized video is de second one */ const layouts = [ // First layout: side by side { id: "side-by-side", videos: [ { content:null, rect:[ {aspectRatio:"16/9",width:560,height:315,top:218,left:712}, {aspectRatio:"16/10",width:560,height:350,top:206,left:712}, {aspectRatio:"4/3",width:560,height:420,top:173,left:712}, {aspectRatio:"5/3",width:560,height:336,top:206,left:712}, {aspectRatio:"5/4",width:560,height:448,top:160,left:712} ], visible:true, layer:1 }, { content:null, rect:[ {aspectRatio:"16/9",width:688,height:387,top:166,left:10}, {aspectRatio:"16/10",width:688,height:430,top:148,left:10}, {aspectRatio:"4/3",width:688,height:516,top:111,left:10}, {aspectRatio:"5/3",width:690,height:414,top:154,left:10}, {aspectRatio:"5/4",width:690,height:552,top:96,left:10} ], visible:true, layer:"1" } ], buttons: [] }, // Second layout: PIP left { id: "pip-left", videos:[ { content:null, rect:[ {aspectRatio:"16/9",left:0,top:0,width:1280,height:720}, {aspectRatio:"16/10",left:64,top:0,width:1152,height:720}, {aspectRatio:"5/3",left:40,top:0,width:1200,height:720}, {aspectRatio:"5/4",left:190,top:0,width:900,height:720}, {aspectRatio:"4/3",left:160,top:0,width:960,height:720} ], visible:true, layer:1 }, { content:null, rect:[ {aspectRatio:"16/9",left:50,top:470,width:350,height:197}, {aspectRatio:"16/10",left:50,top:448,width:350,height:219}, {aspectRatio:"5/3",left:50,top:457,width:350,height:210}, {aspectRatio:"5/4",left:50,top:387,width:350,height:280}, {aspectRatio:"4/3",left:50,top:404,width:350,height:262} ], visible:true, layer:2 } ], buttons: [] }, // Third layout: PIP right { id: "pip-right", videos: [ { content:null, rect:[ {aspectRatio:"16/9",left:0,top:0,width:1280,height:720}, {aspectRatio:"16/10",left:64,top:0,width:1152,height:720}, {aspectRatio:"5/3",left:40,top:0,width:1200,height:720}, {aspectRatio:"5/4",left:190,top:0,width:900,height:720}, {aspectRatio:"4/3",left:160,top:0,width:960,height:720} ], visible:true, layer:1 }, { content:null, rect:[ {aspectRatio:"16/9",left:880,top:470,width:350,height:197}, {aspectRatio:"16/10",left:880,top:448,width:350,height:219}, {aspectRatio:"5/3",left:880,top:457,width:350,height:210}, {aspectRatio:"5/4",left:880,top:387,width:350,height:280}, {aspectRatio:"4/3",left:880,top:404,width:350,height:262} ], visible:true, layer:2 } ], buttons: [] } ]; function nextLayout(validContent) { layout = (layout + 1) % layouts.length; return currentLayout(validContent); } function setLayout(validContent, index) { layout = index < layouts.length ? index : layout; return currentLayout(validContent); } function currentLayout(validContent) { let selectedLayout = JSON.parse(JSON.stringify(layouts[layout])); selectedLayout.videos[0].content = validContent[0]; selectedLayout.videos[1].content = validContent[1]; return selectedLayout; } export default class DualVideoLayout extends VideoLayout { getPluginModuleInstance() { return PaellaCoreLayouts.Get(); } get name() { return super.name || "es.upv.paella.dualVideo"; } get identifier() { return "dual-video"; } async load() { let layoutIndex = getCookie('dualVideoLayoutIndex'); if (layoutIndex !== "") { layout = Number(layoutIndex); } this.player.log.debug("Dual video layout loaded"); } getValidStreams(streamData) { // As this is a dual stream layout plugin, we make sure that the valid streams containis // two streams. This prevents a bad configuration of the plugin return super.getValidStreams(streamData) .filter(stream => stream.length === 2); } switchContent() { const v0 = this._currentContent[0]; const v1 = this._currentContent[1]; this._currentContent[0] = v1; this._currentContent[1] = v0; this.player.videoContainer.updateLayout(); } async switchMinimized() { nextLayout(this._currentContent); await this.player.videoContainer.updateLayout(); } async minimizeVideo(content) { let switchLayout = true; if (content === this._currentContent[0]) { const v0 = this._currentContent[0]; const v1 = this._currentContent[1]; this._currentContent[0] = v1; this._currentContent[1] = v0; switchLayout = false; } if (layout === 1 && switchLayout) { setLayout(this._currentContent, 2); } else { setLayout(this._currentContent, 1); } await this.player.videoContainer.updateLayout(); } async maximizeVideo(content) { let switchLayout = true; if (content === this._currentContent[1]) { const v0 = this._currentContent[0]; const v1 = this._currentContent[1]; this._currentContent[0] = v1; this._currentContent[1] = v0; switchLayout = false; } if (layout === 1 && switchLayout) { setLayout(this._currentContent, 2); } else { setLayout(this._currentContent, 1); } await this.player.videoContainer.updateLayout(); } async setSideBySide() { setLayout(this._currentContent, 0); await this.player.videoContainer.updateLayout(); } get minimizedContent() { // See layout structure if (layout === 0) { return ""; } else { return this._currentContent[1]; } } async closeVideo(content) { const singleStreamContentIds = this.player.videoContainer.validContentIds.filter(cid => cid.indexOf("-") === -1); const contentId = singleStreamContentIds.find(cid => cid != content); await this.player.videoContainer.setLayout(contentId); } getVideoCanvasButtons(layoutStructure, content, video, videoCanvas) { if (layoutStructure.id === "side-by-side") { // Buttons: swap videos and minimize return [ // Swap { icon: this.player.getCustomPluginIcon(this.name,"iconRotate") || defaultIconRotate, position: CanvasButtonPosition.LEFT, title: this.player.translate('Swap position of the videos'), ariaLabel: this.player.translate('Swap position of the videos'), name: this.name + ':iconRotate', click: async () => { await this.switchContent(); } }, // Minimize { icon: this.player.getCustomPluginIcon(this.name,"iconMaximize") || defaultIconMaximize, position: CanvasButtonPosition.LEFT, title: this.player.translate('Maximize video'), ariaLabel: this.player.translate('Maximize video'), name: this.name + ':iconMaximize', click: async () => { await this.maximizeVideo(content); } }, // Close { icon: this.player.getCustomPluginIcon(this.name,"iconClose") || defaultIconClose, position: CanvasButtonPosition.RIGHT, title: this.player.translate('Close video'), ariaLabel: this.player.translate('Close video'), name: this.name + ':iconClose', click: async () => { await this.closeVideo(content); } } ] } else { const result = []; if (content === this.minimizedContent) { result.push({ icon: this.player.getCustomPluginIcon(this.name,"iconMaximize") || defaultIconMaximize, position: CanvasButtonPosition.LEFT, title: this.player.translate('Maximize video'), ariaLabel: this.player.translate('Maximize video'), name: this.name + ':iconMaximize', click: async () => { await this.switchContent(); } }); result.push({ icon: this.player.getCustomPluginIcon(this.name,"iconSwitchSide") || defaultIconSwitchSide, position: CanvasButtonPosition.LEFT, title: this.player.translate('Place the video on the other side of the screen'), ariaLabel: this.player.translate('Place the video on the other side of the screen'), name: this.name + ':iconSwitchSide', click: async () => { await this.minimizeVideo(content); } }); result.push({ icon: this.player.getCustomPluginIcon(this.name,"iconClose") || defaultIconClose, position: CanvasButtonPosition.RIGHT, title: this.player.translate('Close video'), ariaLabel: this.player.translate('Close video'), name: this.name + ':iconClose', click: async () => { await this.closeVideo(content); } }); } else { result.push({ icon: this.player.getCustomPluginIcon(this.name,"iconMinimize") || defaultIconMinimize, position: CanvasButtonPosition.LEFT, title: this.player.translate('Minimize video'), ariaLabel: this.player.translate('Minimize video'), name: this.name + ':iconMinimize', click: async () => { await this.switchContent(); } }); result.push({ icon: this.player.getCustomPluginIcon(this.name,"iconSideBySide") || defaultIconSideBySide, position: CanvasButtonPosition.LEFT, title: this.player.translate('Put the videos side by side'), ariaLabel: this.player.translate('Put the videos side by side'), name: this.name + ':iconSideBySide', click: async () => { await this.setSideBySide(); } }); result.push({ icon: this.player.getCustomPluginIcon(this.name,"iconClose") || defaultIconClose, position: CanvasButtonPosition.RIGHT, title: this.player.translate('Close video'), ariaLabel: this.player.translate('Close video'), name: this.name + ':iconClose', click: async () => { await this.closeVideo(content); } }); } return result; } } getLayoutStructure(streamData, contentId) { if (!this._currentContent || this._currentContentId!==contentId) { const {content} = this.validContent.find(content => content.id === contentId); this._currentContent = content; this._currentContentId = contentId; const content0 = getCookie('dualVideoLayoutContent0'); const content1 = getCookie('dualVideoLayoutContent1'); if (content0 !== "" && content1 !== "" && this._currentContent.indexOf(content0) !== -1 && this._currentContent.indexOf(content1) !== -1) { this._currentContent[0] = content0; this._currentContent[1] = content1; } } const selectedLayout = currentLayout(this._currentContent); const result = { id: selectedLayout.id, player: this.player, name:{es:"Dos streams con posición dinámica"}, hidden:false, videos: selectedLayout.videos, buttons: [] }; // Save layout settings setCookie("dualVideoLayoutIndex", layout); setCookie("dualVideoLayoutContent0", this._currentContent[0]); setCookie("dualVideoLayoutContent1", this._currentContent[1]); return result; } }