openvidu-components: Added preliminary subtitles

pull/743/head
csantosm 2022-07-05 12:03:35 +02:00
parent fc7b961010
commit 0b74590252
39 changed files with 905 additions and 353 deletions

View File

@ -20,6 +20,7 @@ var PARTICIPANTS_PANEL_BUTTON;
var ACTIVITIES_RECORDING_ACTIVITY; var ACTIVITIES_RECORDING_ACTIVITY;
var RECORDING_ERROR; var RECORDING_ERROR;
var TOOLBAR_SETTINGS_BUTTON; var TOOLBAR_SETTINGS_BUTTON;
var SUBTITLES_BUTTON;
var SESSION_NAME; var SESSION_NAME;
@ -37,6 +38,7 @@ $(document).ready(() => {
RECORDING_BUTTON = url.searchParams.get("recordingBtn") === null ? true : url.searchParams.get("recordingBtn") === 'true'; RECORDING_BUTTON = url.searchParams.get("recordingBtn") === null ? true : url.searchParams.get("recordingBtn") === 'true';
FULLSCREEN_BUTTON = url.searchParams.get("fullscreenBtn") === null ? true : url.searchParams.get("fullscreenBtn") === 'true'; FULLSCREEN_BUTTON = url.searchParams.get("fullscreenBtn") === null ? true : url.searchParams.get("fullscreenBtn") === 'true';
TOOLBAR_SETTINGS_BUTTON = url.searchParams.get("toolbarSettingsBtn") === null ? true : url.searchParams.get("toolbarSettingsBtn") === 'true'; TOOLBAR_SETTINGS_BUTTON = url.searchParams.get("toolbarSettingsBtn") === null ? true : url.searchParams.get("toolbarSettingsBtn") === 'true';
SUBTITLES_BUTTON = url.searchParams.get("toolbarSubtitlesBtn") === null ? true : url.searchParams.get("toolbarSubtitlesBtn") === 'true';
LEAVE_BUTTON = url.searchParams.get("leaveBtn") === null ? true : url.searchParams.get("leaveBtn") === 'true'; LEAVE_BUTTON = url.searchParams.get("leaveBtn") === null ? true : url.searchParams.get("leaveBtn") === 'true';
ACTIVITIES_PANEL_BUTTON = url.searchParams.get("activitiesPanelBtn") === null ? true : url.searchParams.get("activitiesPanelBtn") === 'true'; ACTIVITIES_PANEL_BUTTON = url.searchParams.get("activitiesPanelBtn") === null ? true : url.searchParams.get("activitiesPanelBtn") === 'true';
@ -147,6 +149,7 @@ async function joinSession(sessionName, participantName) {
webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON; webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON;
webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON; webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON;
webComponent.toolbarSubtitlesButton = SUBTITLES_BUTTON;
webComponent.toolbarLeaveButton = LEAVE_BUTTON; webComponent.toolbarLeaveButton = LEAVE_BUTTON;
webComponent.toolbarRecordingButton = RECORDING_BUTTON; webComponent.toolbarRecordingButton = RECORDING_BUTTON;
webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON; webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON;

View File

@ -252,6 +252,41 @@ describe('Testing API Directives', () => {
expect(element.length).equals(0); expect(element.length).equals(0);
}); });
it('should HIDE the SUBTITLES button', async () => {
let element;
await browser.get(`${url}?prejoin=false&toolbarSubtitlesBtn=false`);
element = await browser.wait(until.elementLocated(By.id('session-container')), TIMEOUT);
expect(await element.isDisplayed()).to.be.true;
// Checking if toolbar is present
element = await browser.wait(until.elementLocated(By.id('media-buttons-container')), TIMEOUT);
expect(await element.isDisplayed()).to.be.true;
// Open more options menu
element = await browser.wait(until.elementLocated(By.id('more-options-btn')), TIMEOUT);
await element.click();
await browser.sleep(500);
// Checking if subtitles button is not present
element = await browser.wait(until.elementLocated(By.className('mat-menu-content')), TIMEOUT);
expect(await element.isDisplayed()).to.be.true;
element = await browser.findElements(By.id('subtitles-btn'));
expect(element.length).equals(0);
element = await browser.findElements(By.id('toolbar-settings-btn'));
expect(element.length).equals(1);
await element[0].click();
await browser.sleep(500);
element = await browser.wait(until.elementLocated(By.className('settings-container')), TIMEOUT);
expect(await element.isDisplayed()).to.be.true;
element = await browser.findElements(By.id('subtitles-opt'));
expect(element.length).equals(0);
});
it('should HIDE the TOOLBAR SETTINGS button', async () => { it('should HIDE the TOOLBAR SETTINGS button', async () => {
let element; let element;
await browser.get(`${url}?prejoin=false&toolbarSettingsBtn=false`); await browser.get(`${url}?prejoin=false&toolbarSettingsBtn=false`);

View File

@ -30,7 +30,7 @@ export class AudioWaveComponent implements OnInit, OnDestroy {
if (this.streamManager) { if (this.streamManager) {
this.streamManager.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => { this.streamManager.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => {
if (event.reason === 'trackReplaced' && event.changedProperty === 'audioActive') { if (event.reason === 'trackReplaced' && event.changedProperty === 'audioActive') {
// FIXUP: When the audio track is replaced, the startSpeakingEvents is not fired by openvidu-browser // TODO: When the audio track is replaced, the startSpeakingEvents is not fired by openvidu-browser
this.unsubscribeSpeakingEvents(); this.unsubscribeSpeakingEvents();
this.subscribeSpeakingEvents(); this.subscribeSpeakingEvents();
} }

View File

@ -2,6 +2,12 @@
height: 100%; height: 100%;
} }
.container {
height: 100%;
}
.withSubtitles {
height: calc(100% - 75px) !important;
}
.layout { .layout {
position: relative; position: relative;
@ -16,40 +22,39 @@
height: -moz-available; height: -moz-available;
} }
/*! /*!
* Copyright (c) 2017 TokBox, Inc. * Copyright (c) 2017 TokBox, Inc.
* Released under the MIT license * Released under the MIT license
* http://opensource.org/licenses/MIT * http://opensource.org/licenses/MIT
*/ */
/**
/**
* OT Base styles * OT Base styles
*/ */
/* Root OT object, this is where our CSS reset happens */ /* Root OT object, this is where our CSS reset happens */
.OT_root, .OT_root,
.OT_root * { .OT_root * {
color: #ffffff; color: #ffffff;
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
font-size: 100%; font-size: 100%;
vertical-align: baseline; vertical-align: baseline;
} }
.OT_dialog-centering { .OT_dialog-centering {
display: table; display: table;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.OT_dialog-centering-child { .OT_dialog-centering-child {
display: table-cell; display: table-cell;
vertical-align: middle; vertical-align: middle;
} }
.OT_dialog { .OT_dialog {
position: relative; position: relative;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
@ -60,15 +65,15 @@
font-family: 'Ubuntu', sans-serif; font-family: 'Ubuntu', sans-serif;
font-size: 13px; font-size: 13px;
line-height: 1.4; line-height: 1.4;
} }
.OT_dialog * { .OT_dialog * {
font-family: inherit; font-family: inherit;
-webkit-box-sizing: inherit; -webkit-box-sizing: inherit;
box-sizing: inherit; box-sizing: inherit;
} }
.OT_closeButton { .OT_closeButton {
color: #999999; color: #999999;
cursor: pointer; cursor: pointer;
font-size: 32px; font-size: 32px;
@ -76,37 +81,37 @@
position: absolute; position: absolute;
right: 18px; right: 18px;
top: 0; top: 0;
} }
.OT_dialog-messages { .OT_dialog-messages {
text-align: center; text-align: center;
} }
.OT_dialog-messages-main { .OT_dialog-messages-main {
margin-bottom: 36px; margin-bottom: 36px;
line-height: 36px; line-height: 36px;
font-weight: 300; font-weight: 300;
font-size: 24px; font-size: 24px;
} }
.OT_dialog-messages-minor { .OT_dialog-messages-minor {
margin-bottom: 18px; margin-bottom: 18px;
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
color: #a4a4a4; color: #a4a4a4;
} }
.OT_dialog-messages-minor strong { .OT_dialog-messages-minor strong {
color: #ffffff; color: #ffffff;
} }
.OT_dialog-actions-card { .OT_dialog-actions-card {
display: inline-block; display: inline-block;
} }
.OT_dialog-button-title { .OT_dialog-button-title {
margin-bottom: 18px; margin-bottom: 18px;
line-height: 18px; line-height: 18px;
@ -114,24 +119,24 @@
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
color: #999999; color: #999999;
} }
.OT_dialog-button-title label { .OT_dialog-button-title label {
color: #999999; color: #999999;
} }
.OT_dialog-button-title a, .OT_dialog-button-title a,
.OT_dialog-button-title a:link, .OT_dialog-button-title a:link,
.OT_dialog-button-title a:active { .OT_dialog-button-title a:active {
color: #02a1de; color: #02a1de;
} }
.OT_dialog-button-title strong { .OT_dialog-button-title strong {
color: #ffffff; color: #ffffff;
font-weight: 100; font-weight: 100;
display: block; display: block;
} }
.OT_dialog-button { .OT_dialog-button {
display: inline-block; display: inline-block;
margin-bottom: 18px; margin-bottom: 18px;
@ -140,23 +145,23 @@
background-color: #1ca3dc; background-color: #1ca3dc;
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
} }
.OT_dialog-button:disabled { .OT_dialog-button:disabled {
cursor: not-allowed; cursor: not-allowed;
opacity: 0.5; opacity: 0.5;
} }
.OT_dialog-button-large { .OT_dialog-button-large {
line-height: 36px; line-height: 36px;
padding-top: 9px; padding-top: 9px;
padding-bottom: 9px; padding-bottom: 9px;
font-weight: 100; font-weight: 100;
font-size: 24px; font-size: 24px;
} }
.OT_dialog-button-small { .OT_dialog-button-small {
line-height: 18px; line-height: 18px;
padding-top: 9px; padding-top: 9px;
padding-bottom: 9px; padding-bottom: 9px;
@ -164,9 +169,9 @@
background-color: #444444; background-color: #444444;
color: #999999; color: #999999;
font-size: 16px; font-size: 16px;
} }
.OT_dialog-progress-bar { .OT_dialog-progress-bar {
display: inline-block; /* prevents margin collapse */ display: inline-block; /* prevents margin collapse */
width: 100%; width: 100%;
margin-top: 5px; margin-top: 5px;
@ -174,85 +179,85 @@
border: 1px solid #4e4e4e; border: 1px solid #4e4e4e;
height: 8px; height: 8px;
} }
.OT_dialog-progress-bar-fill { .OT_dialog-progress-bar-fill {
height: 100%; height: 100%;
background-color: #29a4da; background-color: #29a4da;
} }
.OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage { .OT_dialog-plugin-upgrading .OT_dialog-plugin-upgrade-percentage {
line-height: 54px; line-height: 54px;
font-size: 48px; font-size: 48px;
font-weight: 100; font-weight: 100;
} }
/* Helpers */ /* Helpers */
.OT_centered { .OT_centered {
position: fixed; position: fixed;
left: 50%; left: 50%;
top: 50%; top: 50%;
margin: 0; margin: 0;
} }
.OT_dialog-hidden { .OT_dialog-hidden {
display: none; display: none;
} }
.OT_dialog-button-block { .OT_dialog-button-block {
display: block; display: block;
} }
.OT_dialog-no-natural-margin { .OT_dialog-no-natural-margin {
margin-bottom: 0; margin-bottom: 0;
} }
/* Publisher and Subscriber styles */ /* Publisher and Subscriber styles */
.OT_publisher, .OT_publisher,
.OT_subscriber { .OT_subscriber {
position: relative; position: relative;
min-width: 0px; min-width: 0px;
min-height: 0px; min-height: 0px;
margin: 3px; padding: 3px;
transition-duration: 0.1s; transition-duration: 0.1s;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
} }
.OT_publisher .OT_video-element, .OT_publisher .OT_video-element,
.OT_subscriber .OT_video-element { .OT_subscriber .OT_video-element {
display: block; display: block;
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
-webkit-transform-origin: 0 0; -webkit-transform-origin: 0 0;
transform-origin: 0 0; transform-origin: 0 0;
} }
.OT_subscriber_error { .OT_subscriber_error {
background-color: #000; background-color: #000;
color: #fff; color: #fff;
text-align: center; text-align: center;
} }
.OT_subscriber_error > p { .OT_subscriber_error > p {
padding: 20px; padding: 20px;
} }
/* The publisher/subscriber name/mute background */ /* The publisher/subscriber name/mute background */
.OT_publisher .OT_bar, .OT_publisher .OT_bar,
.OT_subscriber .OT_bar, .OT_subscriber .OT_bar,
.OT_publisher .OT_name, .OT_publisher .OT_name,
.OT_subscriber .OT_name, .OT_subscriber .OT_name,
.OT_publisher .OT_archiving, .OT_publisher .OT_archiving,
.OT_subscriber .OT_archiving, .OT_subscriber .OT_archiving,
.OT_publisher .OT_archiving-status, .OT_publisher .OT_archiving-status,
.OT_subscriber .OT_archiving-status, .OT_subscriber .OT_archiving-status,
.OT_publisher .OT_archiving-light-box, .OT_publisher .OT_archiving-light-box,
.OT_subscriber .OT_archiving-light-box { .OT_subscriber .OT_archiving-light-box {
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-ms-box-sizing: border-box; -ms-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
@ -262,31 +267,31 @@
display: block; display: block;
height: 34px; height: 34px;
position: absolute; position: absolute;
} }
.OT_publisher .OT_bar, .OT_publisher .OT_bar,
.OT_subscriber .OT_bar { .OT_subscriber .OT_bar {
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
} }
.OT_publisher .OT_edge-bar-item, .OT_publisher .OT_edge-bar-item,
.OT_subscriber .OT_edge-bar-item { .OT_subscriber .OT_edge-bar-item {
z-index: 1; /* required to get audio level meter underneath */ z-index: 1; /* required to get audio level meter underneath */
} }
/* The publisher/subscriber name panel/archiving status bar */ /* The publisher/subscriber name panel/archiving status bar */
.OT_publisher .OT_name, .OT_publisher .OT_name,
.OT_subscriber .OT_name { .OT_subscriber .OT_name {
background-color: transparent; background-color: transparent;
color: #ffffff; color: #ffffff;
font-size: 15px; font-size: 15px;
line-height: 34px; line-height: 34px;
font-weight: normal; font-weight: normal;
padding: 0 4px 0 36px; padding: 0 4px 0 36px;
} }
.OT_publisher .OT_archiving-status, .OT_publisher .OT_archiving-status,
.OT_subscriber .OT_archiving-status { .OT_subscriber .OT_archiving-status {
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
top: auto; top: auto;
bottom: 0; bottom: 0;
@ -296,26 +301,26 @@
font-size: 15px; font-size: 15px;
line-height: 34px; line-height: 34px;
font-weight: normal; font-weight: normal;
} }
.OT_micro .OT_archiving-status, .OT_micro .OT_archiving-status,
.OT_micro:hover .OT_archiving-status, .OT_micro:hover .OT_archiving-status,
.OT_mini .OT_archiving-status, .OT_mini .OT_archiving-status,
.OT_mini:hover .OT_archiving-status { .OT_mini:hover .OT_archiving-status {
display: none; display: none;
} }
.OT_publisher .OT_archiving-light-box, .OT_publisher .OT_archiving-light-box,
.OT_subscriber .OT_archiving-light-box { .OT_subscriber .OT_archiving-light-box {
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
top: auto; top: auto;
bottom: 0; bottom: 0;
right: auto; right: auto;
width: 34px; width: 34px;
height: 34px; height: 34px;
} }
.OT_archiving-light { .OT_archiving-light {
width: 7px; width: 7px;
height: 7px; height: 7px;
border-radius: 30px; border-radius: 30px;
@ -325,9 +330,9 @@
background-color: #575757; background-color: #575757;
-webkit-box-shadow: 0 0 5px 1px #575757; -webkit-box-shadow: 0 0 5px 1px #575757;
box-shadow: 0 0 5px 1px #575757; box-shadow: 0 0 5px 1px #575757;
} }
.OT_archiving-light.OT_active { .OT_archiving-light.OT_active {
background-color: #970d13; background-color: #970d13;
animation: OT_pulse 1.3s ease-in; animation: OT_pulse 1.3s ease-in;
-webkit-animation: OT_pulse 1.3s ease-in; -webkit-animation: OT_pulse 1.3s ease-in;
@ -337,8 +342,8 @@
-webkit-animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite; -moz-animation-iteration-count: infinite;
-webkit-animation-iteration-count: infinite; -webkit-animation-iteration-count: infinite;
} }
@-webkit-keyframes OT_pulse { @-webkit-keyframes OT_pulse {
0% { 0% {
-webkit-box-shadow: 0 0 0px 0px #c70019; -webkit-box-shadow: 0 0 0px 0px #c70019;
box-shadow: 0 0 0px 0px #c70019; box-shadow: 0 0 0px 0px #c70019;
@ -363,9 +368,9 @@
-webkit-box-shadow: 0 0 0px 0px #c70019; -webkit-box-shadow: 0 0 0px 0px #c70019;
box-shadow: 0 0 0px 0px #c70019; box-shadow: 0 0 0px 0px #c70019;
} }
} }
@-webkit-keyframes OT_pulse { @-webkit-keyframes OT_pulse {
0% { 0% {
-webkit-box-shadow: 0 0 0px 0px #c70019; -webkit-box-shadow: 0 0 0px 0px #c70019;
box-shadow: 0 0 0px 0px #c70019; box-shadow: 0 0 0px 0px #c70019;
@ -390,32 +395,32 @@
-webkit-box-shadow: 0 0 0px 0px #c70019; -webkit-box-shadow: 0 0 0px 0px #c70019;
box-shadow: 0 0 0px 0px #c70019; box-shadow: 0 0 0px 0px #c70019;
} }
} }
.OT_mini .OT_bar, .OT_mini .OT_bar,
.OT_bar.OT_mode-mini, .OT_bar.OT_mode-mini,
.OT_bar.OT_mode-mini-auto { .OT_bar.OT_mode-mini-auto {
bottom: 0; bottom: 0;
height: auto; height: auto;
} }
.OT_mini .OT_name.OT_mode-off, .OT_mini .OT_name.OT_mode-off,
.OT_mini .OT_name.OT_mode-on, .OT_mini .OT_name.OT_mode-on,
.OT_mini .OT_name.OT_mode-auto, .OT_mini .OT_name.OT_mode-auto,
.OT_mini:hover .OT_name.OT_mode-auto { .OT_mini:hover .OT_name.OT_mode-auto {
display: none; display: none;
} }
.OT_publisher .OT_name, .OT_publisher .OT_name,
.OT_subscriber .OT_name { .OT_subscriber .OT_name {
left: 10px; left: 10px;
right: 37px; right: 37px;
height: 34px; height: 34px;
padding-left: 0; padding-left: 0;
} }
.OT_publisher .OT_mute, .OT_publisher .OT_mute,
.OT_subscriber .OT_mute { .OT_subscriber .OT_mute {
border: none; border: none;
cursor: pointer; cursor: pointer;
display: block; display: block;
@ -424,127 +429,127 @@
text-indent: -9999em; text-indent: -9999em;
background-color: transparent; background-color: transparent;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
.OT_publisher .OT_mute, .OT_publisher .OT_mute,
.OT_subscriber .OT_mute { .OT_subscriber .OT_mute {
right: 0; right: 0;
top: 0; top: 0;
border-left: 1px solid rgba(255, 255, 255, 0.2); border-left: 1px solid rgba(255, 255, 255, 0.2);
height: 36px; height: 36px;
width: 37px; width: 37px;
} }
.OT_mini .OT_mute, .OT_mini .OT_mute,
.OT_publisher.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold, .OT_publisher.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold,
.OT_subscriber.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold { .OT_subscriber.OT_mini .OT_mute.OT_mode-auto.OT_mode-on-hold {
top: 50%; top: 50%;
left: 50%; left: 50%;
right: auto; right: auto;
margin-top: -18px; margin-top: -18px;
margin-left: -18.5px; margin-left: -18.5px;
border-left: none; border-left: none;
} }
.OT_publisher .OT_mute { .OT_publisher .OT_mute {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAcCAMAAAC02HQrAAAA1VBMVEUAAAD3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pn3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pn3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj39/j3+Pj3+Pn4+Pk/JRMlAAAAQ3RSTlMABAUHCQoLDhAQERwdHiAjLjAxOD9ASFBRVl1mbnZ6fH2LjI+QkaWqrrC1uLzAwcXJycrL1NXj5Ofo6u3w9fr7/P3+d4M3+QAAAQBJREFUGBlVwYdCglAABdCLlr5Unijm3hMUtBzlBLSr//9JgUToOQgVJgceJgU8aHgMeA38K50ZOpcQmTPwcyXn+JM8M3JJIqQypiIkeXelTyIkGZPwKS1NMia1lgKTVkaE3oQQGYsmHNqSMWnTgUFbMiZtGlD2dpaxrL1XgM0i4ZK8MeAmFhsAs29MGZniawagS63oMOQUNXYB5D0D1RMDpyoMLw/fiE2og/V+PVDR5AiBl0/2Uwik+vx4xV3a5G5Ye68Nd1czjUjZckm6VhmPciRzeCZICjwTJAViQq+3e+St167rAoHK8sLYZVkBYPCZAZ/eGa+2R5LH7Wrc0YFf/O9J3yBDFaoAAAAASUVORK5CYII=); background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAAcCAMAAAC02HQrAAAA1VBMVEUAAAD3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pn3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pn3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj3+Pj39/j3+Pj3+Pn4+Pk/JRMlAAAAQ3RSTlMABAUHCQoLDhAQERwdHiAjLjAxOD9ASFBRVl1mbnZ6fH2LjI+QkaWqrrC1uLzAwcXJycrL1NXj5Ofo6u3w9fr7/P3+d4M3+QAAAQBJREFUGBlVwYdCglAABdCLlr5Unijm3hMUtBzlBLSr//9JgUToOQgVJgceJgU8aHgMeA38K50ZOpcQmTPwcyXn+JM8M3JJIqQypiIkeXelTyIkGZPwKS1NMia1lgKTVkaE3oQQGYsmHNqSMWnTgUFbMiZtGlD2dpaxrL1XgM0i4ZK8MeAmFhsAs29MGZniawagS63oMOQUNXYB5D0D1RMDpyoMLw/fiE2og/V+PVDR5AiBl0/2Uwik+vx4xV3a5G5Ye68Nd1czjUjZckm6VhmPciRzeCZICjwTJAViQq+3e+St167rAoHK8sLYZVkBYPCZAZ/eGa+2R5LH7Wrc0YFf/O9J3yBDFaoAAAAASUVORK5CYII=);
background-position: 9px 5px; background-position: 9px 5px;
} }
.OT_publisher .OT_mute.OT_active { .OT_publisher .OT_mute.OT_active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAdCAYAAABFRCf7AAADcElEQVRIiaWVXWhcRRTHf7NNd2aDtUKMIjTpg4ufFIuiUOmDEWm0Vi3VYhXRqIggQh4sWJFSig9+oOhTKSpIRUWMIBIr2kptoTbgU6ooxCiIjR+14kcJmf9sNceHnd3ebnc3Uv9wuXfOzPzmnDMz5zozGwdWAbc65w5RUJQ8cC2wDJgFJioh/MJCMrNxq2vOzK4HmIvRRemxKP0RJWt53o7S+d2Yzsx6gQ+AIUDAnUqpBLzXZd4RYFUlhB/bdZacc3PAOmAcCMC7wfvFwLNdoAPAyx09bXyYWRl4E7gDmAdGlNKFwLYu8GolhO9O87RJd64GbMrgEvB68P4osMWdXLtVV7czlooNpVRWSs8DO7NpR/B+3rBHsvetCgtCMTxwQCm9BbyQrc8F7/uBex3uRCeXO0PrUZ4NfKyUPgWeyj3bg/crDNsIRGwBaJQGorQ3Svdn2wHgc2BUKb0DPJHtjwfvbwRucc7tz+N+i9LFUdoXpfVN36I0CVwBTFI/q9e1LPxT8P4qYEdu70q12mYzWw1MYQzjeJF6zq+shHC4B7jklOBPP/TzSunh4P0DwKvAfb5c9krpe+CcwsEoZdbhEvBM9wxRAl5RShcA9wAngE3B+8tLpdLuwrhp4MNmK0pfRWkySr7NXS8+L5nZbWZWy/Vin1IaitJnUTqvwevJ71lgSSWEFKUfHG7Q2m/xqFJaGry/GXgfGPLl8mJgrXPur2JoUC8Qy3OpG+sAbGhEKT0ErAWOA6uBPWbW1wr9BOgFbgKezot0kAPYqJQA1gC/A9cA+82svzksSn1R+jNKX0SpnM/e1x3yqig92JhrZivM7FjO8bSZLSuCR/Ok16K0KMNHojQWpYko7Y7S1igN5PE3ROl4lNaZ2UVmNpPBU01orvZvZPCeKFXbBR+lEKVtUapFaSZKg9njqpl9aWYTrmXCImA7sCWb9lK/jj9TrwkrgA1AH3AQuKsSwkzbrLfxpgpsBtYDxf/R3xm2ExirhNCuHHZXTsmRwiat+S/zSt06eysVA/4pmGr/G3qm6ik28v29FKgCg8BS6pvS0KNRGgZ+Bb4FpsxsOkfUlMuwDcBWYOUZOHYM2AU8WQmhBifDv70O7PjX7KZ+4G7g3FM8zd6uBIaBy4AqxnIcZwFLCovPAhE4Sj38b4BDwEeVEFKD9S94Khjn486v3QAAAABJRU5ErkJggg==); background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAdCAYAAABFRCf7AAADcElEQVRIiaWVXWhcRRTHf7NNd2aDtUKMIjTpg4ufFIuiUOmDEWm0Vi3VYhXRqIggQh4sWJFSig9+oOhTKSpIRUWMIBIr2kptoTbgU6ooxCiIjR+14kcJmf9sNceHnd3ebnc3Uv9wuXfOzPzmnDMz5zozGwdWAbc65w5RUJQ8cC2wDJgFJioh/MJCMrNxq2vOzK4HmIvRRemxKP0RJWt53o7S+d2Yzsx6gQ+AIUDAnUqpBLzXZd4RYFUlhB/bdZacc3PAOmAcCMC7wfvFwLNdoAPAyx09bXyYWRl4E7gDmAdGlNKFwLYu8GolhO9O87RJd64GbMrgEvB68P4osMWdXLtVV7czlooNpVRWSs8DO7NpR/B+3rBHsvetCgtCMTxwQCm9BbyQrc8F7/uBex3uRCeXO0PrUZ4NfKyUPgWeyj3bg/crDNsIRGwBaJQGorQ3Svdn2wHgc2BUKb0DPJHtjwfvbwRucc7tz+N+i9LFUdoXpfVN36I0CVwBTFI/q9e1LPxT8P4qYEdu70q12mYzWw1MYQzjeJF6zq+shHC4B7jklOBPP/TzSunh4P0DwKvAfb5c9krpe+CcwsEoZdbhEvBM9wxRAl5RShcA9wAngE3B+8tLpdLuwrhp4MNmK0pfRWkySr7NXS8+L5nZbWZWy/Vin1IaitJnUTqvwevJ71lgSSWEFKUfHG7Q2m/xqFJaGry/GXgfGPLl8mJgrXPur2JoUC8Qy3OpG+sAbGhEKT0ErAWOA6uBPWbW1wr9BOgFbgKezot0kAPYqJQA1gC/A9cA+82svzksSn1R+jNKX0SpnM/e1x3yqig92JhrZivM7FjO8bSZLSuCR/Ok16K0KMNHojQWpYko7Y7S1igN5PE3ROl4lNaZ2UVmNpPBU01orvZvZPCeKFXbBR+lEKVtUapFaSZKg9njqpl9aWYTrmXCImA7sCWb9lK/jj9TrwkrgA1AH3AQuKsSwkzbrLfxpgpsBtYDxf/R3xm2ExirhNCuHHZXTsmRwiat+S/zSt06eysVA/4pmGr/G3qm6ik28v29FKgCg8BS6pvS0KNRGgZ+Bb4FpsxsOkfUlMuwDcBWYOUZOHYM2AU8WQmhBifDv70O7PjX7KZ+4G7g3FM8zd6uBIaBy4AqxnIcZwFLCovPAhE4Sj38b4BDwEeVEFKD9S94Khjn486v3QAAAABJRU5ErkJggg==);
background-position: 9px 4px; background-position: 9px 4px;
} }
.OT_subscriber .OT_mute { .OT_subscriber .OT_mute {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAATCAYAAAB7u5a2AAABx0lEQVQ4jaWUv48NURiGn3ONmCs32ZBd28ht1gqyZAkF21ylQkEiSp2ehpDlD1BoFGqqVdJohYKI7MaPxMoVNghCWMF+7ybLUewnOXfcMWO9yeQ857zne8+XmZOBGjJpr0kvTIomvTZpS526UCO4DUwD64FjwCFgqZnnR+oc8LfgzKQ73vGsr42ZtGjSQFV9o8KfBCacZwCaef4YmAf2rzjcpN3A2WSpm/AssKcqPDNpDBjs410CViXzTwk/A7b1C4wxDgOngAsZcAXY2buDfp/6S4F3lDS8DjgBzDWAjX/Y/e/QgYS/AhsKHa+OMQ6GEJ4Cj4BOAxgq6aCowyZtdf4OtAr+FHDO+R4wWnVbihr3cQnICt4boO38GWj9a/icjwOACt4m4K3zEPA+AxaAtTWCnwN3lzHkEL8V/OPAGud9wK2GF9XR1Wae/1zG2AI+pGYI4VUIoRtjHAc2A9cz4LRPevYCZ+i9/4sJt4GXJU10gaPAzdI2TTro/5Tfz8XEe2LSZGmxq/SDNvP8BnA5WRrx4BwYBe6vONx1EnjovGvBLAAd4Adwuyq8UiaNmDTvr+a8SQ9MuvbfwckBHZPe+QEfTdpep+4XZmPBHiHgz74AAAAASUVORK5CYII=); background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAATCAYAAAB7u5a2AAABx0lEQVQ4jaWUv48NURiGn3ONmCs32ZBd28ht1gqyZAkF21ylQkEiSp2ehpDlD1BoFGqqVdJohYKI7MaPxMoVNghCWMF+7ybLUewnOXfcMWO9yeQ857zne8+XmZOBGjJpr0kvTIomvTZpS526UCO4DUwD64FjwCFgqZnnR+oc8LfgzKQ73vGsr42ZtGjSQFV9o8KfBCacZwCaef4YmAf2rzjcpN3A2WSpm/AssKcqPDNpDBjs410CViXzTwk/A7b1C4wxDgOngAsZcAXY2buDfp/6S4F3lDS8DjgBzDWAjX/Y/e/QgYS/AhsKHa+OMQ6GEJ4Cj4BOAxgq6aCowyZtdf4OtAr+FHDO+R4wWnVbihr3cQnICt4boO38GWj9a/icjwOACt4m4K3zEPA+AxaAtTWCnwN3lzHkEL8V/OPAGud9wK2GF9XR1Wae/1zG2AI+pGYI4VUIoRtjHAc2A9cz4LRPevYCZ+i9/4sJt4GXJU10gaPAzdI2TTro/5Tfz8XEe2LSZGmxq/SDNvP8BnA5WRrx4BwYBe6vONx1EnjovGvBLAAd4Adwuyq8UiaNmDTvr+a8SQ9MuvbfwckBHZPe+QEfTdpep+4XZmPBHiHgz74AAAAASUVORK5CYII=);
background-position: 8px 7px; background-position: 8px 7px;
} }
.OT_subscriber .OT_mute.OT_active { .OT_subscriber .OT_mute.OT_active {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAUCAYAAACXtf2DAAACtklEQVQ4jZ2VSYiURxTHf+/T9Nc9iRrBuYySmIsXUU9iFMEFERRBvAjJLUQi5ioiHvSScfTmgqC4XAT1ZIgLuJHkICaaQAgKI2hAUBT30bjUq7bbv4eukXK029F3+eqtv/fqK6qQdEnSNUmT6CDB/bvgfjO4N9zj2RD8007xg1IABkwEzkma0qb4PGAPMBZYLtSD8eNwAEjqTlNI0gNJM4YU7w7ut4O7gvuhZFsR3C8NC5BBLiTIY0mzM8AvqbiC++pk+zLpE95XuwAws3vAQuBPYDRwWtL84P4tsDSLv5oaug4EYOawAMF9jMdoLxqNZcDvQA04UVYqL4G/svj7AF21mhJscrvCksYBFO7xc2AAGGg2mrdjvf4rcAyomNn+slLZmUEGBgsYdh945xZJmgvckDSrEJpK6ySBgV6q12O8ABwGPjGzfWWlsjdN9rpjoSfA+DYDXARGAksK4Is3XC1Ub4z1f4CDQGFmu6tleQSYk0U+p7WVeefLJc00s4fAeWB6Qeunvj0m2ugx9gO7kmlrtSxvBfcy6fXUZS6rgG/S+jLQUwCVNmMC9HqM14EtSe+rluWazN8YEv8IqKZ1E1qnaIDO0ucx3gX6kv6TpM3AM+D/IbGjgP60/gq4WQA33gMA2OQxPgHWJX1ttSwL4FAeZGYLgB2SasBs4A8L7qOBf9M0uXQB3a+TMYSmVctyDrA9mfcBK82smSdKWgCcAaa1bTm4fxbc/8uuCQX3RanAD5Ka6Wo5IGnE0HxJPZ03pQX5Org3MsD3AO5xXLPZXJ9BjkrqdFg6QjZkgG3Jtsw93pG0VFI9QU5K6voYQBHcTydAfwheBI9HgvvPAJIWS3qeIL9JGvUxkO7gfi1BrqTvwkG/pPmSnibIqTzXPgAyEVgBjAEu1qrVPbk/PVTHgb/NbPGg/RVIzOQqzSTBaQAAAABJRU5ErkJggg==); background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAUCAYAAACXtf2DAAACtklEQVQ4jZ2VSYiURxTHf+/T9Nc9iRrBuYySmIsXUU9iFMEFERRBvAjJLUQi5ioiHvSScfTmgqC4XAT1ZIgLuJHkICaaQAgKI2hAUBT30bjUq7bbv4eukXK029F3+eqtv/fqK6qQdEnSNUmT6CDB/bvgfjO4N9zj2RD8007xg1IABkwEzkma0qb4PGAPMBZYLtSD8eNwAEjqTlNI0gNJM4YU7w7ut4O7gvuhZFsR3C8NC5BBLiTIY0mzM8AvqbiC++pk+zLpE95XuwAws3vAQuBPYDRwWtL84P4tsDSLv5oaug4EYOawAMF9jMdoLxqNZcDvQA04UVYqL4G/svj7AF21mhJscrvCksYBFO7xc2AAGGg2mrdjvf4rcAyomNn+slLZmUEGBgsYdh945xZJmgvckDSrEJpK6ySBgV6q12O8ABwGPjGzfWWlsjdN9rpjoSfA+DYDXARGAksK4Is3XC1Ub4z1f4CDQGFmu6tleQSYk0U+p7WVeefLJc00s4fAeWB6Qeunvj0m2ugx9gO7kmlrtSxvBfcy6fXUZS6rgG/S+jLQUwCVNmMC9HqM14EtSe+rluWazN8YEv8IqKZ1E1qnaIDO0ucx3gX6kv6TpM3AM+D/IbGjgP60/gq4WQA33gMA2OQxPgHWJX1ttSwL4FAeZGYLgB2SasBs4A8L7qOBf9M0uXQB3a+TMYSmVctyDrA9mfcBK82smSdKWgCcAaa1bTm4fxbc/8uuCQX3RanAD5Ka6Wo5IGnE0HxJPZ03pQX5Org3MsD3AO5xXLPZXJ9BjkrqdFg6QjZkgG3Jtsw93pG0VFI9QU5K6voYQBHcTydAfwheBI9HgvvPAJIWS3qeIL9JGvUxkO7gfi1BrqTvwkG/pPmSnibIqTzXPgAyEVgBjAEu1qrVPbk/PVTHgb/NbPGg/RVIzOQqzSTBaQAAAABJRU5ErkJggg==);
background-position: 7px 7px; background-position: 7px 7px;
} }
/** /**
* Styles for display modes * Styles for display modes
* *
* Note: It's important that these completely control the display and opacity * Note: It's important that these completely control the display and opacity
* attributes, no other selectors should atempt to change them. * attributes, no other selectors should atempt to change them.
*/ */
/* Default display mode transitions for various chrome elements */ /* Default display mode transitions for various chrome elements */
.OT_publisher .OT_edge-bar-item, .OT_publisher .OT_edge-bar-item,
.OT_subscriber .OT_edge-bar-item { .OT_subscriber .OT_edge-bar-item {
-webkit-transition-property: top, bottom, opacity; -webkit-transition-property: top, bottom, opacity;
transition-property: top, bottom, opacity; transition-property: top, bottom, opacity;
-webkit-transition-duration: 0.5s; -webkit-transition-duration: 0.5s;
transition-duration: 0.5s; transition-duration: 0.5s;
-webkit-transition-timing-function: ease-in; -webkit-transition-timing-function: ease-in;
transition-timing-function: ease-in; transition-timing-function: ease-in;
} }
.OT_publisher .OT_edge-bar-item.OT_mode-off, .OT_publisher .OT_edge-bar-item.OT_mode-off,
.OT_subscriber .OT_edge-bar-item.OT_mode-off, .OT_subscriber .OT_edge-bar-item.OT_mode-off,
.OT_publisher .OT_edge-bar-item.OT_mode-auto, .OT_publisher .OT_edge-bar-item.OT_mode-auto,
.OT_subscriber .OT_edge-bar-item.OT_mode-auto, .OT_subscriber .OT_edge-bar-item.OT_mode-auto,
.OT_publisher .OT_edge-bar-item.OT_mode-mini-auto, .OT_publisher .OT_edge-bar-item.OT_mode-mini-auto,
.OT_subscriber .OT_edge-bar-item.OT_mode-mini-auto { .OT_subscriber .OT_edge-bar-item.OT_mode-mini-auto {
top: -25px; top: -25px;
opacity: 0; opacity: 0;
} }
.OT_publisher .OT_edge-bar-item.OT_mode-off, .OT_publisher .OT_edge-bar-item.OT_mode-off,
.OT_subscriber .OT_edge-bar-item.OT_mode-off { .OT_subscriber .OT_edge-bar-item.OT_mode-off {
display: none; display: none;
} }
.OT_mini .OT_mute.OT_mode-auto, .OT_mini .OT_mute.OT_mode-auto,
.OT_publisher .OT_mute.OT_mode-mini-auto, .OT_publisher .OT_mute.OT_mode-mini-auto,
.OT_subscriber .OT_mute.OT_mode-mini-auto { .OT_subscriber .OT_mute.OT_mode-mini-auto {
top: 50%; top: 50%;
} }
.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-off, .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-off,
.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-off, .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-off,
.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto,
.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto,
.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto, .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto,
.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto { .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-mini-auto {
top: auto; top: auto;
bottom: -25px; bottom: -25px;
} }
.OT_publisher .OT_edge-bar-item.OT_mode-on, .OT_publisher .OT_edge-bar-item.OT_mode-on,
.OT_subscriber .OT_edge-bar-item.OT_mode-on, .OT_subscriber .OT_edge-bar-item.OT_mode-on,
.OT_publisher .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold, .OT_publisher .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold,
.OT_subscriber .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold, .OT_subscriber .OT_edge-bar-item.OT_mode-auto.OT_mode-on-hold,
.OT_publisher:hover .OT_edge-bar-item.OT_mode-auto, .OT_publisher:hover .OT_edge-bar-item.OT_mode-auto,
.OT_subscriber:hover .OT_edge-bar-item.OT_mode-auto, .OT_subscriber:hover .OT_edge-bar-item.OT_mode-auto,
.OT_publisher:hover .OT_edge-bar-item.OT_mode-mini-auto, .OT_publisher:hover .OT_edge-bar-item.OT_mode-mini-auto,
.OT_subscriber:hover .OT_edge-bar-item.OT_mode-mini-auto { .OT_subscriber:hover .OT_edge-bar-item.OT_mode-mini-auto {
top: 0; top: 0;
opacity: 1; opacity: 1;
} }
.OT_mini .OT_mute.OT_mode-on, .OT_mini .OT_mute.OT_mode-on,
.OT_mini:hover .OT_mute.OT_mode-auto, .OT_mini:hover .OT_mute.OT_mode-auto,
.OT_mute.OT_mode-mini, .OT_mute.OT_mode-mini,
.OT_root:hover .OT_mute.OT_mode-mini-auto { .OT_root:hover .OT_mute.OT_mode-mini-auto {
top: 50%; top: 50%;
} }
.OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-on, .OT_publisher .OT_edge-bar-item.OT_edge-bottom.OT_mode-on,
.OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-on, .OT_subscriber .OT_edge-bar-item.OT_edge-bottom.OT_mode-on,
.OT_publisher:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto, .OT_publisher:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto,
.OT_subscriber:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto { .OT_subscriber:hover .OT_edge-bar-item.OT_edge-bottom.OT_mode-auto {
top: auto; top: auto;
bottom: 0; bottom: 0;
opacity: 1; opacity: 1;
} }
/* Load animation */ /* Load animation */
.OT_root .OT_video-loading { .OT_root .OT_video-loading {
position: absolute; position: absolute;
z-index: 1; z-index: 1;
width: 100%; width: 100%;
@ -552,9 +557,9 @@
display: none; display: none;
background-color: rgba(0, 0, 0, 0.75); background-color: rgba(0, 0, 0, 0.75);
} }
.OT_root .OT_video-loading .OT_video-loading-spinner { .OT_root .OT_video-loading .OT_video-loading-spinner {
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0yMCAtMjAgMjQwIDI0MCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgeDE9IjEiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjA4Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImMiIHgxPSIxIiB4Mj0iMCIgeTE9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuMDgiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjE2Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIHgyPSIwIiB5MT0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9Ii4xNiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgeDI9IjEiIHkxPSIxIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjMzIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9Ii42NiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiB4Mj0iMSIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuNjYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiLz48L2xpbmVhckdyYWRpZW50PjxtYXNrIGlkPSJnIj48ZyBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjQwIj48cGF0aCBzdHJva2U9InVybCgjYSkiIGQ9Ik04Ni42LTUwYTEwMCAxMDAgMCAwIDEgMCAxMDAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMCAxMDApIi8+PHBhdGggc3Ryb2tlPSJ1cmwoI2IpIiBkPSJNODYuNiA1MEExMDAgMTAwIDAgMCAxIDAgMTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjxwYXRoIHN0cm9rZT0idXJsKCNjKSIgZD0iTTAgMTAwYTEwMCAxMDAgMCAwIDEtODYuNi01MCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAwIDEwMCkiLz48cGF0aCBzdHJva2U9InVybCgjZCkiIGQ9Ik0tODYuNiA1MGExMDAgMTAwIDAgMCAxIDAtMTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjxwYXRoIHN0cm9rZT0idXJsKCNlKSIgZD0iTS04Ni42LTUwQTEwMCAxMDAgMCAwIDEgMC0xMDAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMCAxMDApIi8+PHBhdGggc3Ryb2tlPSJ1cmwoI2YpIiBkPSJNMC0xMDBhMTAwIDEwMCAwIDAgMSA4Ni42IDUwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjwvZz48L21hc2s+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHg9Ii0yMCIgeT0iLTIwIiBtYXNrPSJ1cmwoI2cpIiBmaWxsPSIjZmZmIi8+PC9zdmc+) background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0yMCAtMjAgMjQwIDI0MCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJhIiB4Mj0iMCIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgeDE9IjEiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjA4Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImMiIHgxPSIxIiB4Mj0iMCIgeTE9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuMDgiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjE2Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIHgyPSIwIiB5MT0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9Ii4xNiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuMzMiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgeDI9IjEiIHkxPSIxIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iLjMzIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9Ii42NiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiB4Mj0iMSIgeTI9IjEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIgc3RvcC1vcGFjaXR5PSIuNjYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiLz48L2xpbmVhckdyYWRpZW50PjxtYXNrIGlkPSJnIj48ZyBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjQwIj48cGF0aCBzdHJva2U9InVybCgjYSkiIGQ9Ik04Ni42LTUwYTEwMCAxMDAgMCAwIDEgMCAxMDAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMCAxMDApIi8+PHBhdGggc3Ryb2tlPSJ1cmwoI2IpIiBkPSJNODYuNiA1MEExMDAgMTAwIDAgMCAxIDAgMTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjxwYXRoIHN0cm9rZT0idXJsKCNjKSIgZD0iTTAgMTAwYTEwMCAxMDAgMCAwIDEtODYuNi01MCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAwIDEwMCkiLz48cGF0aCBzdHJva2U9InVybCgjZCkiIGQ9Ik0tODYuNiA1MGExMDAgMTAwIDAgMCAxIDAtMTAwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjxwYXRoIHN0cm9rZT0idXJsKCNlKSIgZD0iTS04Ni42LTUwQTEwMCAxMDAgMCAwIDEgMC0xMDAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwMCAxMDApIi8+PHBhdGggc3Ryb2tlPSJ1cmwoI2YpIiBkPSJNMC0xMDBhMTAwIDEwMCAwIDAgMSA4Ni42IDUwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMDAgMTAwKSIvPjwvZz48L21hc2s+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHg9Ii0yMCIgeT0iLTIwIiBtYXNrPSJ1cmwoI2cpIiBmaWxsPSIjZmZmIi8+PC9zdmc+)
no-repeat; no-repeat;
position: absolute; position: absolute;
@ -566,36 +571,36 @@
margin-top: -16px; margin-top: -16px;
-webkit-animation: OT_spin 2s linear infinite; -webkit-animation: OT_spin 2s linear infinite;
animation: OT_spin 2s linear infinite; animation: OT_spin 2s linear infinite;
} }
@-webkit-keyframes OT_spin { @-webkit-keyframes OT_spin {
100% { 100% {
-webkit-transform: rotate(360deg); -webkit-transform: rotate(360deg);
} }
} }
@keyframes OT_spin { @keyframes OT_spin {
100% { 100% {
-webkit-transform: rotate(360deg); -webkit-transform: rotate(360deg);
transform: rotate(360deg); transform: rotate(360deg);
} }
} }
.OT_publisher.OT_loading .OT_video-loading, .OT_publisher.OT_loading .OT_video-loading,
.OT_subscriber.OT_loading .OT_video-loading { .OT_subscriber.OT_loading .OT_video-loading {
display: block; display: block;
} }
.OT_video-centering { .OT_video-centering {
display: table; display: table;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.OT_video-container { .OT_video-container {
display: table-cell; display: table-cell;
vertical-align: middle; vertical-align: middle;
} }
.OT_video-poster { .OT_video-poster {
position: absolute; position: absolute;
z-index: 1; z-index: 1;
width: 100%; width: 100%;
@ -607,36 +612,36 @@
background-repeat: no-repeat; background-repeat: no-repeat;
background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNDcxIDQ2NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSI2Ni42NiUiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNhKSIgZD0iTTc5IDMwOGMxNC4yNS02LjUgNTQuMjUtMTkuNzUgNzEtMjkgOS0zLjI1IDI1LTIxIDI1LTIxczMuNzUtMTMgMy0yMmMtMS43NS02Ljc1LTE1LTQzLTE1LTQzLTIuNSAzLTQuNzQxIDMuMjU5LTcgMS0zLjI1LTcuNS0yMC41LTQ0LjUtMTYtNTcgMS4yNS03LjUgMTAtNiAxMC02LTExLjI1LTMzLjc1LTgtNjctOC02N3MuMDczLTcuMzQ2IDYtMTVjLTMuNDguNjM3LTkgNC05IDQgMi41NjMtMTEuNzI3IDE1LTIxIDE1LTIxIC4xNDgtLjMxMi0xLjMyMS0xLjQ1NC0xMCAxIDEuNS0yLjc4IDE2LjY3NS04LjY1NCAzMC0xMSAzLjc4Ny05LjM2MSAxMi43ODItMTcuMzk4IDIyLTIyLTIuMzY1IDMuMTMzLTMgNi0zIDZzMTUuNjQ3LTguMDg4IDQxLTZjLTE5Ljc1IDItMjQgNi0yNCA2czc0LjUtMTAuNzUgMTA0IDM3YzcuNSA5LjUgMjQuNzUgNTUuNzUgMTAgODkgMy43NS0xLjUgNC41LTQuNSA5IDEgLjI1IDE0Ljc1LTExLjUgNjMtMTkgNjItMi43NSAxLTQtMy00LTMtMTAuNzUgMjkuNS0xNCAzOC0xNCAzOC0yIDQuMjUtMy43NSAxOC41LTEgMjIgMS4yNSA0LjUgMjMgMjMgMjMgMjNsMTI3IDUzYzM3IDM1IDIzIDEzNSAyMyAxMzVMMCA0NjRzLTMtOTYuNzUgMTQtMTIwYzUuMjUtNi4yNSAyMS43NS0xOS43NSA2NS0zNnoiLz48L3N2Zz4=); background-image: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNDcxIDQ2NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSI2Ni42NiUiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZmlsbD0idXJsKCNhKSIgZD0iTTc5IDMwOGMxNC4yNS02LjUgNTQuMjUtMTkuNzUgNzEtMjkgOS0zLjI1IDI1LTIxIDI1LTIxczMuNzUtMTMgMy0yMmMtMS43NS02Ljc1LTE1LTQzLTE1LTQzLTIuNSAzLTQuNzQxIDMuMjU5LTcgMS0zLjI1LTcuNS0yMC41LTQ0LjUtMTYtNTcgMS4yNS03LjUgMTAtNiAxMC02LTExLjI1LTMzLjc1LTgtNjctOC02N3MuMDczLTcuMzQ2IDYtMTVjLTMuNDguNjM3LTkgNC05IDQgMi41NjMtMTEuNzI3IDE1LTIxIDE1LTIxIC4xNDgtLjMxMi0xLjMyMS0xLjQ1NC0xMCAxIDEuNS0yLjc4IDE2LjY3NS04LjY1NCAzMC0xMSAzLjc4Ny05LjM2MSAxMi43ODItMTcuMzk4IDIyLTIyLTIuMzY1IDMuMTMzLTMgNi0zIDZzMTUuNjQ3LTguMDg4IDQxLTZjLTE5Ljc1IDItMjQgNi0yNCA2czc0LjUtMTAuNzUgMTA0IDM3YzcuNSA5LjUgMjQuNzUgNTUuNzUgMTAgODkgMy43NS0xLjUgNC41LTQuNSA5IDEgLjI1IDE0Ljc1LTExLjUgNjMtMTkgNjItMi43NSAxLTQtMy00LTMtMTAuNzUgMjkuNS0xNCAzOC0xNCAzOC0yIDQuMjUtMy43NSAxOC41LTEgMjIgMS4yNSA0LjUgMjMgMjMgMjMgMjNsMTI3IDUzYzM3IDM1IDIzIDEzNSAyMyAxMzVMMCA0NjRzLTMtOTYuNzUgMTQtMTIwYzUuMjUtNi4yNSAyMS43NS0xOS43NSA2NS0zNnoiLz48L3N2Zz4=);
background-size: auto 76%; background-size: auto 76%;
} }
.OT_fit-mode-cover .OT_video-element { .OT_fit-mode-cover .OT_video-element {
-o-object-fit: cover; -o-object-fit: cover;
object-fit: cover; object-fit: cover;
} }
/* Workaround for iOS freezing issue when cropping videos */ /* Workaround for iOS freezing issue when cropping videos */
/* https://bugs.webkit.org/show_bug.cgi?id=176439 */ /* https://bugs.webkit.org/show_bug.cgi?id=176439 */
@media only screen and (orientation: portrait) { @media only screen and (orientation: portrait) {
.OT_subscriber.OT_ForceContain.OT_fit-mode-cover .OT_video-element { .OT_subscriber.OT_ForceContain.OT_fit-mode-cover .OT_video-element {
-o-object-fit: contain !important; -o-object-fit: contain !important;
object-fit: contain !important; object-fit: contain !important;
} }
} }
.OT_fit-mode-contain .OT_video-element { .OT_fit-mode-contain .OT_video-element {
-o-object-fit: contain; -o-object-fit: contain;
object-fit: contain; object-fit: contain;
} }
.OT_fit-mode-cover .OT_video-poster { .OT_fit-mode-cover .OT_video-poster {
background-position: center bottom; background-position: center bottom;
} }
.OT_fit-mode-contain .OT_video-poster { .OT_fit-mode-contain .OT_video-poster {
background-position: center; background-position: center;
} }
.OT_audio-level-meter { .OT_audio-level-meter {
position: absolute; position: absolute;
width: 25%; width: 25%;
max-width: 224px; max-width: 224px;
@ -644,16 +649,16 @@
top: 0; top: 0;
right: 0; right: 0;
overflow: hidden; overflow: hidden;
} }
.OT_audio-level-meter:before { .OT_audio-level-meter:before {
/* makes the height of the container equals its width */ /* makes the height of the container equals its width */
content: ''; content: '';
display: block; display: block;
padding-top: 100%; padding-top: 100%;
} }
.OT_audio-level-meter__bar { .OT_audio-level-meter__bar {
position: absolute; position: absolute;
width: 192%; /* meter value can overflow of 8% */ width: 192%; /* meter value can overflow of 8% */
height: 192%; height: 192%;
@ -662,9 +667,9 @@
border-radius: 50%; border-radius: 50%;
background-color: rgba(0, 0, 0, 0.8); background-color: rgba(0, 0, 0, 0.8);
} }
.OT_audio-level-meter__audio-only-img { .OT_audio-level-meter__audio-only-img {
position: absolute; position: absolute;
top: 22%; top: 22%;
right: 15%; right: 15%;
@ -674,36 +679,36 @@
background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNzkgODYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTkuNzU3IDQwLjkyNGMzLjczOC01LjE5MSAxMi43MTEtNC4zMDggMTIuNzExLTQuMzA4IDIuMjIzIDMuMDE0IDUuMTI2IDI0LjU4NiAzLjYyNCAyOC43MTgtMS40MDEgMS4zMDEtMTEuNjExIDEuNjI5LTEzLjM4LTEuNDM2LTEuMjI2LTguODA0LTIuOTU1LTIyLjk3NS0yLjk1NS0yMi45NzV6bTU4Ljc4NSAwYy0zLjczNy01LjE5MS0xMi43MTEtNC4zMDgtMTIuNzExLTQuMzA4LTIuMjIzIDMuMDE0LTUuMTI2IDI0LjU4Ni0zLjYyNCAyOC43MTggMS40MDEgMS4zMDEgMTEuNjExIDEuNjI5IDEzLjM4LTEuNDM2IDEuMjI2LTguODA0IDIuOTU1LTIyLjk3NSAyLjk1NS0yMi45NzV6Ii8+PHBhdGggZD0iTTY4LjY0NyA1OC42Yy43MjktNC43NTMgMi4zOC05LjU2MSAyLjM4LTE0LjgwNCAwLTIxLjQxMi0xNC4xMTUtMzguNzctMzEuNTI4LTM4Ljc3LTE3LjQxMiAwLTMxLjUyNyAxNy4zNTgtMzEuNTI3IDM4Ljc3IDAgNC41NDEuNTE1IDguOTM2IDEuODAyIDEyLjk1IDEuNjk4IDUuMjk1LTUuNTQyIDYuOTkxLTYuNjE2IDIuMDczQzIuNDEgNTUuMzk0IDAgNTEuNzg3IDAgNDguMTAzIDAgMjEuNTM2IDE3LjY4NSAwIDM5LjUgMCA2MS4zMTYgMCA3OSAyMS41MzYgNzkgNDguMTAzYzAgLjcxOC0yLjg5OSA5LjY5My0zLjI5MiAxMS40MDgtLjc1NCAzLjI5My03Ljc1MSAzLjU4OS03LjA2MS0uOTEyeiIvPjxwYXRoIGQ9Ik01LjA4NCA1MS4zODVjLS44MDQtMy43ODIuNTY5LTcuMzM1IDMuMTM0LTcuOTIxIDIuNjM2LS42MDMgNS40ODUgMi4xNSA2LjI4OSA2LjEzMi43OTcgMy45NDgtLjc1MiA3LjQ1Ny0zLjM4OCA3Ljg1OS0yLjU2Ni4zOTEtNS4yMzctMi4zMTgtNi4wMzQtNi4wN3ptNjguODM0IDBjLjgwNC0zLjc4Mi0uNTY4LTcuMzM1LTMuMTMzLTcuOTIxLTIuNjM2LS42MDMtNS40ODUgMi4xNS02LjI4OSA2LjEzMi0uNzk3IDMuOTQ4Ljc1MiA3LjQ1NyAzLjM4OSA3Ljg1OSAyLjU2NS4zOTEgNS4yMzctMi4zMTggNi4wMzQtNi4wN3ptLTIuMDM4IDguMjg4Yy0uOTI2IDE5LjY1OS0xNS4xMTIgMjQuNzU5LTI1Ljg1OSAyMC40NzUtNS40MDUtLjYwNi0zLjAzNCAxLjI2Mi0zLjAzNCAxLjI2MiAxMy42NjEgMy41NjIgMjYuMTY4IDMuNDk3IDMxLjI3My0yMC41NDktLjU4NS00LjUxMS0yLjM3OS0xLjE4Ny0yLjM3OS0xLjE4N3oiLz48cGF0aCBkPSJNNDEuNjYyIDc4LjQyMmw3LjU1My41NWMxLjE5Mi4xMDcgMi4xMiAxLjE1MyAyLjA3MiAyLjMzNWwtLjEwOSAyLjczOGMtLjA0NyAxLjE4Mi0xLjA1MSAyLjA1NC0yLjI0MyAxLjk0NmwtNy41NTMtLjU1Yy0xLjE5MS0uMTA3LTIuMTE5LTEuMTUzLTIuMDcyLTIuMzM1bC4xMDktMi43MzdjLjA0Ny0xLjE4MiAxLjA1Mi0yLjA1NCAyLjI0My0xLjk0N3oiLz48L2c+PC9zdmc+) background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNzkgODYiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTkuNzU3IDQwLjkyNGMzLjczOC01LjE5MSAxMi43MTEtNC4zMDggMTIuNzExLTQuMzA4IDIuMjIzIDMuMDE0IDUuMTI2IDI0LjU4NiAzLjYyNCAyOC43MTgtMS40MDEgMS4zMDEtMTEuNjExIDEuNjI5LTEzLjM4LTEuNDM2LTEuMjI2LTguODA0LTIuOTU1LTIyLjk3NS0yLjk1NS0yMi45NzV6bTU4Ljc4NSAwYy0zLjczNy01LjE5MS0xMi43MTEtNC4zMDgtMTIuNzExLTQuMzA4LTIuMjIzIDMuMDE0LTUuMTI2IDI0LjU4Ni0zLjYyNCAyOC43MTggMS40MDEgMS4zMDEgMTEuNjExIDEuNjI5IDEzLjM4LTEuNDM2IDEuMjI2LTguODA0IDIuOTU1LTIyLjk3NSAyLjk1NS0yMi45NzV6Ii8+PHBhdGggZD0iTTY4LjY0NyA1OC42Yy43MjktNC43NTMgMi4zOC05LjU2MSAyLjM4LTE0LjgwNCAwLTIxLjQxMi0xNC4xMTUtMzguNzctMzEuNTI4LTM4Ljc3LTE3LjQxMiAwLTMxLjUyNyAxNy4zNTgtMzEuNTI3IDM4Ljc3IDAgNC41NDEuNTE1IDguOTM2IDEuODAyIDEyLjk1IDEuNjk4IDUuMjk1LTUuNTQyIDYuOTkxLTYuNjE2IDIuMDczQzIuNDEgNTUuMzk0IDAgNTEuNzg3IDAgNDguMTAzIDAgMjEuNTM2IDE3LjY4NSAwIDM5LjUgMCA2MS4zMTYgMCA3OSAyMS41MzYgNzkgNDguMTAzYzAgLjcxOC0yLjg5OSA5LjY5My0zLjI5MiAxMS40MDgtLjc1NCAzLjI5My03Ljc1MSAzLjU4OS03LjA2MS0uOTEyeiIvPjxwYXRoIGQ9Ik01LjA4NCA1MS4zODVjLS44MDQtMy43ODIuNTY5LTcuMzM1IDMuMTM0LTcuOTIxIDIuNjM2LS42MDMgNS40ODUgMi4xNSA2LjI4OSA2LjEzMi43OTcgMy45NDgtLjc1MiA3LjQ1Ny0zLjM4OCA3Ljg1OS0yLjU2Ni4zOTEtNS4yMzctMi4zMTgtNi4wMzQtNi4wN3ptNjguODM0IDBjLjgwNC0zLjc4Mi0uNTY4LTcuMzM1LTMuMTMzLTcuOTIxLTIuNjM2LS42MDMtNS40ODUgMi4xNS02LjI4OSA2LjEzMi0uNzk3IDMuOTQ4Ljc1MiA3LjQ1NyAzLjM4OSA3Ljg1OSAyLjU2NS4zOTEgNS4yMzctMi4zMTggNi4wMzQtNi4wN3ptLTIuMDM4IDguMjg4Yy0uOTI2IDE5LjY1OS0xNS4xMTIgMjQuNzU5LTI1Ljg1OSAyMC40NzUtNS40MDUtLjYwNi0zLjAzNCAxLjI2Mi0zLjAzNCAxLjI2MiAxMy42NjEgMy41NjIgMjYuMTY4IDMuNDk3IDMxLjI3My0yMC41NDktLjU4NS00LjUxMS0yLjM3OS0xLjE4Ny0yLjM3OS0xLjE4N3oiLz48cGF0aCBkPSJNNDEuNjYyIDc4LjQyMmw3LjU1My41NWMxLjE5Mi4xMDcgMi4xMiAxLjE1MyAyLjA3MiAyLjMzNWwtLjEwOSAyLjczOGMtLjA0NyAxLjE4Mi0xLjA1MSAyLjA1NC0yLjI0MyAxLjk0NmwtNy41NTMtLjU1Yy0xLjE5MS0uMTA3LTIuMTE5LTEuMTUzLTIuMDcyLTIuMzM1bC4xMDktMi43MzdjLjA0Ny0xLjE4MiAxLjA1Mi0yLjA1NCAyLjI0My0xLjk0N3oiLz48L2c+PC9zdmc+)
no-repeat center; no-repeat center;
} }
.OT_audio-level-meter__audio-only-img:before { .OT_audio-level-meter__audio-only-img:before {
/* makes the height of the container equals its width */ /* makes the height of the container equals its width */
content: ''; content: '';
display: block; display: block;
padding-top: 100%; padding-top: 100%;
} }
.OT_audio-level-meter__value { .OT_audio-level-meter__value {
position: absolute; position: absolute;
border-radius: 50%; border-radius: 50%;
background-image: radial-gradient(circle, rgba(151, 206, 0, 1) 0%, rgba(151, 206, 0, 0) 100%); background-image: radial-gradient(circle, rgba(151, 206, 0, 1) 0%, rgba(151, 206, 0, 0) 100%);
} }
.OT_audio-level-meter.OT_mode-off { .OT_audio-level-meter.OT_mode-off {
display: none; display: none;
} }
.OT_audio-level-meter.OT_mode-on, .OT_audio-level-meter.OT_mode-on,
.OT_audio-only .OT_audio-level-meter.OT_mode-auto { .OT_audio-only .OT_audio-level-meter.OT_mode-auto {
display: block; display: block;
} }
.OT_audio-only.OT_publisher .OT_video-element, .OT_audio-only.OT_publisher .OT_video-element,
.OT_audio-only.OT_subscriber .OT_video-element { .OT_audio-only.OT_subscriber .OT_video-element {
display: none; display: none;
} }
.OT_video-disabled-indicator { .OT_video-disabled-indicator {
opacity: 1; opacity: 1;
border: none; border: none;
display: none; display: none;
@ -716,23 +721,23 @@
left: 0; left: 0;
bottom: 3px; bottom: 3px;
right: 3px; right: 3px;
} }
.OT_video-disabled { .OT_video-disabled {
background-image: url(data:image/png;base64,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); background-image: url(data:image/png;base64,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);
background-size: 33px auto; background-size: 33px auto;
} }
.OT_video-disabled-warning { .OT_video-disabled-warning {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFIAAAAoCAYAAABtla08AAAGMElEQVR4Ae2aA7D0yBaAc7oH12vbRmlLaxYWb23btm3btm2899a2bWuYtPZ01cmtU9lJrib315yqr9I3Oem/5/s7acwEnehEJzoxCcX2O+wEeIgRBDDaGjAZOgQ6ihRpLklHZDJIXK1WWymMIhGGkVBKCWMM+Iv/f/b5t7faYtM/sGgIS7j8RNLjceUVl41GvGN1BFiHy9sgtRWaYbhvuVQ6o1VOvV5/tLe3dyssKoZuh8xClkDEi2MMS6ZjR0cScxdK/+HgnJsmLccYOx0e/PUGUqfTJDEHkV5go9lcMQoj4R8RpSIRRUr4a9baTJFCCNfqESKJ7RYJibK0xoi05EhFRTxMi1Rit6xHAuLaKRLwEVi6q1x+EhlVpd3d3Wfh4VQkQhRhxthYLg7SRGqdLlIp7UVOHf+JhEhEMscUolVje3p63saeeOFoKsT7fjj++BNuw2I/0ouUENmGaQcQEilQvUU6xuWC0kqmVWCt8df6kG7WLoFA20VSCOyNh0RKPT+SyrTWtQsvuvTYCy84z3+oAdbgAiLGIvHjTz6bFuu/B3lKKfVkFKknwih6EnnipZdfXQZzepAupXSGSCfwUGZtkrx3t/0dSQGnnXbmdocdetArQoj+4VR23wMP3bj/vnv9Sv/rBmkish09ca655thHSrlWq4TFF1vkNDxsgjiUnPqZnHPABIq47jx7pPMcecShfz7x1DO7D6eit99576X1113nVd8rqLGAuDaNitJonTGIqHgQGQjDsJglMrUH5iDSEQbRa6y2yrNvv/PuWVmV/PTzLz8steTit1B9FtGJeZrJksmWdBzBMcami4xUkaY1A1Qe94WIaPGBApJhaERrLrXkElf8+NPPz6YMLs1DDjn0Wn9PnI/UiQadM4jNEkhzVsEGE8nIHESM1j5/KqRX+/IEiOQ/yifNBlEkpnb00cccesbpp13T3983H88/48xzrrvm6it/8U5JXgX5G6nSvSq1R5LATR7aYGkwMG1RSwkWABH+4jUb3vT/uJ1Z0xpjraTBRltrxUQhksIRmgTJyy69+Pv99tv3qYX6FxgU+fU33352xGEHf5wisU7nNWJpZRMkAjZ6aIN1mwV7h29Jo2wCHlveu/GV169z65E+T6koexCh6c+EEiky3lnxQKFjUeVyOeI5AOBzIiayRhJryd7YYnkIHgvB0qk9Tdql6N3XH4bRUIOIIIKJSiRb0hkSEpZKRd1CpEq8GxtIyCVmDSgFl94GacTgaJw1rUlYhYng0c4ewaUsmKRIJjpiqMSOCh9QeI+UYECmtQIsxEu6OorEcv6Rl0gu0woh8MhFkmSCTXVI4pC704WCFRJvSRNJSzrMMEZO2iKZTCHAZYnmvXCny7ed5vfZK3viHSBdIFCKEFj2+nt+73nw8m2uedcLJlktA++VNMEPaR45aYukcKnnCfY3/DFbZS8t7eHxNgsPM0N1hXhJJwwM1QbpoQFlog2R13a/zBxEYHAQEUYUM6qiVwEyBYoM6JFNF2kFLelI5KQf+fVI4dJFCguDS7oAyx2R6SFQJKRedSDj/cMg/RXQ6ZE05GSIDAaXdCi1I3L021SQWNJ1RLY5OiIdL4/yvuw8ADfWPFrSciaMyH8tEQPwf1uGG54g5+KlJGTmsrxsQdl5PKidnPFe2QS///7Hu+VS6WX/HYnf0sevGL7lXydwod2/9DykZq0s5yff0sgSWCigNOH7TPHL7ufj+/TH8P/+qYpL4HkBDiRYpEXeM8/89/9zzjn7EtY64dfd1nqccM7Bs8+9MKy8555/8TnKS+5MufH6EZVASkgPzf+mJXroet17JirU0ALST3nT0y5ONyLpeo1y64ih+vuQfsoTOeRFSJXa+SvyB90TUmdw49EjLaKpMQ0mzEeTzkWsd/oI6fzfiKM8gWg6X6OjpXstu5ZHnmIb0GFiu29MIUfUewkmVrEN3RqVQ/bY8FzNcquMBv/pCNUZ5pHHem01KdN/I/DG66/lLhKSvTO5M84kav5C5z2ZfyAivi9i9VGd45RH7UWJbjwGG/7NYsRECt7jiOToHedKAui8SW4CsxyRc54mKH/8f7ELhCCACyNcIl/wI+FaAJyc8yzRtinQPzWzuFZrFHq/AAAAAElFTkSuQmCC); background-image: url(data:image/png;base64,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);
background-size: 33px auto; background-size: 33px auto;
} }
.OT_video-disabled-indicator.OT_active { .OT_video-disabled-indicator.OT_active {
display: block; display: block;
} }
.OT_audio-blocked-indicator { .OT_audio-blocked-indicator {
opacity: 1; opacity: 1;
border: none; border: none;
display: none; display: none;
@ -745,30 +750,30 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
} }
.OT_audio-blocked { .OT_audio-blocked {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjkwIj48ZGVmcz48cGF0aCBkPSJNNjcgMTJMNi40NDggNzIuNTUyIDAgMzFWMThMMjYgMGw0MSAxMnptMyA3bDYgNDctMjkgMTgtMzUuNTAyLTYuNDk4TDcwIDE5eiIgaWQ9ImEiLz48L2RlZnM+PHJlY3Qgd2lkdGg9IjE1MCIgaGVpZ2h0PSI5MCIgcng9IjM1IiByeT0iNDUiIG9wYWNpdHk9Ii41Ii8+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNikiPjxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj48dXNlIHhsaW5rOmhyZWY9IiNhIi8+PC9tYXNrPjxwYXRoIGQ9Ik0zOS4yNDkgNTEuMzEyYy42OTcgMTAuMzcgMi43ODUgMTcuODk3IDUuMjUxIDE3Ljg5NyAzLjAzOCAwIDUuNS0xMS40MTcgNS41LTI1LjVzLTIuNDYyLTI1LjUtNS41LTI1LjVjLTIuNTEgMC00LjYyOCA3Ljc5Ny01LjI4NyAxOC40NTNBOC45ODkgOC45ODkgMCAwIDEgNDMgNDRhOC45ODggOC45ODggMCAwIDEtMy43NTEgNy4zMTJ6TTIwLjk4NSAzMi4yMjRsMTUuNzQ2LTE2Ljg3N2E3LjM4NSA3LjM4NSAwIDAgMSAxMC4zNzQtLjQyQzUxLjcwMiAxOS4xMTQgNTQgMjkuMjA4IDU0IDQ1LjIwOGMwIDE0LjUyNy0yLjM0MyAyMy44OC03LjAzIDI4LjA1OGE3LjI4IDcuMjggMCAwIDEtMTAuMTY4LS40NjhMMjAuNDA1IDU1LjIyNEgxMmE1IDUgMCAwIDEtNS01di0xM2E1IDUgMCAwIDEgNS01aDguOTg1eiIgZmlsbD0iI0ZGRiIgbWFzaz0idXJsKCNiKSIvPjwvZz48cGF0aCBkPSJNMTA2LjUgMTMuNUw0NC45OTggNzUuMDAyIiBzdHJva2U9IiNGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9nPjwvc3ZnPg==); background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTUwIiBoZWlnaHQ9IjkwIj48ZGVmcz48cGF0aCBkPSJNNjcgMTJMNi40NDggNzIuNTUyIDAgMzFWMThMMjYgMGw0MSAxMnptMyA3bDYgNDctMjkgMTgtMzUuNTAyLTYuNDk4TDcwIDE5eiIgaWQ9ImEiLz48L2RlZnM+PHJlY3Qgd2lkdGg9IjE1MCIgaGVpZ2h0PSI5MCIgcng9IjM1IiByeT0iNDUiIG9wYWNpdHk9Ii41Ii8+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNikiPjxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj48dXNlIHhsaW5rOmhyZWY9IiNhIi8+PC9tYXNrPjxwYXRoIGQ9Ik0zOS4yNDkgNTEuMzEyYy42OTcgMTAuMzcgMi43ODUgMTcuODk3IDUuMjUxIDE3Ljg5NyAzLjAzOCAwIDUuNS0xMS40MTcgNS41LTI1LjVzLTIuNDYyLTI1LjUtNS41LTI1LjVjLTIuNTEgMC00LjYyOCA3Ljc5Ny01LjI4NyAxOC40NTNBOC45ODkgOC45ODkgMCAwIDEgNDMgNDRhOC45ODggOC45ODggMCAwIDEtMy43NTEgNy4zMTJ6TTIwLjk4NSAzMi4yMjRsMTUuNzQ2LTE2Ljg3N2E3LjM4NSA3LjM4NSAwIDAgMSAxMC4zNzQtLjQyQzUxLjcwMiAxOS4xMTQgNTQgMjkuMjA4IDU0IDQ1LjIwOGMwIDE0LjUyNy0yLjM0MyAyMy44OC03LjAzIDI4LjA1OGE3LjI4IDcuMjggMCAwIDEtMTAuMTY4LS40NjhMMjAuNDA1IDU1LjIyNEgxMmE1IDUgMCAwIDEtNS01di0xM2E1IDUgMCAwIDEgNS01aDguOTg1eiIgZmlsbD0iI0ZGRiIgbWFzaz0idXJsKCNiKSIvPjwvZz48cGF0aCBkPSJNMTA2LjUgMTMuNUw0NC45OTggNzUuMDAyIiBzdHJva2U9IiNGRkYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9nPjwvc3ZnPg==);
background-size: 90px auto; background-size: 90px auto;
} }
.OT_container-audio-blocked { .OT_container-audio-blocked {
cursor: pointer; cursor: pointer;
} }
.OT_container-audio-blocked.OT_mini .OT_edge-bar-item { .OT_container-audio-blocked.OT_mini .OT_edge-bar-item {
display: none; display: none;
} }
.OT_container-audio-blocked .OT_mute { .OT_container-audio-blocked .OT_mute {
display: none; display: none;
} }
.OT_audio-blocked-indicator.OT_active { .OT_audio-blocked-indicator.OT_active {
display: block; display: block;
} }
.OT_video-unsupported { .OT_video-unsupported {
opacity: 1; opacity: 1;
border: none; border: none;
display: none; display: none;
@ -784,9 +789,9 @@
bottom: 0; bottom: 0;
right: 0; right: 0;
margin-top: -30px; margin-top: -30px;
} }
.OT_video-unsupported-bar { .OT_video-unsupported-bar {
display: none; display: none;
position: absolute; position: absolute;
width: 192%; /* copy the size of the audio meter bar for symmetry */ width: 192%; /* copy the size of the audio meter bar for symmetry */
@ -796,9 +801,9 @@
border-radius: 50%; border-radius: 50%;
background-color: rgba(0, 0, 0, 0.8); background-color: rgba(0, 0, 0, 0.8);
} }
.OT_video-unsupported-img { .OT_video-unsupported-img {
display: none; display: none;
position: absolute; position: absolute;
top: 11%; top: 11%;
@ -809,16 +814,16 @@
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center; background-position: center;
background-size: 100% auto; background-size: 100% auto;
} }
.OT_video-unsupported-img:before { .OT_video-unsupported-img:before {
/* makes the height of the container 93% of its width (90/97 px) */ /* makes the height of the container 93% of its width (90/97 px) */
content: ''; content: '';
display: block; display: block;
padding-top: 93%; padding-top: 93%;
} }
.OT_video-unsupported-text { .OT_video-unsupported-text {
display: -webkit-box; display: -webkit-box;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
@ -831,4 +836,4 @@
text-align: center; text-align: center;
height: 100%; height: 100%;
margin-top: 40px; margin-top: 40px;
} }

