ov-components: remove OpenviduWebComponent and related files

master
Carlos Santos 2025-05-21 13:31:26 +02:00
parent 59112b79fa
commit 3139437bfe
19 changed files with 841 additions and 3112 deletions

View File

@ -10,7 +10,4 @@
node_modules node_modules
dist/ dist/
docs/ docs/
openvidu-webcomponent/
coverage/** coverage/**
e2e/webcomponent-app/openvidu-webcomponent-*.css
e2e/webcomponent-app/openvidu-webcomponent-*.js

View File

@ -149,82 +149,6 @@
} }
} }
} }
},
"openvidu-webcomponent": {
"projectType": "application",
"root": "",
"sourceRoot": "src",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
"options": {
"outputPath": {
"base": "dist/openvidu-webcomponent-rc",
"browser": ""
},
"index": "src/index.html",
"polyfills": ["zone.js"],
"tsConfig": "src/app/openvidu-webcomponent/tsconfig.openvidu-webcomponent.json",
"aot": true,
"assets": ["src/favicon.ico"],
"styles": ["src/app/openvidu-webcomponent/openvidu-webcomponent.component.scss"],
"scripts": [],
"browser": "src/app/openvidu-webcomponent/openvidu-webcomponent.main.ts"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "none",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "1mb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
]
},
"testing": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.testing.ts"
}
],
"optimization": true,
"outputHashing": "none",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "1mb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
]
}
}
}
}
} }
}, },
"cli": { "cli": {

View File

@ -1,4 +1,3 @@
export const LAUNCH_MODE = process.env.LAUNCH_MODE || 'DEV'; export const LAUNCH_MODE = process.env.LAUNCH_MODE || 'DEV';
export const OPENVIDU_CALL_SERVER = process.env.OPENVIDU_CALL_SERVER || 'http://localhost:6080';
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000; jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;

View File

@ -47,14 +47,6 @@ const chromeArgumentsWithoutMediaDevicesCI = [
'--deny-permission-prompts' '--deny-permission-prompts'
]; ];
export const WebComponentConfig: BrowserConfig = {
appUrl: 'http://localhost:8080/',
seleniumAddress: LAUNCH_MODE === 'CI' ? 'http://localhost:4444/wd/hub' : '',
browserName: 'chrome',
browserCapabilities: Capabilities.chrome().set('acceptInsecureCerts', true),
browserOptions: new chrome.Options().addArguments(...(LAUNCH_MODE === 'CI' ? chromeArgumentsCI : chromeArguments))
};
export const TestAppConfig: BrowserConfig = { export const TestAppConfig: BrowserConfig = {
appUrl: 'http://localhost:4200/#/call?staticVideos=false', appUrl: 'http://localhost:4200/#/call?staticVideos=false',
seleniumAddress: LAUNCH_MODE === 'CI' ? 'http://localhost:4444/wd/hub' : '', seleniumAddress: LAUNCH_MODE === 'CI' ? 'http://localhost:4444/wd/hub' : '',

View File

@ -1,285 +0,0 @@
import monkeyPatchMediaDevices from './utils/media-devices.js';
var MINIMAL;
var LANG;
var CAPTIONS_LANG;
var CUSTOM_LANG_OPTIONS;
var CUSTOM_CAPTIONS_LANG_OPTIONS;
var PREJOIN;
var VIDEO_ENABLED;
var AUDIO_ENABLED;
var CAMERA_BUTTON;
var MICROPHONE_BUTTON;
var SCREENSHARE_BUTTON;
var FULLSCREEN_BUTTON;
var ACTIVITIES_PANEL_BUTTON;
var RECORDING_BUTTON;
var BROADCASTING_BUTTON;
var CHAT_PANEL_BUTTON;
var DISPLAY_LOGO;
var DISPLAY_ROOM_NAME;
var DISPLAY_PARTICIPANT_NAME;
var DISPLAY_AUDIO_DETECTION;
var VIDEO_CONTROLS;
var LEAVE_BUTTON;
var PARTICIPANT_MUTE_BUTTON;
var PARTICIPANTS_PANEL_BUTTON;
var ACTIVITIES_RECORDING_ACTIVITY;
var ACTIVITIES_BROADCASTING_ACTIVITY;
var TOOLBAR_SETTINGS_BUTTON;
var CAPTIONS_BUTTON;
var ROOM_NAME;
var FAKE_DEVICES;
var FAKE_RECORDINGS;
var PARTICIPANT_NAME;
var OPENVIDU_CALL_SERVER_URL;
document.addEventListener('DOMContentLoaded', () => {
var url = new URL(window.location.href);
OPENVIDU_CALL_SERVER_URL = url.searchParams.get('OPENVIDU_CALL_SERVER_URL') || 'http://localhost:6080';
FAKE_DEVICES = url.searchParams.get('fakeDevices') === null ? false : url.searchParams.get('fakeDevices') === 'true';
FAKE_RECORDINGS = url.searchParams.get('fakeRecordings') === null ? false : url.searchParams.get('fakeRecordings') === 'true';
// Directives
MINIMAL = url.searchParams.get('minimal') === null ? false : url.searchParams.get('minimal') === 'true';
LANG = url.searchParams.get('lang') || 'en';
CUSTOM_LANG_OPTIONS = url.searchParams.get('langOptions') === null ? false : url.searchParams.get('langOptions') === 'true';
// CAPTIONS_LANG = url.searchParams.get('captionsLang') || 'en-US';
// CUSTOM_CAPTIONS_LANG_OPTIONS = url.searchParams.get('captionsLangOptions') === null ? false : url.searchParams.get('captionsLangOptions') === 'true';
PARTICIPANT_NAME =
url.searchParams.get('participantName') === null
? 'TEST_USER' + Math.random().toString(36).substr(2, 9)
: url.searchParams.get('participantName');
PREJOIN = url.searchParams.get('prejoin') === null ? true : url.searchParams.get('prejoin') === 'true';
VIDEO_ENABLED = url.searchParams.get('videoEnabled') === null ? true : url.searchParams.get('videoEnabled') === 'true';
AUDIO_ENABLED = url.searchParams.get('audioEnabled') === null ? true : url.searchParams.get('audioEnabled') === 'true';
CAMERA_BUTTON = url.searchParams.get('cameraBtn') === null ? true : url.searchParams.get('cameraBtn') === 'true';
MICROPHONE_BUTTON = url.searchParams.get('microphoneBtn') === null ? true : url.searchParams.get('microphoneBtn') === 'true';
SCREENSHARE_BUTTON = url.searchParams.get('screenshareBtn') === null ? true : url.searchParams.get('screenshareBtn') === 'true';
RECORDING_BUTTON =
url.searchParams.get('toolbarRecordingButton') === null ? true : url.searchParams.get('toolbarRecordingButton') === 'true';
FULLSCREEN_BUTTON = url.searchParams.get('fullscreenBtn') === null ? true : url.searchParams.get('fullscreenBtn') === 'true';
BROADCASTING_BUTTON =
url.searchParams.get('toolbarBroadcastingButton') === null ? true : url.searchParams.get('toolbarBroadcastingButton') === 'true';
TOOLBAR_SETTINGS_BUTTON =
url.searchParams.get('toolbarSettingsBtn') === null ? true : url.searchParams.get('toolbarSettingsBtn') === 'true';
CAPTIONS_BUTTON = url.searchParams.get('toolbarCaptionsBtn') === null ? true : url.searchParams.get('toolbarCaptionsBtn') === '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';
CHAT_PANEL_BUTTON = url.searchParams.get('chatPanelBtn') === null ? true : url.searchParams.get('chatPanelBtn') === 'true';
PARTICIPANTS_PANEL_BUTTON =
url.searchParams.get('participantsPanelBtn') === null ? true : url.searchParams.get('participantsPanelBtn') === 'true';
ACTIVITIES_BROADCASTING_ACTIVITY =
url.searchParams.get('activitiesPanelBroadcastingActivity') === null
? true
: url.searchParams.get('activitiesPanelBroadcastingActivity') === 'true';
ACTIVITIES_RECORDING_ACTIVITY =
url.searchParams.get('activitiesPanelRecordingActivity') === null
? true
: url.searchParams.get('activitiesPanelRecordingActivity') === 'true';
DISPLAY_LOGO = url.searchParams.get('displayLogo') === null ? true : url.searchParams.get('displayLogo') === 'true';
DISPLAY_ROOM_NAME = url.searchParams.get('displayRoomName') === null ? true : url.searchParams.get('displayRoomName') === 'true';
DISPLAY_PARTICIPANT_NAME =
url.searchParams.get('displayParticipantName') === null ? true : url.searchParams.get('displayParticipantName') === 'true';
DISPLAY_AUDIO_DETECTION =
url.searchParams.get('displayAudioDetection') === null ? true : url.searchParams.get('displayAudioDetection') === 'true';
VIDEO_CONTROLS = url.searchParams.get('videoControls') === null ? true : url.searchParams.get('videoControls') === 'true';
PARTICIPANT_MUTE_BUTTON =
url.searchParams.get('participantMuteBtn') === null ? true : url.searchParams.get('participantMuteBtn') === 'true';
ROOM_NAME = url.searchParams.get('roomName') === null ? `E2ESession${Math.floor(Date.now())}` : url.searchParams.get('roomName');
var webComponent = document.querySelector('openvidu-webcomponent');
webComponent.addEventListener('onTokenRequested', (event) => {
appendElement('onTokenRequested');
console.log('Token ready', event.detail);
joinSession(ROOM_NAME, event.detail);
});
webComponent.addEventListener('onReadyToJoin', (event) => appendElement('onReadyToJoin'));
webComponent.addEventListener('onRoomDisconnected', (event) => appendElement('onRoomDisconnected'));
webComponent.addEventListener('onParticipantLeft', (event) => appendElement('onParticipantLeft'));
webComponent.addEventListener('onVideoEnabledChanged', (event) => appendElement('onVideoEnabledChanged-' + event.detail));
webComponent.addEventListener('onVideoDeviceChanged', (event) => appendElement('onVideoDeviceChanged'));
webComponent.addEventListener('onAudioEnabledChanged', (eSESSIONvent) => appendElement('onAudioEnabledChanged-' + event.detail));
webComponent.addEventListener('onAudioDeviceChanged', (event) => appendElement('onAudioDeviceChanged'));
webComponent.addEventListener('onScreenShareEnabledChanged', (event) => appendElement('onScreenShareEnabledChanged'));
webComponent.addEventListener('onParticipantsPanelStatusChanged', (event) =>
appendElement('onParticipantsPanelStatusChanged-' + event.detail.isOpened)
);
webComponent.addEventListener('onLangChanged', (event) => appendElement('onLangChanged-' + event.detail.lang));
webComponent.addEventListener('onChatPanelStatusChanged', (event) =>
appendElement('onChatPanelStatusChanged-' + event.detail.isOpened)
);
webComponent.addEventListener('onActivitiesPanelStatusChanged', (event) =>
appendElement('onActivitiesPanelStatusChanged-' + event.detail.isOpened)
);
webComponent.addEventListener('onSettingsPanelStatusChanged', (event) =>
appendElement('onSettingsPanelStatusChanged-' + event.detail.isOpened)
);
webComponent.addEventListener('onFullscreenEnabledChanged', (event) => appendElement('onFullscreenEnabledChanged-' + event.detail));
webComponent.addEventListener('onRecordingStartRequested', async (event) => {
appendElement('onRecordingStartRequested-' + event.detail.roomName);
// Can't test the recording
// RECORDING_ID = await startRecording(SESSION_NAME);
});
// Can't test the recording
// webComponent.addEventListener('onRecordingStopRequested', async (event) => {
// appendElement('onRecordingStopRequested-' + event.detail.roomName);
// await stopRecording(RECORDING_ID);
// });
webComponent.addEventListener('onRecordingStopRequested', async (event) => {
appendElement('onRecordingStopRequested-' + event.detail.roomName);
});
// Can't test the recording
// webComponent.addEventListener('onActivitiesPanelStopRecordingClicked', async (event) => {
// appendElement('onActivitiesPanelStopRecordingClicked');
// await stopRecording(RECORDING_ID);
// });
webComponent.addEventListener('onRecordingDeleteRequested', (event) => {
const { roomName, recordingId } = event.detail;
appendElement(`onRecordingDeleteRequested-${roomName}-${recordingId}`);
});
webComponent.addEventListener('onBroadcastingStartRequested', async (event) => {
const { roomName, broadcastUrl } = event.detail;
appendElement(`onBroadcastingStartRequested-${roomName}-${broadcastUrl}`);
});
webComponent.addEventListener('onActivitiesPanelStopBroadcastingClicked', async (event) => {
appendElement('onActivitiesPanelStopBroadcastingClicked');
});
webComponent.addEventListener('onRoomCreated', (event) => {
var room = event.detail;
appendElement('onRoomCreated');
room.on('disconnected', (e) => {
console.log('Room disconnected', e);
appendElement('roomDisconnected');
});
});
webComponent.addEventListener('onParticipantCreated', (event) => {
var participant = event.detail;
appendElement(`${participant.name}-onParticipantCreated`);
});
setWebcomponentAttributes();
});
function setWebcomponentAttributes() {
var webComponent = document.querySelector('openvidu-webcomponent');
webComponent.participantName = PARTICIPANT_NAME;
webComponent.minimal = MINIMAL;
webComponent.lang = LANG;
if (CUSTOM_LANG_OPTIONS) {
webComponent.langOptions = [
{ name: 'Esp', lang: 'es' },
{ name: 'Eng', lang: 'en' }
];
}
// TODO: Uncomment when the captions are implemented
// webComponent.captionsLang = CAPTIONS_LANG;
// if (CUSTOM_CAPTIONS_LANG_OPTIONS) {
// webComponent.captionsLangOptions = [
// { name: 'Esp', lang: 'es-ES' },
// { name: 'Eng', lang: 'en-US' }
// ];
// }
if (FAKE_DEVICES) {
console.warn('Using fake devices');
monkeyPatchMediaDevices();
}
if (FAKE_RECORDINGS) {
console.warn('Using fake recordings');
webComponent.recordingActivityRecordingsList = [{ status: 'ready', filename: 'fakeRecording' }];
}
webComponent.prejoin = PREJOIN;
webComponent.videoEnabled = VIDEO_ENABLED;
webComponent.audioEnabled = AUDIO_ENABLED;
webComponent.toolbarCameraButton = CAMERA_BUTTON;
webComponent.toolbarMicrophoneButton = MICROPHONE_BUTTON;
webComponent.toolbarScreenshareButton = SCREENSHARE_BUTTON;
webComponent.toolbarFullscreenButton = FULLSCREEN_BUTTON;
webComponent.toolbarSettingsButton = TOOLBAR_SETTINGS_BUTTON;
// webComponent.toolbarCaptionsButton = CAPTIONS_BUTTON;
webComponent.toolbarLeaveButton = LEAVE_BUTTON;
webComponent.toolbarRecordingButton = RECORDING_BUTTON;
webComponent.toolbarBroadcastingButton = BROADCASTING_BUTTON;
webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON;
webComponent.toolbarChatPanelButton = CHAT_PANEL_BUTTON;
webComponent.toolbarParticipantsPanelButton = PARTICIPANTS_PANEL_BUTTON;
webComponent.toolbarDisplayLogo = DISPLAY_LOGO;
webComponent.toolbarDisplayRoomName = DISPLAY_ROOM_NAME;
webComponent.streamDisplayParticipantName = DISPLAY_PARTICIPANT_NAME;
webComponent.streamDisplayAudioDetection = DISPLAY_AUDIO_DETECTION;
webComponent.streamVideoControls = VIDEO_CONTROLS;
webComponent.participantPanelItemMuteButton = PARTICIPANT_MUTE_BUTTON;
webComponent.activitiesPanelRecordingActivity = ACTIVITIES_RECORDING_ACTIVITY;
webComponent.activitiesPanelBroadcastingActivity = ACTIVITIES_BROADCASTING_ACTIVITY;
}
function appendElement(id) {
var eventsDiv = document.getElementById('events');
eventsDiv.setAttribute('style', 'position: absolute;');
var element = document.createElement('div');
element.setAttribute('id', id);
element.setAttribute('style', 'height: 1px;');
eventsDiv.appendChild(element);
}
async function joinSession(roomName, participantName) {
var webComponent = document.querySelector('openvidu-webcomponent');
console.log('Joining session', roomName, participantName);
try {
webComponent.token = await getToken(roomName, participantName);
} catch (error) {
webComponent.tokenError = error;
}
}
async function getToken(roomName, participantName) {
try {
const response = await fetch(OPENVIDU_CALL_SERVER_URL + '/call/api/rooms', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
// 'Authorization': 'Basic ' + btoa('OPENVIDUAPP:' + OPENVIDU_SECRET),
},
body: JSON.stringify({
participantName,
roomName
})
});
if (!response.ok) {
throw new Error('Failed to fetch token');
}
const data = await response.json();
return data.token;
} catch (error) {
console.error(error);
throw error;
}
}

View File

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>openvidu-web-component</title>
<script type="module" src="utils/filter-stream.js"></script>
<!-- <script type="module" src="utils/shader-renderer.js"></script> -->
<script type="module" src="utils/media-devices.js"></script>
<script type="module" src="app.js"></script>
<script src="openvidu-webcomponent-dev.js"></script>
<link rel="stylesheet" href="openvidu-webcomponent-dev.css" />
<style>
:root {
--ov-background-color: #303030;
--ov-secondary-action-color: #3e3f3f;
--ov-accent-action-color: #598eff;
--ov-error-color: #eb5144;
--ov-accent-action-color: #ffae35;
--ov-light-color: #e6e6e6;
--ov-secondary-action-color: #3a3d3d;
--ov-text-primary-color: #ffffff;
--ov-text-primary-color: #1d1d1d;
--ov-surface-color: #ffffff;
--ov-toolbar-buttons-radius: 50%;
--ov-leave-button-radius: 10px;
--ov-video-radius: 5px;
--ov-surface-radius: 5px;
}
</style>
</head>
<body>
<div id="events"></div>
<!-- OpenVidu Web Component -->
<openvidu-webcomponent></openvidu-webcomponent>
</body>
</html>

View File

@ -1,30 +0,0 @@
class FilterStream {
constructor(stream, label) {
const videoTrack = stream.getVideoTracks()[0];
const { width, height } = videoTrack.getSettings();
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const video = document.createElement('video');
video.srcObject = new MediaStream([videoTrack]);
video.play();
video.addEventListener('play', () => {
const loop = () => {
if (!video.paused && !video.ended) {
ctx.filter = 'grayscale(100%)';
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, video.videoWidth, video.videoHeight);
setTimeout(loop, 33);
}
};
loop();
});
this.outputStream = canvas.captureStream();
Object.defineProperty(this.outputStream.getVideoTracks()[0], 'label', {
writable: true,
value: label
});
}
}
export { FilterStream };

View File

@ -1,77 +0,0 @@
// Ideally we'd use an editor or import shaders directly from the API.
import { FilterStream } from './filter-stream.js';
export default function monkeyPatchMediaDevices() {
const enumerateDevicesFn = MediaDevices.prototype.enumerateDevices;
const getUserMediaFn = MediaDevices.prototype.getUserMedia;
const getDisplayMediaFn = MediaDevices.prototype.getDisplayMedia;
const fakeVideoDevice = {
deviceId: 'virtual',
groupID: '',
kind: 'videoinput',
label: 'custom_fake_video_1'
};
const fakeAudioDevice = {
deviceId: 'virtual',
groupID: '',
kind: 'audioinput',
label: 'custom_fake_audio_1'
};
const enumerateDevicesMonkeyPatch = async function () {
const res = await enumerateDevicesFn.call(navigator.mediaDevices);
res.push(fakeVideoDevice);
res.push(fakeAudioDevice);
return res;
};
const getUserMediaMonkeyPatch = async function () {
const args = arguments[0];
const { deviceId, advanced, width, height } = args.video;
if (deviceId === 'virtual' || deviceId?.exact === 'virtual') {
const constraints = {
video: {
facingMode: args.facingMode,
advanced,
width,
height
},
audio: false
};
const res = await getUserMediaFn.call(navigator.mediaDevices, constraints);
if (res) {
const filter = new FilterStream(res, fakeVideoDevice.label);
return filter.outputStream;
}
return res;
}
return getUserMediaFn.call(navigator.mediaDevices, ...arguments);
};
const getDisplayMediaMonkeyPatch = async function () {
const { video, audio } = arguments[0];
const screenVideoElement = document.getElementsByClassName('OV_video-element screen-type')[0];
const currentTrackLabel = screenVideoElement?.srcObject?.getVideoTracks()[0]?.label;
const res = await getDisplayMediaFn.call(navigator.mediaDevices, { video, audio });
if (res && currentTrackLabel && currentTrackLabel !== 'custom_fake_screen') {
const filter = new FilterStream(res, 'custom_fake_screen');
return filter.outputStream;
}
return res;
};
MediaDevices.prototype.enumerateDevices = enumerateDevicesMonkeyPatch;
navigator.mediaDevices.enumerateDevices = enumerateDevicesMonkeyPatch;
MediaDevices.prototype.getUserMedia = getUserMediaMonkeyPatch;
navigator.mediaDevices.getUserMedia = getUserMediaMonkeyPatch;
MediaDevices.prototype.getDisplayMedia = getDisplayMediaMonkeyPatch;
navigator.mediaDevices.getDisplayMedia = getDisplayMediaMonkeyPatch;
}

View File

@ -1,180 +0,0 @@
import { Builder, Key, WebDriver } from 'selenium-webdriver';
import { OPENVIDU_CALL_SERVER } from '../config';
import { WebComponentConfig } from '../selenium.conf';
import { OpenViduComponentsPO } from '../utils.po.test';
const url = `${WebComponentConfig.appUrl}?OV_URL=${OPENVIDU_CALL_SERVER}`;
//TODO: Uncomment when captions are implemented
// describe('Testing captions features', () => {
// let browser: WebDriver;
// let utils: OpenViduComponentsPO;
// async function createChromeBrowser(): Promise<WebDriver> {
// return await new Builder()
// .forBrowser(WebComponentConfig.browserName)
// .withCapabilities(WebComponentConfig.browserCapabilities)
// .setChromeOptions(WebComponentConfig.browserOptions)
// .usingServer(WebComponentConfig.seleniumAddress)
// .build();
// }
// beforeEach(async () => {
// browser = await createChromeBrowser();
// utils = new OpenViduComponentsPO(browser);
// });
// afterEach(async () => {
// await browser.quit();
// });
// it('should OPEN the CAPTIONS container', async () => {
// await browser.get(`${url}&prejoin=false`);
// await utils.checkSessionIsPresent();
// // Checking if toolbar is present
// await utils.checkToolbarIsPresent();
// // Open more options menu
// await utils.clickOn('#more-options-btn');
// await browser.sleep(500);
// // Checking if button panel is present
// await utils.waitForElement('#more-options-menu');
// expect(await utils.isPresent('#more-options-menu')).toBeTrue();
// // Checking if captions button is present
// await utils.waitForElement('#captions-btn');
// expect(await utils.isPresent('#captions-btn')).toBeTrue();
// await utils.clickOn('#captions-btn');
// await utils.waitForElement('.captions-container');
// });
// it('should OPEN the SETTINGS panel from captions button', async () => {
// await browser.get(`${url}&prejoin=false`);
// await utils.checkSessionIsPresent();
// // Checking if toolbar is present
// await utils.checkToolbarIsPresent();
// // Open more options menu
// await utils.clickOn('#more-options-btn');
// await browser.sleep(500);
// // Checking if button panel is present
// await utils.waitForElement('#more-options-menu');
// expect(await utils.isPresent('#more-options-menu')).toBeTrue();
// // Checking if captions button is present
// await utils.waitForElement('#captions-btn');
// expect(await utils.isPresent('#captions-btn')).toBeTrue();
// await utils.clickOn('#captions-btn');
// await utils.waitForElement('.captions-container');
// await utils.waitForElement('#caption-settings-btn');
// await utils.clickOn('#caption-settings-btn');
// await browser.sleep(500);
// await utils.waitForElement('.settings-container');
// expect(await utils.isPresent('.settings-container')).toBeTrue();
// await utils.waitForElement('ov-captions-settings');
// // Expect caption button is not present
// expect(await utils.isPresent('#caption-settings-btn')).toBeFalse();
// });
// it('should TOGGLE the CAPTIONS container from settings panel', async () => {
// await browser.get(`${url}&prejoin=false`);
// await utils.checkSessionIsPresent();
// // Checking if toolbar is present
// await utils.checkToolbarIsPresent();
// // Open more options menu
// await utils.clickOn('#more-options-btn');
// await browser.sleep(500);
// // Checking if button panel is present
// await utils.waitForElement('#more-options-menu');
// expect(await utils.isPresent('#more-options-menu')).toBeTrue();
// // Checking if captions button is present
// await utils.waitForElement('#captions-btn');
// expect(await utils.isPresent('#captions-btn')).toBeTrue();
// await utils.clickOn('#captions-btn');
// await utils.waitForElement('.captions-container');
// await utils.waitForElement('#caption-settings-btn');
// await utils.clickOn('#caption-settings-btn');
// await browser.sleep(500);
// await utils.waitForElement('.settings-container');
// expect(await utils.isPresent('.settings-container')).toBeTrue();
// await utils.waitForElement('ov-captions-settings');
// expect(await utils.isPresent('.captions-container')).toBeTrue();
// await utils.clickOn('#captions-toggle-slide');
// expect(await utils.isPresent('.captions-container')).toBeFalse();
// await browser.sleep(200);
// await utils.clickOn('#captions-toggle-slide');
// expect(await utils.isPresent('.captions-container')).toBeTrue();
// });
// it('should change the CAPTIONS language', async () => {
// await browser.get(`${url}&prejoin=false`);
// await utils.checkSessionIsPresent();
// // Checking if toolbar is present
// await utils.checkToolbarIsPresent();
// // Open more options menu
// await utils.clickOn('#more-options-btn');
// await browser.sleep(500);
// // Checking if button panel is present
// await utils.waitForElement('#more-options-menu');
// expect(await utils.isPresent('#more-options-menu')).toBeTrue();
// // Checking if captions button is present
// await utils.waitForElement('#captions-btn');
// expect(await utils.isPresent('#captions-btn')).toBeTrue();
// await utils.clickOn('#captions-btn');
// await utils.waitForElement('.captions-container');
// await utils.waitForElement('#caption-settings-btn');
// await utils.clickOn('#caption-settings-btn');
// await browser.sleep(500);
// await utils.waitForElement('.settings-container');
// expect(await utils.isPresent('.settings-container')).toBeTrue();
// await utils.waitForElement('ov-captions-settings');
// expect(await utils.isPresent('.captions-container')).toBeTrue();
// await utils.clickOn('.lang-button');
// await browser.sleep(500);
// await utils.clickOn('#es-ES');
// await utils.clickOn('.panel-close-button');
// const button = await utils.waitForElement('#caption-settings-btn');
// expect(await button.getText()).toEqual('settingsEspañol');
// });
// });

View File

@ -1,65 +0,0 @@
import fs from 'fs-extra';
import concat from 'concat';
const packageJson = fs.readJSONSync('./package.json');
const VERSION = packageJson.version;
const ovWebcomponentRCPath = './dist/openvidu-webcomponent-rc';
const ovWebcomponentProdPath = './dist/openvidu-webcomponent';
export const buildWebcomponent = async () => {
console.log('Building OpenVidu Web Component (' + VERSION + ')');
const tutorialWcPath = '../../openvidu-tutorials/openvidu-webcomponent/web';
const e2eWcPath = './e2e/webcomponent-app';
try {
await buildElement();
await copyFiles(tutorialWcPath);
await copyFiles(e2eWcPath);
await renameWebComponentTestName(e2eWcPath);
console.log(`OpenVidu Web Component (${VERSION}) built`);
} catch (error) {
console.error(error);
}
};
async function buildElement() {
const files = [`${ovWebcomponentRCPath}/polyfills.js`, /*`${ovWebcomponentRCPath}/runtime.js`,*/ `${ovWebcomponentRCPath}/main.js`];
try {
for (const file of files) {
if (!fs.existsSync(file)) {
console.error(`Error: File ${file} does not exist`);
throw new Error(`Missing required file: ${file}`);
}
}
await fs.ensureDir('./dist/openvidu-webcomponent');
await concat(files, `${ovWebcomponentProdPath}/openvidu-webcomponent-${VERSION}.js`);
await fs.copy(`${ovWebcomponentRCPath}/styles.css`, `${ovWebcomponentProdPath}/openvidu-webcomponent-${VERSION}.css`);
if (fs.existsSync(`${ovWebcomponentRCPath}/assets`)) {
await fs.copy(`${ovWebcomponentRCPath}/assets`, `${ovWebcomponentProdPath}/assets`);
}
} catch (err) {
console.error('Error executing build function in webcomponent-builds.js');
throw err;
}
}
function renameWebComponentTestName(dir) {
fs.renameSync(`${dir}/openvidu-webcomponent-${VERSION}.js`, `${dir}/openvidu-webcomponent-dev.js`);
fs.renameSync(`${dir}/openvidu-webcomponent-${VERSION}.css`, `${dir}/openvidu-webcomponent-dev.css`);
}
async function copyFiles(destination) {
if (fs.existsSync(destination)) {
try {
console.log(`Copying openvidu-webcomponent files from: ${ovWebcomponentProdPath} to: ${destination}`);
await fs.ensureDir(ovWebcomponentProdPath);
await fs.copy(ovWebcomponentProdPath, destination);
} catch (err) {
console.error('Error executing copy function in webcomponent-builds.js');
throw err;
}
}
}
await buildWebcomponent();

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,6 @@
"@angular/cli": "19.2.9", "@angular/cli": "19.2.9",
"@angular/compiler": "19.2.8", "@angular/compiler": "19.2.8",
"@angular/compiler-cli": "19.2.8", "@angular/compiler-cli": "19.2.8",
"@angular/elements": "19.2.8",
"@compodoc/compodoc": "^1.1.25", "@compodoc/compodoc": "^1.1.25",
"@types/jasmine": "^5.1.4", "@types/jasmine": "^5.1.4",
"@types/node": "20.12.14", "@types/node": "20.12.14",
@ -74,7 +73,6 @@
"start-prod": "npx http-server ./dist/openvidu-components-testapp/browser --port 4200", "start-prod": "npx http-server ./dist/openvidu-components-testapp/browser --port 4200",
"start:ssl": "ng serve --ssl --configuration development --host 0.0.0.0 --port 5080", "start:ssl": "ng serve --ssl --configuration development --host 0.0.0.0 --port 5080",
"build": "ng build openvidu-components-testapp --configuration production", "build": "ng build openvidu-components-testapp --configuration production",
"bundle-report": "ng build openvidu-webcomponent --stats-json --configuration production && webpack-bundle-analyzer dist/openvidu-webcomponent/stats.json",
"doc:build": "npx compodoc -c ./projects/openvidu-components-angular/doc/.compodocrc.json", "doc:build": "npx compodoc -c ./projects/openvidu-components-angular/doc/.compodocrc.json",
"doc:generate-directives-tutorials": "node ./projects/openvidu-components-angular/doc/scripts/generate-directive-tutorials.js", "doc:generate-directives-tutorials": "node ./projects/openvidu-components-angular/doc/scripts/generate-directive-tutorials.js",
"doc:generate-directive-tables": "node ./projects/openvidu-components-angular/doc/scripts/generate-directive-tables.js", "doc:generate-directive-tables": "node ./projects/openvidu-components-angular/doc/scripts/generate-directive-tables.js",
@ -98,12 +96,6 @@
"e2e:lib-screensharing": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/screensharing.test.js", "e2e:lib-screensharing": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/screensharing.test.js",
"e2e:lib-stream": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/stream.test.js", "e2e:lib-stream": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/stream.test.js",
"e2e:lib-toolbar": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/toolbar.test.js", "e2e:lib-toolbar": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/toolbar.test.js",
"e2e:webcomponent-all": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/webcomponent-e2e/**/*.test.js",
"e2e:webcomponent-captions": "tsc --project ./e2e && npx jasmine --fail-fast ./e2e/dist/webcomponent-e2e/captions.test.js",
"webcomponent:testing-build": "./node_modules/@angular/cli/bin/ng.js build openvidu-webcomponent --configuration testing && node ./openvidu-webcomponent-build.js",
"webcomponent:build": "./node_modules/@angular/cli/bin/ng.js build openvidu-webcomponent --configuration production && node ./openvidu-webcomponent-build.js",
"webcomponent:serve-testapp": "npx http-server ./e2e/webcomponent-app/",
"simulate:multiparty": "livekit-cli load-test --url ws://localhost:7880 --api-key devkey --api-secret secret --room daily-call --publishers 8 --audio-publishers 8 --identity-prefix Participant --identity publisher", "simulate:multiparty": "livekit-cli load-test --url ws://localhost:7880 --api-key devkey --api-secret secret --room daily-call --publishers 8 --audio-publishers 8 --identity-prefix Participant --identity publisher",
"husky": "cd .. && husky install" "husky": "cd .. && husky install"
}, },