View File

@ -1,9 +1,6 @@
<div id="layout" class="layout"> <div class="container" [class.withSubtitles]="subtitlesEnabled">
<div <div id="layout" class="layout">
class="OT_root OT_publisher" <div class="OT_root OT_publisher" *ngFor="let stream of localParticipant | streams" [ngClass]="{ OV_big: stream.videoEnlarged }">
*ngFor="let stream of localParticipant | streams"
[ngClass]="{ OV_big: stream.videoEnlarged }"
>
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container> <ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
</div> </div>
@ -15,4 +12,7 @@
> >
<ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container> <ng-container *ngTemplateOutlet="streamTemplate; context: { $implicit: stream }"></ng-container>
</div> </div>
</div>
<ov-subtitles *ngIf="subtitlesEnabled" class="OV_ignored"></ov-subtitles>
</div> </div>

View File

@ -73,8 +73,14 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
localParticipant: ParticipantAbstractModel; localParticipant: ParticipantAbstractModel;
remoteParticipants: ParticipantAbstractModel[] = []; remoteParticipants: ParticipantAbstractModel[] = [];
protected localParticipantSubs: Subscription; /**
protected remoteParticipantsSubs: Subscription; * @ignore
*/
subtitlesEnabled = true;
private localParticipantSubs: Subscription;
private remoteParticipantsSubs: Subscription;
private subtitlesSubs: Subscription;
/** /**
* @ignore * @ignore
@ -83,10 +89,11 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
ngOnInit(): void { ngOnInit(): void {
this.subscribeToParticipants(); this.subscribeToParticipants();
this.subscribeToSubtitles();
} }
ngAfterViewInit() { ngAfterViewInit() {
let timeout: number = 0; let timeout: number = 100;
this.layoutService.initialize(timeout); this.layoutService.initialize(timeout);
this.layoutService.update(timeout); this.layoutService.update(timeout);
} }
@ -96,9 +103,18 @@ export class LayoutComponent implements OnInit, OnDestroy, AfterViewInit {
this.remoteParticipants = []; this.remoteParticipants = [];
if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe(); if (this.localParticipantSubs) this.localParticipantSubs.unsubscribe();
if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe(); if (this.remoteParticipantsSubs) this.remoteParticipantsSubs.unsubscribe();
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
this.layoutService.clear(); this.layoutService.clear();
} }
private subscribeToSubtitles() {
this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => {
this.subtitlesEnabled = value;
this.cd.markForCheck();
this.layoutService.update();
});
}
private subscribeToParticipants() { private subscribeToParticipants() {
this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => { this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => {
this.localParticipant = p; this.localParticipant = p;

View File

@ -1,4 +1,4 @@
<div class="panel-container" id="background-effects-container" fxLayout="column" fxLayoutAlign="space-evenly none"> <div class="panel-container" id="settings-container" fxLayout="column" fxLayoutAlign="space-evenly none">
<div class="panel-header-container" fxFlex="55px" fxLayoutAlign="start center"> <div class="panel-header-container" fxFlex="55px" fxLayoutAlign="start center">
<h3 class="panel-title">{{ 'PANEL.SETTINGS.TITLE' | translate }}</h3> <h3 class="panel-title">{{ 'PANEL.SETTINGS.TITLE' | translate }}</h3>
<button class="panel-close-button" mat-icon-button matTooltip="{{ 'PANEL.CLOSE' | translate }}" (click)="close()"> <button class="panel-close-button" mat-icon-button matTooltip="{{ 'PANEL.CLOSE' | translate }}" (click)="close()">
@ -8,26 +8,35 @@
<div class="settings-container" fxFlex="100%" fxLayoutAlign="space-evenly none"> <div class="settings-container" fxFlex="100%" fxLayoutAlign="space-evenly none">
<div class="item-menu"> <div class="item-menu">
<mat-selection-list #settings [multiple]="false"> <mat-selection-list (selectionChange)="onSelectionChanged($event)" [multiple]="false">
<mat-list-option class="option" [selected]="true" value="general"> <mat-list-option class="option" id="general-opt" [selected]="selectedOption === settingsOptions.GENERAL" [value]="settingsOptions.GENERAL">
<mat-icon mat-list-icon>manage_accounts</mat-icon> <mat-icon mat-list-icon>manage_accounts</mat-icon>
<div mat-line>{{ 'PANEL.SETTINGS.GENERAL' | translate }}</div> <div mat-line>{{ 'PANEL.SETTINGS.GENERAL' | translate }}</div>
</mat-list-option> </mat-list-option>
<mat-list-option class="option" value="video"> <mat-list-option class="option" id="video-opt" [selected]="selectedOption === settingsOptions.VIDEO" [value]="settingsOptions.VIDEO">
<mat-icon mat-list-icon>videocam</mat-icon> <mat-icon mat-list-icon>videocam</mat-icon>
<div mat-line>{{ 'PANEL.SETTINGS.VIDEO' | translate }}</div> <div mat-line>{{ 'PANEL.SETTINGS.VIDEO' | translate }}</div>
</mat-list-option> </mat-list-option>
<mat-list-option class="option" value="audio"> <mat-list-option class="option" id="audio-opt" [selected]="selectedOption === settingsOptions.AUDIO" [value]="settingsOptions.AUDIO">
<mat-icon mat-list-icon>mic</mat-icon> <mat-icon mat-list-icon>mic</mat-icon>
<div mat-line>{{ 'PANEL.SETTINGS.AUDIO' | translate }}</div> <div mat-line>{{ 'PANEL.SETTINGS.AUDIO' | translate }}</div>
</mat-list-option> </mat-list-option>
<mat-list-option
*ngIf="showSubtitles"
class="option"
[selected]="selectedOption === settingsOptions.SUBTITLES"
[value]="settingsOptions.SUBTITLES"
id="subtitles-opt"
>
<mat-icon mat-list-icon>closed_caption</mat-icon>
<div mat-line>{{ 'PANEL.SETTINGS.SUBTITLE' | translate }}</div>
</mat-list-option>
</mat-selection-list> </mat-selection-list>
</div> </div>
<div class="item-content"> <div class="item-content">
<div *ngIf="settings.selectedOptions.selected[0]?.value === 'general'"> <div *ngIf="selectedOption === settingsOptions.GENERAL">
<ov-nickname-input></ov-nickname-input> <ov-nickname-input></ov-nickname-input>
<mat-list> <mat-list>
<mat-list-item> <mat-list-item>
<mat-icon mat-list-icon>language</mat-icon> <mat-icon mat-list-icon>language</mat-icon>
@ -36,8 +45,9 @@
</mat-list-item> </mat-list-item>
</mat-list> </mat-list>
</div> </div>
<ov-video-devices-select *ngIf="settings.selectedOptions.selected[0]?.value === 'video'"></ov-video-devices-select> <ov-video-devices-select *ngIf="selectedOption === settingsOptions.VIDEO"></ov-video-devices-select>
<ov-audio-devices-select *ngIf="settings.selectedOptions.selected[0]?.value === 'audio'"></ov-audio-devices-select> <ov-audio-devices-select *ngIf="selectedOption === settingsOptions.AUDIO"></ov-audio-devices-select>
<ov-subtitles-settings *ngIf="selectedOption === settingsOptions.SUBTITLES && showSubtitles"></ov-subtitles-settings>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,8 @@
import { Component, HostListener, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { MatOptionSelectionChange } from '@angular/material/core'; import { Subscription } from 'rxjs';
import { PanelType } from '../../../models/panel.model'; import { PanelSettingsOptions, PanelType } from '../../../models/panel.model';
import { PanelService } from '../../../services/panel/panel.service'; import { OpenViduAngularConfigService } from '../../../services/config/openvidu-angular.config.service';
import { PanelEvent, PanelService } from '../../../services/panel/panel.service';
@Component({ @Component({
selector: 'ov-settings-panel', selector: 'ov-settings-panel',
@ -9,12 +10,41 @@ import { PanelService } from '../../../services/panel/panel.service';
styleUrls: ['../panel.component.css', './settings-panel.component.css'] styleUrls: ['../panel.component.css', './settings-panel.component.css']
}) })
export class SettingsPanelComponent implements OnInit { export class SettingsPanelComponent implements OnInit {
settingsOptions: typeof PanelSettingsOptions = PanelSettingsOptions;
selectedOption: PanelSettingsOptions = PanelSettingsOptions.GENERAL;
showSubtitles: boolean = true;
private subtitlesSubs: Subscription;
panelSubscription: Subscription;
constructor(private panelService: PanelService, private libService: OpenViduAngularConfigService) {}
ngOnInit() {
this.subscribeToPanelToggling();
this.subscribeToDirectives();
}
selectedOption: string; ngOnDestroy() {
constructor(private panelService: PanelService) {} if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
ngOnInit() {} }
close() { close() {
this.panelService.togglePanel(PanelType.SETTINGS); this.panelService.togglePanel(PanelType.SETTINGS);
} }
onSelectionChanged(e: any){
this.selectedOption = e.option.value;
}
private subscribeToDirectives() {
this.subtitlesSubs = this.libService.subtitlesButtonObs.subscribe((value: boolean) => {
this.showSubtitles = value;
});
}
private subscribeToPanelToggling() {
this.panelSubscription = this.panelService.panelOpenedObs.subscribe(
(ev: PanelEvent) => {
if (ev.type === PanelType.SETTINGS && !!ev.expand) {
this.selectedOption = ev.expand as PanelSettingsOptions;
}
}
);
}
} }

View File

@ -8,7 +8,7 @@
position: relative; position: relative;
height: calc(100% - 70px); height: calc(100% - 70px);
min-height: calc(100% - 70px); min-height: calc(100% - 70px);
padding-top: 10px; padding-top: 0px;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
} }

View File

@ -0,0 +1,8 @@
::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-bar {
background-color: var(--ov-tertiary-color);
}
::ng-deep .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{
background-color: var(--ov-light-color);
}

View File

@ -0,0 +1,21 @@
<mat-list>
<mat-list-item>
<div mat-line>{{ 'PANEL.SETTINGS.SUBTITLE' | translate }}</div>
<mat-slide-toggle (change)="toggleSubtitles()" [checked]="subtitlesEnabled" [disableRipple]="true"></mat-slide-toggle>
</mat-list-item>
<mat-list-item>
<div mat-line>{{ 'PANEL.SETTINGS.LANGUAGE' | translate }}:</div>
<button mat-flat-button [matMenuTriggerFor]="menu" class="lang-button" [disabled]="true">
<span>{{langSelected}}</span>
<mat-icon>expand_more</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item *ngFor="let lang of languagesAvailable" (click)="onLangSelected(lang)">
<span>{{lang}}</span>
</button>
</mat-menu>
</mat-list-item>
</mat-list>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SubtitlesComponent } from './subtitles.component';
describe('SubtitlesComponent', () => {
let component: SubtitlesComponent;
let fixture: ComponentFixture<SubtitlesComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SubtitlesComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SubtitlesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,40 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { LayoutService } from '../../../services/layout/layout.service';
@Component({
selector: 'ov-subtitles-settings',
templateUrl: './subtitles.component.html',
styleUrls: ['./subtitles.component.css']
})
export class SubtitlesSettingComponent implements OnInit, OnDestroy {
subtitlesEnabled: boolean;
languagesAvailable = [];
subtitlesSubs: Subscription;
langSelected: string = 'English';
constructor(private layoutService: LayoutService) {}
ngOnInit(): void {
this.subscribeToSubtitles();
}
ngOnDestroy() {
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
}
onLangSelected(lang: string){
this.langSelected = lang;
}
toggleSubtitles() {
this.layoutService.toggleSubtitles();
}
private subscribeToSubtitles() {
this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => {
this.subtitlesEnabled = value;
// this.cd.markForCheck();
});
}
}

View File

@ -0,0 +1,44 @@
.subtitles-container {
/* padding: 5px; */
display: flex;
height: 75px;
}
.subtitles-offset {
height: 75px;
width: 115px;
text-align: center;
}
.subtitles-main-container {
flex-grow: 1;
text-align: center;
align-self: center;
}
.subtitles-offset + .subtitles-offset {
margin-left: 2%;
}
#subtitle-settings-btn {
color: var(--ov-text-color);
background-color: var(--ov-secondary-color);
}
#subtitle-settings-icon {
font-size: 15px;
height: 15px;
width: 15px;
padding-right: 5px;
}
#subtitle-text {
color: var(--ov-text-color);
background-color: var(--ov-logo-background-color);
font-size: 18px;
font-family: Arial, Helvetica, sans-serif;
padding: 4.5px;
line-height: 1.6;
word-break: break-word;
}
.small-text {
font-size: 14px !important;
}