View File

@ -5,8 +5,7 @@
"../src/lib/directives/**/*.ts", "../src/lib/directives/**/*.ts",
"../src/lib/services/**/*.ts", "../src/lib/services/**/*.ts",
"../src/lib/models/**/*.ts", "../src/lib/models/**/*.ts",
"../src/lib/pipes/**/*.ts", "../src/lib/pipes/**/*.ts"
// "../../../src/app/openvidu-webcomponent/**/*.ts",
], ],
"exclude": [ "exclude": [
"src/test.ts", "src/test.ts",

View File

@ -1,57 +0,0 @@
<ov-videoconference
[participantName]="_participantName"
[livekitUrl]="_livekitUrl"
[token]="_token"
[tokenError]="_tokenError"
[minimal]="_minimal"
[lang]="_lang"
[langOptions]="_langOptions"
[prejoin]="_prejoin"
[videoEnabled]="_videoEnabled"
[audioEnabled]="_audioEnabled"
[toolbarCameraButton]="_toolbarCameraButton"
[toolbarMicrophoneButton]="_toolbarMicrophoneButton"
[toolbarScreenshareButton]="_toolbarScreenshareButton"
[toolbarRecordingButton]="_toolbarRecordingButton"
[toolbarBroadcastingButton]="_toolbarBroadcastingButton"
[toolbarFullscreenButton]="_toolbarFullscreenButton"
[toolbarBackgroundEffectsButton]="_toolbarBackgroundEffectsButton"
[toolbarSettingsButton]="_toolbarSettingsButton"
[toolbarLeaveButton]="_toolbarLeaveButton"
[toolbarActivitiesPanelButton]="_toolbarActivitiesPanelButton"
[toolbarChatPanelButton]="_toolbarChatPanelButton"
[toolbarParticipantsPanelButton]="_toolbarParticipantsPanelButton"
[toolbarDisplayLogo]="_toolbarDisplayLogo"
[toolbarDisplayRoomName]="_toolbarDisplayRoomName"
[streamDisplayParticipantName]="_streamDisplayParticipantName"
[streamDisplayAudioDetection]="_streamDisplayAudioDetection"
[streamVideoControls]="_streamVideoControls"
[participantPanelItemMuteButton]="_participantPanelItemMuteButton"
[activitiesPanelRecordingActivity]="_activitiesPanelRecordingActivity"
[activitiesPanelBroadcastingActivity]="_activitiesPanelBroadcastingActivity"
(onRoomCreated)="onRoomCreated.emit($event)"
(onParticipantCreated)="onParticipantCreated.emit($event)"
(onReadyToJoin)="onReadyToJoin.emit()"
(onRoomDisconnected)="onRoomDisconnected.emit($event)"
(onParticipantLeft)="_onParticipantLeft($event)"
(onVideoEnabledChanged)="onVideoEnabledChanged.emit($event)"
(onVideoDeviceChanged)="onVideoDeviceChanged.emit($event)"
(onAudioEnabledChanged)="onAudioEnabledChanged.emit($event)"
(onAudioDeviceChanged)="onAudioDeviceChanged.emit($event)"
(onLangChanged)="onLangChanged.emit($event)"
(onScreenShareEnabledChanged)="onScreenShareEnabledChanged.emit($event)"
(onFullscreenEnabledChanged)="onFullscreenEnabledChanged.emit($event)"
(onSettingsPanelStatusChanged)="onSettingsPanelStatusChanged.emit($event)"
(onParticipantsPanelStatusChanged)="onParticipantsPanelStatusChanged.emit($event)"
(onChatPanelStatusChanged)="onChatPanelStatusChanged.emit($event)"
(onActivitiesPanelStatusChanged)="onActivitiesPanelStatusChanged.emit($event)"
(onTokenRequested)="onTokenRequested.emit($event)"
(onRecordingStartRequested)="onRecordingStartRequested.emit($event)"
(onRecordingStopRequested)="onRecordingStopRequested.emit($event)"
(onRecordingDeleteRequested)="onRecordingDeleteRequested.emit($event)"
(onRecordingDownloadClicked)="onRecordingDownloadClicked.emit($event)"
(onRecordingPlayClicked)="onRecordingPlayClicked.emit($event)"
(onActivitiesPanelDownloadRecordingClicked)="onActivitiesPanelDownloadRecordingClicked.emit($event)"
(onBroadcastingStartRequested)="onBroadcastingStartRequested.emit($event)"
(onBroadcastingStopRequested)="onBroadcastingStopRequested.emit($event)"
></ov-videoconference>

View File

@ -1,59 +0,0 @@
@use '@angular/material' as mat;
@include mat.elevation-classes();
@include mat.app-background();
// Define the theme
$openvidu-theme: mat.define-theme();
html {
// Emit theme-dependent styles for common features used across multiple components.
@include mat.elevation-classes();
@include mat.app-background();
// @include mat.button-theme($theme);
@include mat.all-component-bases($openvidu-theme);
@include mat.all-component-colors($openvidu-theme);
@include mat.all-component-typographies($openvidu-theme);
@include mat.all-component-densities($openvidu-theme);
}
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/materialicons/v129/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
html,
body {
height: 100%;
overflow: hidden;
}
body {
margin: 0;
font-family: 'Roboto', 'RobotoDraft', Helvetica, Arial, sans-serif;
}
#poster-text {
padding: 0px !important;
}
ov-chat-panel .text-info {
margin: 3px auto !important;
}

View File

@ -1,850 +0,0 @@
import { Component, ElementRef, EventEmitter, Input, Output } from '@angular/core';
import { OpenViduService, ParticipantModel, Room, ParticipantLeftEvent } from 'openvidu-components-angular';
// import { CaptionsLangOption } from '../../../projects/openvidu-components-angular/src/lib/models/caption.model';
import { CustomDevice } from '../../../projects/openvidu-components-angular/src/lib/models/device.model';
import {
ActivitiesPanelStatusEvent,
ChatPanelStatusEvent,
ParticipantsPanelStatusEvent,
SettingsPanelStatusEvent
} from '../../../projects/openvidu-components-angular/src/lib/models/panel.model';
import {
RecordingDeleteRequestedEvent,
RecordingDownloadClickedEvent,
RecordingPlayClickedEvent,
RecordingStartRequestedEvent,
RecordingStopRequestedEvent
} from '../../../projects/openvidu-components-angular/src/lib/models/recording.model';
import {
BroadcastingStartRequestedEvent,
BroadcastingStopRequestedEvent
} from '../../../projects/openvidu-components-angular/src/lib/models/broadcasting.model';
import { LangOption } from '../../../projects/openvidu-components-angular/src/lib/models/lang.model';
/**
*
* The **OpenviduWebComponentComponent** serves as a bridge to create and export the **OpenVidu Webcomponent**.
* It acts as an intermediary interface to the web component, it is not part of the Angular library.
*
*/
@Component({
templateUrl: './openvidu-webcomponent.component.html',
standalone: false
})
export class OpenviduWebComponentComponent {
/**
* @internal
*/
_livekitUrl: string;
/**
* @internal
*/
_token: string;
/**
* @internal
*/
_tokenError: string;
/**
* @internal
*/
_minimal: boolean = false;
/**
* @internal
*/
_lang: string = '';
/**
* @internal
*/
_langOptions: LangOption;
/**
* @internal
*/
_captionsLang: string = '';
/**
* @internal
*/
// _captionsLangOptions: CaptionsLangOption;
/**
* @internal
*/
_participantName: string;
/**
* @internal
*/
_prejoin: boolean = true;
/**
* @internal
*/
_videoEnabled: boolean = true;
/**
* @internal
*/
_audioEnabled: boolean = true;
/**
* @internal
*/
_toolbarCameraButton: boolean = true;
/**
* @internal
*/
_toolbarMicrophoneButton: boolean = true;
/**
* @internal
*/
_toolbarScreenshareButton: boolean = true;
/**
* @internal
*/
_toolbarRecordingButton: boolean = true;
/**
* @internal
*/
_toolbarBroadcastingButton: boolean = true;
/**
* @internal
*/
_toolbarFullscreenButton: boolean = true;
/**
* @internal
*/
_toolbarBackgroundEffectsButton: boolean = true;
/**
* @internal
*/
_toolbarSettingsButton: boolean = true;
/**
* @internal
*/
_toolbarLeaveButton: boolean = true;
/**
* @internal
*/
_toolbarChatPanelButton: boolean = true;
/**
* @internal
*/
_toolbarActivitiesPanelButton: boolean = true;
/**
* @internal
*/
_toolbarParticipantsPanelButton: boolean = true;
/**
* @internal
*/
_toolbarDisplayLogo: boolean = true;
/**
* @internal
*/
_toolbarDisplayRoomName: boolean = true;
/**
* @internal
*/
// _toolbarCaptionsButton: boolean = true;
/**
* @internal
*/
_streamDisplayParticipantName: boolean = true;
/**
* @internal
*/
_streamDisplayAudioDetection: boolean = true;
/**
* @internal
*/
_streamVideoControls: boolean = true;
/**
* @internal
*/
_participantPanelItemMuteButton: boolean = true;
/**
* @internal
*/
_activitiesPanelRecordingActivity: boolean = true;
/**
* @internal
*/
_activitiesPanelBroadcastingActivity: boolean = true;
/**
* The **minimal** attribute applies a minimal UI hiding all controls except for cam and mic.
*
* Default: `false`
*
* @example
* <openvidu-webcomponent minimal="true"></openvidu-webcomponent>
*/
@Input() set minimal(value: string | boolean) {
this._minimal = this.castToBoolean(value);
}
/**
* The **lang** attribute sets the default UI language.
*
* Default: `en`
*
* @example
* <openvidu-webcomponent lang="es"></openvidu-webcomponent>
*/
@Input() set lang(value: string) {
this._lang = value;
}
/**
* The **langOptions** directive allows to set the application language options.
* It will override the application languages provided by default.
* This propety is an array of objects which must comply with the {@link LangOption} interface.
*
* It is only available for {@link VideoconferenceComponent}.
*
* Default: ```
* [
* { name: 'English', lang: 'en' },
* { name: 'Español', lang: 'es' },
* { name: 'Deutsch', lang: 'de' },
* { name: 'Français', lang: 'fr' },
* { name: '中国', lang: 'cn' },
* { name: 'हिन्दी', lang: 'hi' },
* { name: 'Italiano', lang: 'it' },
* { name: 'やまと', lang: 'ja' },
* { name: 'Dutch', lang: 'nl' },
* { name: 'Português', lang: 'pt' }
* ]```
*
* Note: If you want to add a new language, you must add a new object with the name and the language code (e.g. `{ name: 'Custom', lang: 'cus' }`)
* and then add the language file in the `assets/lang` folder with the name `cus.json`.
*
*
* @example
* <openvidu-webcomponent captions-lang-options="[{name:'Spanish', lang: 'es-ES'}]"></openvidu-webcomponent>
*/
@Input() set langOptions(value: string | LangOption[]) {
this._langOptions = this.castToArray(value);
}
/**
* The **captionsLang** attribute sets the deafult language that OpenVidu will try to recognise.
*
* It must be a valid [BCP-47](https://tools.ietf.org/html/bcp47) language tag like "en-US" or "es-ES".
*
* Default: `en-US`
*
* @example
* <openvidu-webcomponent captions-lang="es-ES"></openvidu-webcomponent>
*/
// TODO: Uncomment when captions are implemented
// @Input() set captionsLang(value: string) {
// this._captionsLang = value;
// }
/**
* The captionsLangOptions attribute sets the language options for the captions.
* It will override the languages provided by default.
* This propety is an array of objects which must comply with the {@link CaptionsLangOption} interface.
*
* Default: ```
* [
* { name: 'English', lang: 'en-US' },
* { name: 'Español', lang: 'es-ES' },
* { name: 'Deutsch', lang: 'de-DE' },
* { name: 'Français', lang: 'fr-FR' },
* { name: '中国', lang: 'zh-CN' },
* { name: 'हिन्दी', lang: 'hi-IN' },
* { name: 'Italiano', lang: 'it-IT' },
* { name: 'やまと', lang: 'jp-JP' },
* { name: 'Português', lang: 'pt-PT' }
* ]```
*
* @example
* <openvidu-webcomponent captions-lang-options="[{name:'Spanish', lang: 'es-ES'}]"></openvidu-webcomponent>
*/
// TODO: Uncomment when captions are implemented
// @Input() set captionsLangOptions(value: string | CaptionsLangOption[]) {
// this._captionsLangOptions = this.castToArray(value);
// }
/**
* The **participantName** attribute sets the participant name. It can be useful for aplications which doesn't need the prejoin page.
*
* <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 participant-name="MY_NAME"></openvidu-webcomponent>
*/
@Input() set participantName(value: string) {
this._participantName = value;
}
/**
* The **prejoin** attribute allows show/hide the prejoin page for selecting media devices.
*
* Default: `true`
*
* @example
* <openvidu-webcomponent prejoin="false"></openvidu-webcomponent>
*/
@Input() set prejoin(value: string | boolean) {
this._prejoin = this.castToBoolean(value);
}
/**
* The **videoEnabled** attribute allows to join the room with camera enabled or disabled.
*
* 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 video-enabled="false"></openvidu-webcomponent>
*/
@Input() set videoEnabled(value: string | boolean) {
this._videoEnabled = this.castToBoolean(value);
}
/**
* The **audioEnabled** attribute allows to join the room with microphone muted/unmuted.
*
* 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 audio-enabled="false"></openvidu-webcomponent>
*/
@Input() set audioEnabled(value: string | boolean) {
this._audioEnabled = this.castToBoolean(value);
}
/**
* The **toolbarCameraButton** attribute allows show/hide the camera toolbar button.
*
* Default: `true`
*
* @example
* <openvidu-webcomponent toolbar-camera-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarCameraButton(value: string | boolean) {
this._toolbarCameraButton = this.castToBoolean(value);
}
/**
* The **toolbarMicrophoneButton** attribute allows show/hide the microphone toolbar button.
*
* Default: `true`
*
* @example
* <openvidu-webcomponent toolbar-microphone-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarMicrophoneButton(value: string | boolean) {
this._toolbarMicrophoneButton = this.castToBoolean(value);
}
/**
* The **toolbarScreenshareButton** attribute allows show/hide the screenshare toolbar button.
*
* 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-screenshare-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarScreenshareButton(value: string | boolean) {
this._toolbarScreenshareButton = this.castToBoolean(value);
}
/**
* The **toolbarRecordingButton** attribute allows show/hide the start/stop recording toolbar button.
*
* 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-recording-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarRecordingButton(value: string | boolean) {
this._toolbarRecordingButton = this.castToBoolean(value);
}
/**
* The **toolbarBroadcastingButton** attribute allows show/hide the start/stop broadcasting toolbar button.
*
* 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-broadcasting-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarBroadcastingButton(value: string | boolean) {
this._toolbarBroadcastingButton = this.castToBoolean(value);
}
/**
* The **toolbarFullscreenButton** attribute allows show/hide the fullscreen toolbar button.
*
* 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-fullscreen-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarFullscreenButton(value: string | boolean) {
this._toolbarFullscreenButton = this.castToBoolean(value);
}
/**
* The **toolbarBackgroundEffectsButton** attribute allows show/hide the background effects toolbar button.
*
* 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-background-effects-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarBackgroundEffectsButton(value: string | boolean) {
this._toolbarBackgroundEffectsButton = this.castToBoolean(value);
}
/**
* The **toolbarSettingsButton** attribute allows show/hide the settings toolbar button.
*
* 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-settings-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarSettingsButton(value: string | boolean) {
this._toolbarSettingsButton = this.castToBoolean(value);
}
/**
* The **toolbarLeaveButton** attribute allows show/hide the leave toolbar button.
*
* 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-leave-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarLeaveButton(value: string | boolean) {
this._toolbarLeaveButton = this.castToBoolean(value);
}
/**
* The **toolbarChatPanelButton** attribute allows show/hide the chat panel toolbar button.
*
* 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-chat-panel-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarChatPanelButton(value: string | boolean) {
this._toolbarChatPanelButton = this.castToBoolean(value);
}
/**
* The **toolbarActivitiesPanelButton** attribute allows show/hide the activities panel toolbar button.
*
* 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-activities-panel-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarActivitiesPanelButton(value: string | boolean) {
this._toolbarActivitiesPanelButton = this.castToBoolean(value);
}
/**
* The **toolbarParticipantsPanelButton** attribute allows show/hide the participants panel toolbar button.
*
* 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-participants-panel-button="false"></openvidu-webcomponent>
*/
@Input() set toolbarParticipantsPanelButton(value: string | boolean) {
this._toolbarParticipantsPanelButton = this.castToBoolean(value);
}
/**
* The **toolbarDisplayLogo** attribute allows show/hide the branding logo.
*
* 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-logo="false"></openvidu-webcomponent>
*/
@Input() set toolbarDisplayLogo(value: string | boolean) {
this._toolbarDisplayLogo = this.castToBoolean(value);
}
/**
* The **toolbarDisplayRoomName** attribute allows show/hide the room 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-room-name="false"></openvidu-webcomponent>
*/
@Input() set toolbarDisplayRoomName(value: string | boolean) {
this._toolbarDisplayRoomName = this.castToBoolean(value);
}
/**
* The **toolbarCaptionsButton** attribute allows show/hide the captions toolbar button.
*
* 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-captions-button="false"></openvidu-webcomponent>
*/
// TODO: Uncomment when captions are implemented
// @Input() set toolbarCaptionsButton(value: string | boolean) {
// this._toolbarCaptionsButton = this.castToBoolean(value);
// }
/**
* The **streamDisplayParticipantName** attribute allows show/hide the participants name in stream component.
*
* 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 stream-display-participant-name="false"></openvidu-webcomponent>
*/
@Input() set streamDisplayParticipantName(value: string | boolean) {
this._streamDisplayParticipantName = this.castToBoolean(value);
}
/**
* The **streamDisplayAudioDetection** attribute allows show/hide the participants audio detection in stream component.
*
* 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 stream-display-audio-detection="false"></openvidu-webcomponent>
*/
@Input() set streamDisplayAudioDetection(value: string | boolean) {
this._streamDisplayAudioDetection = this.castToBoolean(value);
}
/**
* The **streamVideoControls** attribute allows show/hide the participants video controls in stream component.
*
* 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 stream-video-controls="false"></openvidu-webcomponent>
*/
@Input() set streamVideoControls(value: string | boolean) {
this._streamVideoControls = this.castToBoolean(value);
}
/**
* The **participantPanelItemMuteButton** attribute allows show/hide the muted button in participant panel item component.
*
* 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 participant-panel-item-mute-button="false"></openvidu-webcomponent>
*/
@Input() set participantPanelItemMuteButton(value: string | boolean) {
this._participantPanelItemMuteButton = this.castToBoolean(value);
}
/**
* The **activitiesPanelRecordingActivity** attribute allows show/hide the recording activity in {@link ActivitiesPanelComponent}.
*
* Default: `true`
*
* @example
* <openvidu-webcomponent activity-panel-recording-activity="false"></openvidu-webcomponent>
*/
@Input() set activitiesPanelRecordingActivity(value: string | boolean) {
this._activitiesPanelRecordingActivity = this.castToBoolean(value);
}
/**
* The **activitiesPanelBroadcastingActivity** attribute allows show/hide the broadcasting activity in {@link ActivitiesPanelComponent}.
*
* Default: `true`
*
* @example
* <openvidu-webcomponent activity-panel-broadcasting-activity="false"></openvidu-webcomponent>
*/
@Input() set activitiesPanelBroadcastingActivity(value: string | boolean) {
this._activitiesPanelBroadcastingActivity = this.castToBoolean(value);
}
/**
* Provides event notifications that fire when videconference is ready to received the token.
* This event emits the participant name as data.
*/
@Output() onTokenRequested: EventEmitter<string> = new EventEmitter<string>();
/**
* Provides event notifications that fire when the participant is ready to join to the room. This event is only emitted when the prejoin page has been shown.
*/
@Output() onReadyToJoin: EventEmitter<void> = new EventEmitter<void>();
/**
* This event is emitted when the room connection has been lost and the reconnection process has started.
*/
@Output() onRoomDisconnected: EventEmitter<void> = new EventEmitter<void>();
/**
* This event is emitted when a participant leaves the room.
*/
@Output() onParticipantLeft: EventEmitter<ParticipantLeftEvent> = new EventEmitter<ParticipantLeftEvent>();
/**
* This event is emitted when the video state changes, providing information about if the video is enabled (true) or disabled (false).
*/
@Output() onVideoEnabledChanged = new EventEmitter<boolean>();
/**
* This event is emitted when the selected video device changes, providing information about the new custom device that has been selected.
*/
@Output() onVideoDeviceChanged = new EventEmitter<CustomDevice>();
/**
* This event is emitted when the audio state changes, providing information about if the audio is enabled (true) or disabled (false).
*/
@Output() onAudioEnabledChanged = new EventEmitter<boolean>();
/**
* This event is emitted when the selected audio device changes, providing information about the new custom device that has been selected.
*/
@Output() onAudioDeviceChanged = new EventEmitter<CustomDevice>();
/**
* This event is emitted when the language changes, providing information about the new language that has been selected.
*/
@Output() onLangChanged: EventEmitter<LangOption> = new EventEmitter<LangOption>();
/**
* This event is emitted when the screen share state changes, providing information about if the screen share is enabled (true) or disabled (false).
*/
@Output() onScreenShareEnabledChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
/**
* This event is emitted when the fullscreen state changes, providing information about if the fullscreen is enabled (true) or disabled (false).
*/
@Output() onFullscreenEnabledChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
/**
* This events is emitted when the settings panel status changes.
*/
@Output() onSettingsPanelStatusChanged = new EventEmitter<SettingsPanelStatusEvent>();
/**
* This events is emitted when the participants panel status changes.
*/
@Output() onParticipantsPanelStatusChanged = new EventEmitter<ParticipantsPanelStatusEvent>();
/**
* This events is emitted when the chat panel status changes.
*/
@Output() onChatPanelStatusChanged = new EventEmitter<ChatPanelStatusEvent>();
/**
* This events is emitted when the activities panel status changes.
*/
@Output() onActivitiesPanelStatusChanged = new EventEmitter<ActivitiesPanelStatusEvent>();
/**
* This event is fired when the user clicks on the start recording button.
* It provides the {@link RecordingStartRequestedEvent} payload as event data.
*/
@Output() onRecordingStartRequested: EventEmitter<RecordingStartRequestedEvent> = new EventEmitter<RecordingStartRequestedEvent>();
/**
* Provides event notifications that fire when stop recording button has been clicked.
* It provides the {@link RecordingStopRequestedEvent} payload as event data.
*/
@Output() onRecordingStopRequested: EventEmitter<RecordingStopRequestedEvent> = new EventEmitter<RecordingStopRequestedEvent>();
/**
* Provides event notifications that fire when delete recording button has been clicked.
* It provides the {@link RecordingDeleteRequestedEvent} payload as event data.
*/
@Output() onRecordingDeleteRequested: EventEmitter<RecordingDeleteRequestedEvent> = new EventEmitter<RecordingDeleteRequestedEvent>();
/**
* Provides event notifications that fire when download recording button is clicked.
* It provides the {@link RecordingDownloadClickedEvent} payload as event data.
*/
@Output() onRecordingDownloadClicked: EventEmitter<RecordingDownloadClickedEvent> = new EventEmitter<RecordingDownloadClickedEvent>();
/**
* Provides event notifications that fire when play recording button is clicked.
* It provides the {@link RecordingPlayClickedEvent} payload as event data.
*/
@Output() onRecordingPlayClicked: EventEmitter<RecordingPlayClickedEvent> = new EventEmitter<RecordingPlayClickedEvent>();
/**
* Provides event notifications that fire when download recording button is clicked from {@link ActivitiesPanelComponent}.
* The recording should be downloaded using the REST API.
*/
@Output() onActivitiesPanelDownloadRecordingClicked: EventEmitter<string> = new EventEmitter<string>();
/**
* Provides event notifications that fire when start broadcasting button is clicked.
* It provides the {@link BroadcastingStartRequestedEvent} payload as event data.
*/
@Output() onBroadcastingStartRequested: EventEmitter<BroadcastingStartRequestedEvent> =
new EventEmitter<BroadcastingStartRequestedEvent>();
/**
* Provides event notifications that fire when stop broadcasting button is clicked.
* It provides the {@link BroadcastingStopRequestedEvent} payload as event data.
*/
@Output() onBroadcastingStopRequested: EventEmitter<BroadcastingStopRequestedEvent> =
new EventEmitter<BroadcastingStopRequestedEvent>();
/**
* Provides event notifications that fire when OpenVidu Room is created.
*/
@Output() onRoomCreated: EventEmitter<Room> = new EventEmitter<Room>();
/**
* Provides event notifications that fire when local participant is created.
*/
@Output() onParticipantCreated: EventEmitter<ParticipantModel> = new EventEmitter<ParticipantModel>();
/**
* @internal
*/
success: boolean = false;
/**
* @internal
*/
constructor(
private host: ElementRef,
private openviduService: OpenViduService
) {
this.host.nativeElement.disconnect = this.disconnect.bind(this);
}
/**
* LivekitUrl parameter allows to grant a participant access to a Room.
* This parameter will be use by each participant when connecting to a Room.
*
* @example
* <openvidu-webcomponent livekit-url='http://localhost:1234'></openvidu-webcomponent>
*
*/
@Input('livekitUrl')
set livekitUrl(value: string) {
console.debug('Webcomponent livekit url: ', value);
this._livekitUrl = value;
}
/**
* Token parameter is required to grant a participant access to a Room.
* This OpenVidu token will be use by each participant when connecting to a Room.
*
* @example
* <openvidu-webcomponent token='1234qwerxzc'></openvidu-webcomponent>
*
*/
@Input('token')
set token(value: string) {
console.debug('Webcomponent token: ', value);
if (!value) {
console.error('Token parameter is required');
return;
}
this._token = value;
}
/**
* Use the 'tokenError' input to display an error message in case of issues during token request.
*
* @example
* <openvidu-webcomponent token-error='error'></openvidu-webcomponent>
*
*/
@Input('tokenError')
set tokenError(value: any) {
this._tokenError = value;
}
/**
* @internal
*/
_onParticipantLeft(event: ParticipantLeftEvent) {
this.success = false;
this.onParticipantLeft.emit(event);
}
/**
* Disconnects from the Livekit Room.
*/
disconnect() {
this.openviduService.disconnectRoom();
}
private castToBoolean(value: string | boolean): boolean {
if (typeof value === 'boolean') {
return value;
} else if (typeof value === 'string') {
if (value !== 'true' && value !== 'false') {
throw new Error('Parameter has an incorrect string value.');
}
return value === 'true';
} else {
throw new Error('Parameter has not a valid type. The parameters must to be string or boolean.');
}
}
private castToArray(value: LangOption[] | /* CaptionsLangOption[] |*/ string) {
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (error) {
throw 'Unexpected JSON' + error;
}
} else if (typeof value === 'object' && value.length > 0) {
return value;
} else {
throw new Error(
`Parameter has not a valid type. The parameters must to be string or LangOption Array: [{name:string, lang: string}].`
);
}
}
}