View File

@ -0,0 +1,12 @@
<div class="subtitles-container">
<div *ngIf="screenSize !== 'sm' && screenSize !== 'xs' && !settingsPanelOpened" class="subtitles-offset">
<button (click)="onSettingsCliked()" id="subtitle-settings-btn" mat-flat-button>
<mat-icon id="subtitle-settings-icon">settings</mat-icon>
<span>English</span>
</button>
</div>
<div class="subtitles-main-container">
<span id="subtitle-text" [class.small-text]="screenSize === 'xs' ">(Demo preview): {{ subtitleText }}</span>
</div>
<div class="subtitles-offset" *ngIf="screenSize !== 'sm' && screenSize !== 'xs' && !settingsPanelOpened"></div>
</div>

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SubtitlesComponent } from './subtitles.component';
describe('SubtitlesComponent', () => {
let component: SubtitlesComponent;
let fixture: ComponentFixture<SubtitlesComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ SubtitlesComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SubtitlesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,78 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { PanelSettingsOptions, PanelType } from '../../models/panel.model';
import { PanelEvent, PanelService } from '../../services/panel/panel.service';
import { DocumentService } from '../../services/document/document.service';
import { MediaChange } from '@angular/flex-layout';
//TODO: BORRAR
import { LoremIpsum } from 'lorem-ipsum';
/**
* @internal
*/
@Component({
selector: 'ov-subtitles',
templateUrl: './subtitles.component.html',
styleUrls: ['./subtitles.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SubtitlesComponent implements OnInit {
/**
* @ignore
*/
subtitleText: string;
/**
* @ignore
*/
screenSize: string;
/**
* @ignore
*/
settingsPanelOpened: boolean;
private screenSizeSub: Subscription;
private panelTogglingSubscription: Subscription;
interval: NodeJS.Timer;
constructor(private documentService: DocumentService, private panelService: PanelService, private cd: ChangeDetectorRef) {}
ngOnInit(): void {
this.subscribeToScreenSize();
this.subscribeToPanelToggling();
//TODO: Subscribe to openvidu-browser subtitle event
// TODO: REMOVE ------------------
const lorem = new LoremIpsum();
this.interval = setInterval(() => {
this.subtitleText = lorem.generateSentences(1);
this.cd.markForCheck();
}, 3000);
// TODO: REMOVE ------------------
}
ngOnDestroy() {
if (this.screenSizeSub) this.screenSizeSub.unsubscribe();
if(this.panelTogglingSubscription) this.panelTogglingSubscription.unsubscribe();
//TODO: Unsubscribe to openvidu-browser subtitle event
clearInterval(this.interval);
}
onSettingsCliked() {
this.panelService.togglePanel(PanelType.SETTINGS, PanelSettingsOptions.SUBTITLES);
}
private subscribeToPanelToggling() {
this.panelTogglingSubscription = this.panelService.panelOpenedObs.subscribe((ev: PanelEvent) => {
this.settingsPanelOpened = ev.opened;
this.cd.markForCheck();
});
}
private subscribeToScreenSize() {
this.screenSizeSub = this.documentService.screenSizeObs.subscribe((change: MediaChange[]) => {
this.screenSize = change[0].mqAlias;
console.log(this.screenSize);
this.cd.markForCheck();
});
}
}

View File

@ -103,6 +103,19 @@
<span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span> <span>{{ 'TOOLBAR.BACKGROUND' | translate }}</span>
</button> </button>
<!-- Subtitles button -->
<button
*ngIf="!isMinimal && showSubtitlesButton"
[disabled]="isConnectionLost"
mat-menu-item
id="subtitles-btn"
(click)="toggleSubtitles()"
>
<mat-icon>closed_caption</mat-icon>
<span *ngIf="subtitlesEnabled">{{ 'TOOLBAR.DISABLE_SUBTITLES' | translate }}</span>
<span *ngIf="!subtitlesEnabled">{{ 'TOOLBAR.ENABLE_SUBTITLES' | translate }}</span>
</button>
<mat-divider class="divider" *ngIf="!isMinimal && showSettingsButton"></mat-divider> <mat-divider class="divider" *ngIf="!isMinimal && showSettingsButton"></mat-divider>
<!-- Settings button --> <!-- Settings button -->

View File

@ -39,6 +39,7 @@ import { RecordingService } from '../../services/recording/recording.service';
import { RecordingInfo, RecordingStatus } from '../../models/recording.model'; import { RecordingInfo, RecordingStatus } from '../../models/recording.model';
import { TranslateService } from '../../services/translate/translate.service'; import { TranslateService } from '../../services/translate/translate.service';
import { MediaChange } from '@angular/flex-layout'; import { MediaChange } from '@angular/flex-layout';
import { LayoutService } from '../../services/layout/layout.service';
/** /**
* *
@ -303,6 +304,17 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
* @ignore * @ignore
*/ */
showSessionName: boolean = true; showSessionName: boolean = true;
/**
* @ignore
*/
showSubtitlesButton: boolean = true;
/**
* @ignore
*/
subtitlesEnabled: boolean;
/** /**
* @ignore * @ignore
*/ */
@ -350,6 +362,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
private displaySessionNameSub: Subscription; private displaySessionNameSub: Subscription;
private screenSizeSub: Subscription; private screenSizeSub: Subscription;
private settingsButtonSub: Subscription; private settingsButtonSub: Subscription;
private subtitlesSubs: Subscription;
private currentWindowHeight = window.innerHeight; private currentWindowHeight = window.innerHeight;
/** /**
@ -365,6 +378,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
protected oVDevicesService: DeviceService, protected oVDevicesService: DeviceService,
protected actionService: ActionService, protected actionService: ActionService,
protected loggerSrv: LoggerService, protected loggerSrv: LoggerService,
private layoutService: LayoutService,
private cd: ChangeDetectorRef, private cd: ChangeDetectorRef,
private libService: OpenViduAngularConfigService, private libService: OpenViduAngularConfigService,
private platformService: PlatformService, private platformService: PlatformService,
@ -411,6 +425,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.subscribeToChatMessages(); this.subscribeToChatMessages();
this.subscribeToRecordingStatus(); this.subscribeToRecordingStatus();
this.subscribeToScreenSize(); this.subscribeToScreenSize();
this.subscribeToSubtitlesToggling();
} }
ngAfterViewInit() { ngAfterViewInit() {
@ -438,6 +453,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
if (this.recordingSubscription) this.recordingSubscription.unsubscribe(); if (this.recordingSubscription) this.recordingSubscription.unsubscribe();
if (this.screenSizeSub) this.screenSizeSub.unsubscribe(); if (this.screenSizeSub) this.screenSizeSub.unsubscribe();
if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe(); if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe();
if (this.subtitlesSubs) this.subtitlesSubs.unsubscribe();
} }
/** /**
@ -528,6 +544,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.panelService.togglePanel(PanelType.BACKGROUND_EFFECTS); this.panelService.togglePanel(PanelType.BACKGROUND_EFFECTS);
} }
/**
* @ignore
*/
toggleSubtitles() {
this.layoutService.toggleSubtitles();
}
/** /**
* @ignore * @ignore
*/ */
@ -674,6 +697,10 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
this.showSessionName = value; this.showSessionName = value;
this.cd.markForCheck(); this.cd.markForCheck();
}); });
this.subtitlesSubs = this.libService.subtitlesButtonObs.subscribe((value: boolean) => {
this.showSubtitlesButton = value;
this.cd.markForCheck();
});
} }
private subscribeToScreenSize() { private subscribeToScreenSize() {
@ -682,6 +709,13 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
}); });
} }
private subscribeToSubtitlesToggling() {
this.subtitlesSubs = this.layoutService.subtitlesTogglingObs.subscribe((value: boolean) => {
this.subtitlesEnabled = value;
this.cd.markForCheck();
});
}
private checkDisplayMoreOptions() { private checkDisplayMoreOptions() {
this.showMoreOptionsButton = this.showMoreOptionsButton =
this.showFullscreenButton || this.showBackgroundEffectsButton || this.showRecordingButton || this.showSettingsButton; this.showFullscreenButton || this.showBackgroundEffectsButton || this.showRecordingButton || this.showSettingsButton;

View File

@ -20,7 +20,8 @@ import {
ToolbarActivitiesPanelButtonDirective, ToolbarActivitiesPanelButtonDirective,
ToolbarBackgroundEffectsButtonDirective, ToolbarBackgroundEffectsButtonDirective,
ToolbarRecordingButtonDirective, ToolbarRecordingButtonDirective,
ToolbarSettingsButtonDirective ToolbarSettingsButtonDirective,
ToolbarSubtitleButtonDirective
} from './toolbar.directive'; } from './toolbar.directive';
import { import {
AudioMutedDirective, AudioMutedDirective,
@ -41,6 +42,7 @@ import {
ToolbarScreenshareButtonDirective, ToolbarScreenshareButtonDirective,
ToolbarFullscreenButtonDirective, ToolbarFullscreenButtonDirective,
ToolbarBackgroundEffectsButtonDirective, ToolbarBackgroundEffectsButtonDirective,
ToolbarSubtitleButtonDirective,
ToolbarLeaveButtonDirective, ToolbarLeaveButtonDirective,
ToolbarRecordingButtonDirective, ToolbarRecordingButtonDirective,
ToolbarParticipantsPanelButtonDirective, ToolbarParticipantsPanelButtonDirective,
@ -70,6 +72,7 @@ import {
ToolbarScreenshareButtonDirective, ToolbarScreenshareButtonDirective,
ToolbarFullscreenButtonDirective, ToolbarFullscreenButtonDirective,
ToolbarBackgroundEffectsButtonDirective, ToolbarBackgroundEffectsButtonDirective,
ToolbarSubtitleButtonDirective,
ToolbarLeaveButtonDirective, ToolbarLeaveButtonDirective,
ToolbarRecordingButtonDirective, ToolbarRecordingButtonDirective,
ToolbarParticipantsPanelButtonDirective, ToolbarParticipantsPanelButtonDirective,

View File

@ -242,6 +242,65 @@ export class ToolbarBackgroundEffectsButtonDirective implements AfterViewInit, O
} }
} }
/**
* The **subtitleButton** directive allows show/hide the subtitle toolbar button.
*
* Default: `true`
*
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `toolbar` component:
*
* @example
* <ov-videoconference [toolbarSubtitleButton]="false"></ov-videoconference>
*
* \
* And it also can be used in the {@link ToolbarComponent}.
* @example
* <ov-toolbar [subtitleButton]="false"></ov-toolbar>
*/
@Directive({
selector: 'ov-videoconference[toolbarSubtitlesButton], ov-toolbar[subtitlesButton]'
})
export class ToolbarSubtitleButtonDirective implements AfterViewInit, OnDestroy {
/**
* @ignore
*/
@Input() set toolbarSubtitlesButton(value: boolean) {
this.subtitlesButtonValue = value;
this.update(this.subtitlesButtonValue);
}
/**
* @ignore
*/
@Input() set subtitlesButton(value: boolean) {
this.subtitlesButtonValue = value;
this.update(this.subtitlesButtonValue);
}
private subtitlesButtonValue: boolean = true;
/**
* @ignore
*/
constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
ngAfterViewInit() {
this.update(this.subtitlesButtonValue);
}
ngOnDestroy(): void {
this.clear();
}
private clear() {
this.subtitlesButtonValue = true;
this.update(true);
}
private update(value: boolean) {
if (this.libService.subtitlesButton.getValue() !== value) {
this.libService.subtitlesButton.next(value);
}
}
}
/** /**
* The **settingsButton** directive allows show/hide the settings toolbar button. * The **settingsButton** directive allows show/hide the settings toolbar button.
* *

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS":"更多选项", "MORE_OPTIONS":"更多选项",
"FULLSCREEN":"全屏", "FULLSCREEN":"全屏",
"EXIT_FULLSCREEN": "退出全屏", "EXIT_FULLSCREEN": "退出全屏",
"ENABLE_SUBTITLES": "启用字幕",
"DISABLE_SUBTITLES": "禁用字幕",
"BACKGROUND":"背景效果", "BACKGROUND":"背景效果",
"START_RECORDING": "开始录音", "START_RECORDING": "开始录音",
"STOP_RECORDING": "停止录制", "STOP_RECORDING": "停止录制",
@ -70,7 +72,8 @@
"GENERAL": "一般的", "GENERAL": "一般的",
"VIDEO": "视频", "VIDEO": "视频",
"AUDIO": "声音的", "AUDIO": "声音的",
"LANGUAGE": "语" "LANGUAGE": "语",
"SUBTITLE": "字幕"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "背景效果", "TITLE": "背景效果",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "Weitere Optionen", "MORE_OPTIONS": "Weitere Optionen",
"FULLSCREEN": "Vollbild", "FULLSCREEN": "Vollbild",
"EXIT_FULLSCREEN": "Vollbildmodus beenden", "EXIT_FULLSCREEN": "Vollbildmodus beenden",
"ENABLE_SUBTITLES": "Untertitel aktivieren",
"DISABLE_SUBTITLES": "Untertitel deaktivieren",
"BACKGROUND": "Hintergrund-Effekte", "BACKGROUND": "Hintergrund-Effekte",
"START_RECORDING": "Aufzeichnung starten", "START_RECORDING": "Aufzeichnung starten",
"STOP_RECORDING": "Aufzeichnung stoppen", "STOP_RECORDING": "Aufzeichnung stoppen",
@ -70,7 +72,8 @@
"GENERAL": "Allgemein", "GENERAL": "Allgemein",
"VIDEO": "Video", "VIDEO": "Video",
"AUDIO": "Audio", "AUDIO": "Audio",
"LANGUAGE": "Sprache" "LANGUAGE": "Sprache",
"SUBTITLE": "Untertitel"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Hintergrund-Effekte", "TITLE": "Hintergrund-Effekte",

View File

@ -35,6 +35,8 @@
"MORE_OPTIONS": "More options", "MORE_OPTIONS": "More options",
"FULLSCREEN": "Fullscreen", "FULLSCREEN": "Fullscreen",
"EXIT_FULLSCREEN": "Exit fullscreen", "EXIT_FULLSCREEN": "Exit fullscreen",
"ENABLE_SUBTITLES": "Enable subtitles",
"DISABLE_SUBTITLES": "Disable subtitles",
"BACKGROUND": "Background effects", "BACKGROUND": "Background effects",
"START_RECORDING": "Start recording", "START_RECORDING": "Start recording",
"STOP_RECORDING": "Stop recording", "STOP_RECORDING": "Stop recording",
@ -71,7 +73,8 @@
"GENERAL": "General", "GENERAL": "General",
"VIDEO": "Video", "VIDEO": "Video",
"AUDIO": "Audio", "AUDIO": "Audio",
"LANGUAGE": "Language" "LANGUAGE": "Language",
"SUBTITLE": "Subtitles"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Background effects", "TITLE": "Background effects",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "Más opciones", "MORE_OPTIONS": "Más opciones",
"EXIT_FULLSCREEN": "Quitar pantalla completa", "EXIT_FULLSCREEN": "Quitar pantalla completa",
"FULLSCREEN": "Pantalla completa", "FULLSCREEN": "Pantalla completa",
"ENABLE_SUBTITLES": "Activar subtítulos",
"DISABLE_SUBTITLES": "Desactivar subtítulos",
"BACKGROUND": "Efectos de fondo", "BACKGROUND": "Efectos de fondo",
"START_RECORDING": "Iniciar grabación", "START_RECORDING": "Iniciar grabación",
"STOP_RECORDING": "Detener grabación", "STOP_RECORDING": "Detener grabación",
@ -70,7 +72,8 @@
"GENERAL": "General", "GENERAL": "General",
"VIDEO": "Video", "VIDEO": "Video",
"AUDIO": "Audio", "AUDIO": "Audio",
"LANGUAGE": "Idioma" "LANGUAGE": "Idioma",
"SUBTITLE": "Subtítulos"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Efectos de fondo", "TITLE": "Efectos de fondo",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "Plus d'options", "MORE_OPTIONS": "Plus d'options",
"FULLSCREEN": "Plein écran", "FULLSCREEN": "Plein écran",
"EXIT_FULLSCREEN": "Quitter le plein écran", "EXIT_FULLSCREEN": "Quitter le plein écran",
"ENABLE_SUBTITLES": "Activer les sous-titres",
"DISABLE_SUBTITLES": "Désactiver les sous-titres",
"BACKGROUND": "Effets de fond", "BACKGROUND": "Effets de fond",
"START_RECORDING": "démarrer l'enregistrement", "START_RECORDING": "démarrer l'enregistrement",
"STOP_RECORDING": "Arrêter l'enregistrement", "STOP_RECORDING": "Arrêter l'enregistrement",
@ -70,7 +72,8 @@
"GENERAL": "Général", "GENERAL": "Général",
"VIDEO": "Vidéo", "VIDEO": "Vidéo",
"AUDIO": "l'audio", "AUDIO": "l'audio",
"LANGUAGE": "Langue" "LANGUAGE": "Langue",
"SUBTITLE": "Les sous-titres"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Effets de fond", "TITLE": "Effets de fond",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "अधिक विकल्प", "MORE_OPTIONS": "अधिक विकल्प",
"FULLSCREEN": "पूर्ण स्क्रीन", "FULLSCREEN": "पूर्ण स्क्रीन",
"EXIT_FULLSCREEN": "पूर्ण स्क्रीन से बाहर निकलें", "EXIT_FULLSCREEN": "पूर्ण स्क्रीन से बाहर निकलें",
"ENABLE_SUBTITLES": "उपशीर्षक सक्षम करें",
"DISABLE_SUBTITLES": "उपशीर्षक अक्षम करें",
"BACKGROUND": "पृष्ठभूमि प्रभाव", "BACKGROUND": "पृष्ठभूमि प्रभाव",
"START_RECORDING": "रिकॉर्डिंग प्रारंभ करें", "START_RECORDING": "रिकॉर्डिंग प्रारंभ करें",
"STOP_RECORDING": "रिकॉर्डिंग रोकें", "STOP_RECORDING": "रिकॉर्डिंग रोकें",
@ -70,7 +72,8 @@
"GENERAL": "सामान्य", "GENERAL": "सामान्य",
"VIDEO": "वीडियो", "VIDEO": "वीडियो",
"AUDIO": "ऑडियो", "AUDIO": "ऑडियो",
"LANGUAGE": "भाषा" "LANGUAGE": "भाषा",
"SUBTITLE": "उपशीर्षक"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "पृष्ठभूमि प्रभाव", "TITLE": "पृष्ठभूमि प्रभाव",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "Altre opzioni", "MORE_OPTIONS": "Altre opzioni",
"FULLSCREEN": "Schermo intero", "FULLSCREEN": "Schermo intero",
"EXIT_FULLSCREEN": "Esci dallo schermo intero", "EXIT_FULLSCREEN": "Esci dallo schermo intero",
"ENABLE_SUBTITLES": "Abilita i sottotitoli",
"DISABLE_SUBTITLES": "Disabilita i sottotitoli",
"BACKGROUND": "Effetti di sfondo", "BACKGROUND": "Effetti di sfondo",
"START_RECORDING": "Avvia registrazione", "START_RECORDING": "Avvia registrazione",
"STOP_RECORDING": "Interrompi registrazione", "STOP_RECORDING": "Interrompi registrazione",
@ -70,7 +72,8 @@
"GENERAL": "Generale", "GENERAL": "Generale",
"VIDEO": "video", "VIDEO": "video",
"AUDIO": "Audio", "AUDIO": "Audio",
"LANGUAGE":"Lingua" "LANGUAGE":"Lingua",
"SUBTITLE": "Sottotitoli"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Effetti di sfondo", "TITLE": "Effetti di sfondo",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "その他のオプション", "MORE_OPTIONS": "その他のオプション",
"FULLSCREEN": "フルスクリーン", "FULLSCREEN": "フルスクリーン",
"EXIT_FULLSCREEN": "フルスクリーンを終了する", "EXIT_FULLSCREEN": "フルスクリーンを終了する",
"ENABLE_SUBTITLES": "字幕を有効にする",
"DISABLE_SUBTITLES": "字幕を無効にする",
"BACKGROUND": "背景効果", "BACKGROUND": "背景効果",
"START_RECORDING": "録画開始", "START_RECORDING": "録画開始",
"STOP_RECORDING": "録画の停止", "STOP_RECORDING": "録画の停止",
@ -70,7 +72,8 @@
"GENERAL": "全般的", "GENERAL": "全般的",
"VIDEO": "ビデオ", "VIDEO": "ビデオ",
"AUDIO": "オーディオ", "AUDIO": "オーディオ",
"LANGUAGE":"言語" "LANGUAGE":"言語",
"SUBTITLE": "字幕"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "背景効果", "TITLE": "背景効果",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "Meer opties", "MORE_OPTIONS": "Meer opties",
"FULLSCREEN": "Volledig scherm", "FULLSCREEN": "Volledig scherm",
"EXIT_FULLSCREEN": "Volledig scherm verlaten", "EXIT_FULLSCREEN": "Volledig scherm verlaten",
"ENABLE_SUBTITLES": "Ondertiteling inschakelen",
"DISABLE_SUBTITLES": "Ondertiteling uitschakelen",
"BACKGROUND": "Achtergrondeffecten", "BACKGROUND": "Achtergrondeffecten",
"START_RECORDING": "Start opname", "START_RECORDING": "Start opname",
"STOP_RECORDING": "Stop opname", "STOP_RECORDING": "Stop opname",
@ -70,7 +72,8 @@
"GENERAL": "Algemeen", "GENERAL": "Algemeen",
"VIDEO": "Video", "VIDEO": "Video",
"AUDIO": "Audio", "AUDIO": "Audio",
"LANGUAGE":"Taal" "LANGUAGE":"Taal",
"SUBTITLE": "Ondertitels"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Achtergrondeffecten", "TITLE": "Achtergrondeffecten",

View File

@ -34,6 +34,8 @@
"MORE_OPTIONS": "Mais opções", "MORE_OPTIONS": "Mais opções",
"FULLSCREEN": "Tela cheia", "FULLSCREEN": "Tela cheia",
"EXIT_FULLSCREEN": "Sair da tela cheia", "EXIT_FULLSCREEN": "Sair da tela cheia",
"ENABLE_SUBTITLES": "Ativar legendas",
"DISABLE_SUBTITLES": "Desativar legendas",
"BACKGROUND": "Efeitos de fundo", "BACKGROUND": "Efeitos de fundo",
"START_RECORDING": "Iniciar_gravação", "START_RECORDING": "Iniciar_gravação",
"STOP_RECORDING": "Parar de gravar", "STOP_RECORDING": "Parar de gravar",
@ -70,7 +72,8 @@
"GENERAL": "Em geral", "GENERAL": "Em geral",
"VIDEO": "Vídeo", "VIDEO": "Vídeo",
"AUDIO": "Áudio", "AUDIO": "Áudio",
"LANGUAGE":"Linguagem" "LANGUAGE":"Linguagem",
"SUBTITLE": "Legendas"
}, },
"BACKGROUND": { "BACKGROUND": {
"TITLE": "Efeitos de fundo", "TITLE": "Efeitos de fundo",

View File

@ -6,3 +6,10 @@ export enum PanelType {
SETTINGS = 'settings' SETTINGS = 'settings'
} }
export enum PanelSettingsOptions {
GENERAL = 'general',
AUDIO = 'audio',
VIDEO = 'video',
SUBTITLES = 'subtitles'
}

View File

@ -19,6 +19,7 @@ import { MatMenuModule } from '@angular/material/menu';
import { MatListModule } from '@angular/material/list'; import { MatListModule } from '@angular/material/list';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
@ -47,6 +48,7 @@ import { NgModule } from '@angular/core';
MatDividerModule, MatDividerModule,
MatListModule, MatListModule,
MatExpansionModule, MatExpansionModule,
MatSlideToggleModule
] ]
}) })
export class AppMaterialModule { } export class AppMaterialModule { }

View File

@ -58,6 +58,8 @@ import { VideoDevicesComponent } from './components/settings/video-devices/video
import { AudioDevicesComponent } from './components/settings/audio-devices/audio-devices.component'; import { AudioDevicesComponent } from './components/settings/audio-devices/audio-devices.component';
import { NicknameInputComponent } from './components/settings/nickname-input/nickname-input.component'; import { NicknameInputComponent } from './components/settings/nickname-input/nickname-input.component';
import { LangSelectorComponent } from './components/settings/lang-selector/lang-selector.component'; import { LangSelectorComponent } from './components/settings/lang-selector/lang-selector.component';
import { SubtitlesSettingComponent } from './components/settings/subtitles/subtitles.component';
import { SubtitlesComponent } from './components/subtitles/subtitles.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -66,6 +68,7 @@ import { LangSelectorComponent } from './components/settings/lang-selector/lang-
ChatPanelComponent, ChatPanelComponent,
SessionComponent, SessionComponent,
LayoutComponent, LayoutComponent,
SubtitlesComponent,
StreamComponent, StreamComponent,
DialogTemplateComponent, DialogTemplateComponent,
RecordingDialogComponent, RecordingDialogComponent,
@ -87,6 +90,7 @@ import { LangSelectorComponent } from './components/settings/lang-selector/lang-
AudioDevicesComponent, AudioDevicesComponent,
NicknameInputComponent, NicknameInputComponent,
LangSelectorComponent, LangSelectorComponent,
SubtitlesSettingComponent,
BackgroundEffectsPanelComponent, BackgroundEffectsPanelComponent,
SettingsPanelComponent, SettingsPanelComponent,
ActivitiesPanelComponent, ActivitiesPanelComponent,

View File

@ -28,6 +28,9 @@ export class OpenViduAngularConfigService {
fullscreenButton = <BehaviorSubject<boolean>>new BehaviorSubject(true); fullscreenButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
fullscreenButtonObs: Observable<boolean>; fullscreenButtonObs: Observable<boolean>;
subtitlesButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
subtitlesButtonObs: Observable<boolean>;
toolbarSettingsButton = <BehaviorSubject<boolean>>new BehaviorSubject(true); toolbarSettingsButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
toolbarSettingsButtonObs: Observable<boolean>; toolbarSettingsButtonObs: Observable<boolean>;
@ -92,6 +95,7 @@ export class OpenViduAngularConfigService {
this.displayLogoObs = this.displayLogo.asObservable(); this.displayLogoObs = this.displayLogo.asObservable();
this.recordingButtonObs = this.recordingButton.asObservable(); this.recordingButtonObs = this.recordingButton.asObservable();
this.toolbarSettingsButtonObs = this.toolbarSettingsButton.asObservable(); this.toolbarSettingsButtonObs = this.toolbarSettingsButton.asObservable();
this.subtitlesButtonObs = this.subtitlesButton.asObservable();
//Stream observables //Stream observables
this.displayParticipantNameObs = this.displayParticipantName.asObservable(); this.displayParticipantNameObs = this.displayParticipantName.asObservable();
this.displayAudioDetectionObs = this.displayAudioDetection.asObservable(); this.displayAudioDetectionObs = this.displayAudioDetection.asObservable();

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model'; import { LayoutAlignment, LayoutClass, OpenViduLayout, OpenViduLayoutOptions } from '../../models/layout.model';
import { DocumentService } from '../document/document.service'; import { DocumentService } from '../document/document.service';
/** /**
@ -10,13 +10,19 @@ import { DocumentService } from '../document/document.service';
providedIn: 'root' providedIn: 'root'
}) })
export class LayoutService { export class LayoutService {
layoutContainer: HTMLElement | null = null;
layoutWidthObs: Observable<number>; layoutWidthObs: Observable<number>;
private _layoutWidthObs: BehaviorSubject<number> = new BehaviorSubject(0); subtitlesTogglingObs: Observable<boolean>;
private layoutWidth: BehaviorSubject<number> = new BehaviorSubject(0);
private openviduLayout: OpenViduLayout; private openviduLayout: OpenViduLayout;
private openviduLayoutOptions: OpenViduLayoutOptions; private openviduLayoutOptions: OpenViduLayoutOptions;
private subtitlesToggling: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(private documentService: DocumentService) { constructor(private documentService: DocumentService) {
this.layoutWidthObs = this._layoutWidthObs.asObservable(); this.layoutWidthObs = this.layoutWidth.asObservable();
this.subtitlesTogglingObs = this.subtitlesToggling.asObservable();
} }
initialize(timeout: number = null) { initialize(timeout: number = null) {
@ -34,8 +40,10 @@ export class LayoutService {
private _initialize() { private _initialize() {
this.openviduLayout = new OpenViduLayout(); this.openviduLayout = new OpenViduLayout();
this.openviduLayoutOptions = this.getOptions(); this.openviduLayoutOptions = this.getOptions();
const element = document.getElementById('layout'); this.layoutContainer = document.getElementById('layout');
this.openviduLayout.initLayoutContainer(element, this.openviduLayoutOptions); if(this.layoutContainer){
this.openviduLayout.initLayoutContainer(this.layoutContainer, this.openviduLayoutOptions);
}
} }
private getOptions(): OpenViduLayoutOptions { private getOptions(): OpenViduLayoutOptions {
@ -46,20 +54,37 @@ export class LayoutService {
and minRatio and maxRatio are ignored (default false) */, and minRatio and maxRatio are ignored (default false) */,
bigClass: LayoutClass.BIG_ELEMENT, // The class to add to elements that should be sized bigger bigClass: LayoutClass.BIG_ELEMENT, // The class to add to elements that should be sized bigger
smallClass: LayoutClass.SMALL_ELEMENT, smallClass: LayoutClass.SMALL_ELEMENT,
ignoredClass: LayoutClass.IGNORED_ELEMENT,
bigPercentage: 0.8, // The maximum percentage of space the big ones should take up bigPercentage: 0.8, // The maximum percentage of space the big ones should take up
minBigPercentage: 0, // If this is set then it will scale down the big space if there is left over whitespace down to this minimum size
bigFixedRatio: false, // fixedRatio for the big ones bigFixedRatio: false, // fixedRatio for the big ones
bigMaxRatio: 9 / 16, // The narrowest ratio to use for the big elements (default 2x3) bigMaxRatio: 9 / 16, // The narrowest ratio to use for the big elements (default 2x3)
bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9) bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9)
bigFirst: true, // Whether to place the big one in the top left (true) or bottom right bigFirst: true, // Whether to place the big one in the top left (true) or bottom right
animate: true // Whether you want to animate the transitions. Deprecated property, to disable it remove the transaction property on OT_publisher css class animate: true, // Whether you want to animate the transitions. Deprecated property, to disable it remove the transaction property on OT_publisher css class
alignItems: LayoutAlignment.CENTER,
bigAlignItems: LayoutAlignment.CENTER,
smallAlignItems: LayoutAlignment.CENTER,
maxWidth: Infinity, // The maximum width of the elements
maxHeight: Infinity, // The maximum height of the elements
smallMaxWidth: Infinity,
smallMaxHeight: Infinity,
bigMaxWidth: Infinity,
bigMaxHeight: Infinity,
scaleLastRow: true,
bigScaleLastRow: true
}; };
return options; return options;
} }
toggleSubtitles() {
this.subtitlesToggling.next(!this.subtitlesToggling.getValue());
}
update(timeout: number = null) { update(timeout: number = null) {
const updateAux = () => { const updateAux = () => {
if (!!this.openviduLayout) { if (!!this.openviduLayout) {
this.openviduLayout.updateLayout(); this.openviduLayout.updateLayout(this.layoutContainer, this.openviduLayoutOptions);
this.sendLayoutWidthEvent(); this.sendLayoutWidthEvent();
} }
}; };
@ -84,7 +109,7 @@ export class LayoutService {
LayoutClass.SIDENAV_CONTAINER LayoutClass.SIDENAV_CONTAINER
); );
if (sidenavLayoutElement && sidenavLayoutElement.clientWidth) { if (sidenavLayoutElement && sidenavLayoutElement.clientWidth) {
this._layoutWidthObs.next(sidenavLayoutElement.clientWidth); this.layoutWidth.next(sidenavLayoutElement.clientWidth);
} }
} }
} }

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs'; import { BehaviorSubject, Observable } from 'rxjs';
import { ILogger } from '../../models/logger.model'; import { ILogger } from '../../models/logger.model';
import { PanelType } from '../../models/panel.model'; import { PanelSettingsOptions, PanelType } from '../../models/panel.model';
import { LoggerService } from '../logger/logger.service'; import { LoggerService } from '../logger/logger.service';
export interface PanelEvent { export interface PanelEvent {
@ -38,7 +38,7 @@ export class PanelService {
* Open or close the panel type received. Calling this method with the panel opened and the same type panel, will close the panel. * Open or close the panel type received. Calling this method with the panel opened and the same type panel, will close the panel.
* If the type is differente, it will switch to the properly panel. * If the type is differente, it will switch to the properly panel.
*/ */
togglePanel(type: PanelType | string, expand?: string) { togglePanel(type: PanelType | string, expand?: PanelSettingsOptions | string) {
let nextOpenedValue: boolean = false; let nextOpenedValue: boolean = false;
if (this.panelMap.has(type)) { if (this.panelMap.has(type)) {
this.log.d(`Toggling ${type} menu`); this.log.d(`Toggling ${type} menu`);

View File

@ -17,6 +17,7 @@
[toolbarParticipantsPanelButton]="_toolbarParticipantsPanelButton" [toolbarParticipantsPanelButton]="_toolbarParticipantsPanelButton"
[toolbarDisplayLogo]="_toolbarDisplayLogo" [toolbarDisplayLogo]="_toolbarDisplayLogo"
[toolbarDisplaySessionName]="_toolbarDisplaySessionName" [toolbarDisplaySessionName]="_toolbarDisplaySessionName"
[toolbarSubtitlesButton]="_toolbarSubtitlesButton"
[streamDisplayParticipantName]="_streamDisplayParticipantName" [streamDisplayParticipantName]="_streamDisplayParticipantName"
[streamDisplayAudioDetection]="_streamDisplayAudioDetection" [streamDisplayAudioDetection]="_streamDisplayAudioDetection"
[streamSettingsButton]="_streamSettingsButton" [streamSettingsButton]="_streamSettingsButton"

View File

@ -79,6 +79,10 @@ export class OpenviduWebComponentComponent implements OnInit {
* @internal * @internal
*/ */
_toolbarDisplaySessionName: boolean = true; _toolbarDisplaySessionName: boolean = true;
/**
* @internal
*/
_toolbarSubtitlesButton: boolean = true;
/** /**
* @internal * @internal
*/ */
@ -330,6 +334,20 @@ export class OpenviduWebComponentComponent implements OnInit {
@Input() set toolbarDisplaySessionName(value: string | boolean) { @Input() set toolbarDisplaySessionName(value: string | boolean) {
this._toolbarDisplaySessionName = this.castToBoolean(value); this._toolbarDisplaySessionName = this.castToBoolean(value);
} }
/**
* The **toolbarDisplaySessionName** attribute allows show/hide the session name.
*
* Default: `true`
*
* <div class="warn-container">
* <span>WARNING</span>: If you want to use this parameter to OpenVidu Web Component statically, you have to replace the <strong>camelCase</strong> with a <strong>hyphen between words</strong>.</div>
*
* @example
* <openvidu-webcomponent toolbar-display-session-name="false"></openvidu-webcomponent>
*/
@Input() set toolbarSubtitlesButton(value: string | boolean) {
this._toolbarSubtitlesButton = this.castToBoolean(value);
}
/** /**
* The **streamDisplayParticipantName** attribute allows show/hide the participants name in stream component. * The **streamDisplayParticipantName** attribute allows show/hide the participants name in stream component.
* *