View File

@ -1,19 +0,0 @@
import { OpenviduWebComponentModule } from './openvidu-webcomponent.module';
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from '../../environments/environment';
import 'zone.js';
if (environment.production) {
enableProdMode();
}
/**
*
* @internal
*/
platformBrowserDynamic()
.bootstrapModule(OpenviduWebComponentModule, {
ngZone: 'zone.js' // Especificar explícitamente la zona
})
.catch((err) => console.error('Error bootstrapping webcomponent:', err));

View File

@ -1,29 +0,0 @@
import { APP_BASE_HREF, CommonModule } from '@angular/common';
import { DoBootstrap, Injector, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { OpenviduWebComponentComponent } from './openvidu-webcomponent.component';
import { OpenViduComponentsModule, VideoconferenceComponent } from 'openvidu-components-angular';
import { environment } from '../../environments/environment';
import { createCustomElement } from '@angular/elements';
@NgModule({
declarations: [OpenviduWebComponentComponent],
imports: [CommonModule, BrowserModule, BrowserAnimationsModule, OpenViduComponentsModule.forRoot(environment)],
// exports: [OpenviduWebComponentComponent],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }, VideoconferenceComponent]
})
export class OpenviduWebComponentModule implements DoBootstrap {
constructor(private injector: Injector) {}
ngDoBootstrap(): void {
const elementConstructor = createCustomElement(OpenviduWebComponentComponent, {
injector: this.injector
});
customElements.define('openvidu-webcomponent', elementConstructor);
}
}

View File

@ -1,13 +0,0 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"outDir": "../../../out-tsc/app",
"types": [],
"paths": {
"openvidu-components-angular": ["dist/openvidu-components-angular"]
},
"skipLibCheck": true // Livekit track processors fails with typescript types checking
},
"files": ["./openvidu-webcomponent.main.ts"],
"include": ["src/**/*.d.ts"]
}