mirror of https://github.com/OpenVidu/openvidu.git
openvidu-components: Added streaming activity
- Added streaming activity panel - Added streaming structurals directives - Added streaming attributes directives - Added e2e test - Updated test app openvidu-components: Updated e2e configuration openvidu-components: Skipped pro e2e tests openvidu-components: Allowed streaming for moderators only openvidu-components: Request MODERATOR connection in testapp openvidu-components: Fixed streaming signals openvidu-components: Fixed bug with streaming status openvidu-components: Fixed streaming button on status failed openvidu-components: Refactored activities checks openvidu-components: Forced streaming status to enum value openvidu-components: Added non available error in streaming activity Streaming activity will show paid feature error if the service is not available openvidu-components: Created and exported streaming error type openvidu-components: Updated e2e tests openvidu-components: Updated testapp openvidu-components: Enabled streaming input wehn module is disabled openvidu-components: Updated e2e tests openvidu-components: Updated docs openvidu-components: Moved streaming directive to its component Moved streaming directive to streaming component instead of activities component openvidu-components: Updated testapp openvidu-components: Made streaming service public ci: Send branch name in event dispatch openvidu-components: Updated test apppull/771/head
parent
799e875dd7
commit
ab0cf2a343
|
@ -26,13 +26,14 @@ jobs:
|
|||
GITHUB_TOKEN: ${{ secrets.OPENVIDU_DISPATCH_EVENT_GA }}
|
||||
COMMIT_MESSAGE: ${{ github.event.head_commit.message || 'Manually' }}
|
||||
COMMIT_URL: ${{ github.event.commits[0].url || 'Manually' }}
|
||||
BRANCH_NAME: ${{ github.ref_name }}
|
||||
run: |
|
||||
curl \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
||||
https://api.github.com/repos/OpenVidu/openvidu-call/dispatches \
|
||||
-d '{"event_type":"openvidu-components-angular","client_payload":{"commit-message":"'"$COMMIT_MESSAGE"'","commit-ref":"'"$COMMIT_URL"'"}}'
|
||||
-d '{"event_type":"openvidu-components-angular","client_payload":{"commit-message":"'"$COMMIT_MESSAGE"'","commit-ref":"'"$COMMIT_URL"'", "branch-name":"'"$BRANCH_NAME"'"}}'
|
||||
- name: Build openvidu-browser
|
||||
run: |
|
||||
cd openvidu-browser
|
||||
|
@ -112,6 +113,7 @@ jobs:
|
|||
run: npm run webcomponent:e2e-ci --prefix openvidu-components-angular
|
||||
|
||||
webcomponent_e2e_pro:
|
||||
if: false #Skip PRO test because infra is unstable
|
||||
needs: test_setup
|
||||
name: Webcomponent E2E PRO tests
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
@ -5,7 +5,6 @@ import { AngularConfig } from './selenium.conf';
|
|||
import { OpenViduComponentsPO } from './utils.po.test';
|
||||
|
||||
const url = AngularConfig.appUrl;
|
||||
const TIMEOUT = 30000;
|
||||
|
||||
describe('Testing TOOLBAR STRUCTURAL DIRECTIVES', () => {
|
||||
let browser: WebDriver;
|
||||
|
@ -25,6 +24,7 @@ describe('Testing TOOLBAR STRUCTURAL DIRECTIVES', () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// console.log('data:image/png;base64,' + await browser.takeScreenshot());
|
||||
await browser.quit();
|
||||
});
|
||||
|
||||
|
@ -780,6 +780,7 @@ describe('Testing ATTRIBUTE DIRECTIVES', () => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
// console.log('data:image/png;base64,' + await browser.takeScreenshot());
|
||||
await browser.quit();
|
||||
});
|
||||
|
||||
|
@ -872,10 +873,31 @@ describe('Testing ATTRIBUTE DIRECTIVES', () => {
|
|||
|
||||
await browser.sleep(500);
|
||||
|
||||
// Checking if fullscreen button is not present
|
||||
await utils.waitForElement('.mat-menu-content');
|
||||
|
||||
expect(await utils.isPresent('fullscreen-btn')).to.be.false;
|
||||
// Checking if fullscreen button is not present
|
||||
expect(await utils.isPresent('#fullscreen-btn')).to.be.false;
|
||||
});
|
||||
|
||||
it('should HIDE the STREAMING button', async () => {
|
||||
await browser.get(`${url}`);
|
||||
|
||||
await utils.clickOn('#ovToolbar-checkbox');
|
||||
|
||||
await utils.clickOn('#streamingButton-checkbox');
|
||||
|
||||
await utils.clickOn('#apply-btn');
|
||||
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
// Open more options menu
|
||||
await utils.clickOn('#more-options-btn');
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('.mat-menu-content');
|
||||
|
||||
// Checking if fullscreen button is not present
|
||||
expect(await utils.isPresent('#streaming-btn')).to.be.false;
|
||||
});
|
||||
|
||||
it('should HIDE the LEAVE button', async () => {
|
||||
|
@ -1005,6 +1027,80 @@ describe('Testing ATTRIBUTE DIRECTIVES', () => {
|
|||
|
||||
expect(await utils.isPresent('ov-recording-activity')).to.be.false;
|
||||
});
|
||||
|
||||
it('should HIDE the STREAMING activity', async () => {
|
||||
await browser.get(`${url}`);
|
||||
|
||||
await utils.clickOn('#ovActivitiesPanel-checkbox');
|
||||
|
||||
await utils.clickOn('#streamingActivity-checkbox');
|
||||
|
||||
await utils.clickOn('#apply-btn');
|
||||
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
await utils.clickOn('#activities-panel-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('#custom-activities-panel');
|
||||
|
||||
await utils.waitForElement('ov-recording-activity');
|
||||
|
||||
expect(await utils.isPresent('ov-streaming-activity')).to.be.false;
|
||||
});
|
||||
|
||||
it('should SHOW STARTING STREAMING status', async () => {
|
||||
await browser.get(`${url}`);
|
||||
|
||||
await utils.clickOn('#ovActivitiesPanel-checkbox');
|
||||
|
||||
await utils.clickOn('#streamingInfo-checkbox');
|
||||
|
||||
await utils.clickOn('#apply-btn');
|
||||
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
// Open more options menu
|
||||
await utils.clickOn('#activities-panel-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('#custom-activities-panel');
|
||||
console.log('before');
|
||||
|
||||
const status = await utils.waitForElement('#streaming-status');
|
||||
|
||||
expect(await status.getAttribute('innerText')).equals('STARTED');
|
||||
});
|
||||
|
||||
it('should SHOW STREAMING ERROR', async () => {
|
||||
await browser.get(`${url}`);
|
||||
|
||||
await utils.clickOn('#ovActivitiesPanel-checkbox');
|
||||
|
||||
await utils.clickOn('#streamingError-checkbox');
|
||||
|
||||
await utils.clickOn('#apply-btn');
|
||||
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
await utils.clickOn('#activities-panel-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('#custom-activities-panel');
|
||||
|
||||
const status = await utils.waitForElement('#streaming-status');
|
||||
|
||||
expect(await status.getAttribute('innerText')).equals('FAILED');
|
||||
|
||||
await utils.clickOn('#streaming-activity');
|
||||
await browser.sleep(500);
|
||||
const error = await utils.waitForElement('#streaming-error');
|
||||
expect(await error.getAttribute('innerText')).equals('TEST_ERROR');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Testing EVENTS', () => {
|
||||
|
|
|
@ -12,6 +12,7 @@ interface BrowserConfig {
|
|||
|
||||
const chromeArguments = ['--window-size=1024,768', '--use-fake-ui-for-media-stream', '--use-fake-device-for-media-stream'];
|
||||
const chromeArgumentsCI = [
|
||||
'--window-size=1024,768',
|
||||
'--headless',
|
||||
'--no-sandbox',
|
||||
'--disable-gpu',
|
||||
|
@ -25,9 +26,8 @@ const chromeArgumentsCI = [
|
|||
'--use-fake-device-for-media-stream'
|
||||
];
|
||||
const chromeArgumentsWithoutMediaDevices = ['--window-size=1024,768', '--deny-permission-prompts'];
|
||||
|
||||
|
||||
const chromeArgumentsWithoutMediaDevicesCI = [
|
||||
'--window-size=1024,768',
|
||||
'--headless',
|
||||
'--no-sandbox',
|
||||
'--disable-gpu',
|
||||
|
|
|
@ -10,6 +10,7 @@ var SCREENSHARE_BUTTON;
|
|||
var FULLSCREEN_BUTTON;
|
||||
var ACTIVITIES_PANEL_BUTTON;
|
||||
var RECORDING_BUTTON;
|
||||
var STREAMING_BUTTON;
|
||||
var CHAT_PANEL_BUTTON;
|
||||
var DISPLAY_LOGO;
|
||||
var DISPLAY_SESSION_NAME;
|
||||
|
@ -20,7 +21,9 @@ var LEAVE_BUTTON;
|
|||
var PARTICIPANT_MUTE_BUTTON;
|
||||
var PARTICIPANTS_PANEL_BUTTON;
|
||||
var ACTIVITIES_RECORDING_ACTIVITY;
|
||||
var ACTIVITIES_STREAMING_ACTIVITY;
|
||||
var RECORDING_ERROR;
|
||||
var STREAMING_ERROR;
|
||||
var TOOLBAR_SETTINGS_BUTTON;
|
||||
var CAPTIONS_BUTTON;
|
||||
|
||||
|
@ -29,16 +32,14 @@ var SESSION_NAME;
|
|||
|
||||
var PARTICIPANT_NAME;
|
||||
|
||||
|
||||
var OPENVIDU_SERVER_URL;
|
||||
var OPENVIDU_SECRET;
|
||||
|
||||
$(document).ready(() => {
|
||||
var url = new URL(window.location.href);
|
||||
|
||||
OPENVIDU_SERVER_URL = url.searchParams.get('OV_URL');
|
||||
OPENVIDU_SECRET = url.searchParams.get('OV_SECRET');
|
||||
|
||||
OPENVIDU_SERVER_URL = url.searchParams.get('OV_URL');
|
||||
OPENVIDU_SECRET = url.searchParams.get('OV_SECRET');
|
||||
|
||||
SINGLE_TOKEN = url.searchParams.get('singleToken') === null ? false : url.searchParams.get('singleToken') === 'true';
|
||||
|
||||
|
@ -53,8 +54,16 @@ $(document).ready(() => {
|
|||
VIDEO_MUTED = url.searchParams.get('videoMuted') === null ? false : url.searchParams.get('videoMuted') === 'true';
|
||||
AUDIO_MUTED = url.searchParams.get('audioMuted') === null ? false : url.searchParams.get('audioMuted') === 'true';
|
||||
SCREENSHARE_BUTTON = url.searchParams.get('screenshareBtn') === null ? true : url.searchParams.get('screenshareBtn') === 'true';
|
||||
RECORDING_BUTTON = url.searchParams.get('recordingBtn') === null ? true : url.searchParams.get('recordingBtn') === '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';
|
||||
STREAMING_BUTTON =
|
||||
url.searchParams.get('toolbarStreamingButton') === null ? true : url.searchParams.get('toolbarStreamingButton') === 'true';
|
||||
|
||||
if (url.searchParams.get('streamingError') !== null) {
|
||||
STREAMING_ERROR = url.searchParams.get('streamingError');
|
||||
}
|
||||
|
||||
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';
|
||||
|
@ -65,6 +74,10 @@ $(document).ready(() => {
|
|||
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_STREAMING_ACTIVITY =
|
||||
url.searchParams.get('activitiesPanelStreamingActivity') === null
|
||||
? true
|
||||
: url.searchParams.get('activitiesPanelStreamingActivity') === 'true';
|
||||
ACTIVITIES_RECORDING_ACTIVITY =
|
||||
url.searchParams.get('activitiesPanelRecordingActivity') === null
|
||||
? true
|
||||
|
@ -114,6 +127,11 @@ $(document).ready(() => {
|
|||
// await stopRecording(RECORDING_ID);
|
||||
// });
|
||||
|
||||
webComponent.addEventListener('onToolbarStopStreamingClicked', async (event) => {
|
||||
appendElement('onToolbarStopStreamingClicked');
|
||||
webComponent.streamingActivityStreamingInfo = { status: 'stopped', id: '01' };
|
||||
});
|
||||
|
||||
webComponent.addEventListener('onActivitiesPanelStartRecordingClicked', async (event) => {
|
||||
appendElement('onActivitiesPanelStartRecordingClicked');
|
||||
// RECORDING_ID = await startRecording(SESSION_NAME);
|
||||
|
@ -129,6 +147,16 @@ $(document).ready(() => {
|
|||
appendElement('onActivitiesPanelDeleteRecordingClicked')
|
||||
);
|
||||
|
||||
webComponent.addEventListener('onActivitiesPanelStartStreamingClicked', async (event) => {
|
||||
appendElement('onActivitiesPanelStartStreamingClicked');
|
||||
webComponent.streamingActivityStreamingInfo = { status: 'started', id: '01' };
|
||||
});
|
||||
|
||||
webComponent.addEventListener('onActivitiesPanelStopStreamingClicked', async (event) => {
|
||||
appendElement('onActivitiesPanelStopStreamingClicked');
|
||||
webComponent.streamingActivityStreamingInfo = { status: 'stopped', id: '01' };
|
||||
});
|
||||
|
||||
webComponent.addEventListener('onSessionCreated', (event) => {
|
||||
var session = event.detail;
|
||||
appendElement('onSessionCreated');
|
||||
|
@ -192,6 +220,7 @@ async function joinSession(sessionName, participantName) {
|
|||
webComponent.toolbarCaptionsButton = CAPTIONS_BUTTON;
|
||||
webComponent.toolbarLeaveButton = LEAVE_BUTTON;
|
||||
webComponent.toolbarRecordingButton = RECORDING_BUTTON;
|
||||
webComponent.toolbarStreamingButton = STREAMING_BUTTON;
|
||||
webComponent.toolbarActivitiesPanelButton = ACTIVITIES_PANEL_BUTTON;
|
||||
webComponent.toolbarChatPanelButton = CHAT_PANEL_BUTTON;
|
||||
webComponent.toolbarParticipantsPanelButton = PARTICIPANTS_PANEL_BUTTON;
|
||||
|
@ -204,8 +233,11 @@ async function joinSession(sessionName, participantName) {
|
|||
|
||||
webComponent.recordingActivityRecordingsList = [{ status: 'ready' }];
|
||||
webComponent.activitiesPanelRecordingActivity = ACTIVITIES_RECORDING_ACTIVITY;
|
||||
webComponent.activitiesPanelStreamingActivity = ACTIVITIES_STREAMING_ACTIVITY;
|
||||
webComponent.recordingActivityRecordingError = RECORDING_ERROR;
|
||||
|
||||
webComponent.streamingActivityStreamingError = {message: STREAMING_ERROR, rtmpAvailable: true};
|
||||
|
||||
webComponent.participantName = participantName;
|
||||
webComponent.tokens = tokens;
|
||||
}
|
||||
|
@ -222,7 +254,6 @@ async function joinSession(sessionName, participantName) {
|
|||
* 3) Configure OpenVidu Web Component in your client side with the token
|
||||
*/
|
||||
|
||||
|
||||
function getToken(sessionName) {
|
||||
return createSession(sessionName).then((sessionId) => createToken(sessionId));
|
||||
}
|
||||
|
|
|
@ -6,12 +6,6 @@ import { OpenViduComponentsPO } from './utils.po.test';
|
|||
|
||||
const url = `${WebComponentConfig.appUrl}?OV_URL=${OPENVIDU_SERVER_URL}&OV_SECRET=${OPENVIDU_SECRET}`;
|
||||
|
||||
/**
|
||||
*
|
||||
* Testing PRO features with OpenVidu PRO
|
||||
* TODO: Change the openvidu URL when openvidu-pro-dev exists
|
||||
*/
|
||||
|
||||
describe('Testing API Directives', () => {
|
||||
let browser: WebDriver;
|
||||
let utils: OpenViduComponentsPO;
|
||||
|
|
|
@ -110,96 +110,6 @@ describe('Testing API Directives', () => {
|
|||
expect(await element.getText()).equal('Unirme ahora');
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* This test is only available with OpenVidu PRO
|
||||
*/
|
||||
// it('should change the captions LANG ', async () => {
|
||||
// await browser.get(`${url}&prejoin=false&captionsLang=es-ES`);
|
||||
|
||||
// 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('.mat-menu-content');
|
||||
// expect(await utils.isPresent('.mat-menu-content')).to.be.true;
|
||||
|
||||
// // Checking if captions button is present
|
||||
// await utils.waitForElement('#captions-btn');
|
||||
// expect(await utils.isPresent('#captions-btn')).to.be.true;
|
||||
// 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')).to.be.true;
|
||||
|
||||
// await utils.waitForElement('ov-captions-settings');
|
||||
|
||||
// expect(await utils.isPresent('.captions-container')).to.be.true;
|
||||
|
||||
// const element = await utils.waitForElement('.lang-button');
|
||||
// expect(await element.getText()).equal('Españolexpand_more');
|
||||
// });
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* This test is only available with OpenVidu PRO
|
||||
*/
|
||||
// it('should override the CAPTIONS LANG OPTIONS', async () => {
|
||||
// await browser.get(`${url}&prejoin=false&captionsLangOptions=true`);
|
||||
|
||||
// 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('.mat-menu-content');
|
||||
// expect(await utils.isPresent('.mat-menu-content')).to.be.true;
|
||||
|
||||
// // Checking if captions button is present
|
||||
// await utils.waitForElement('#captions-btn');
|
||||
// expect(await utils.isPresent('#captions-btn')).to.be.true;
|
||||
// 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')).to.be.true;
|
||||
|
||||
// await utils.waitForElement('ov-captions-settings');
|
||||
|
||||
// expect(await utils.isPresent('.captions-container')).to.be.true;
|
||||
|
||||
// const element = await utils.waitForElement('.lang-button');
|
||||
// expect(await element.getText()).equal('Espexpand_more');
|
||||
|
||||
// await element.click();
|
||||
|
||||
// expect(await utils.getNumberOfElements('.mat-menu-item')).equals(2);
|
||||
// });
|
||||
|
||||
it('should show the PREJOIN page', async () => {
|
||||
await browser.get(`${url}&prejoin=true`);
|
||||
|
||||
|
@ -376,6 +286,48 @@ describe('Testing API Directives', () => {
|
|||
expect(await utils.isPresent('#captions-opt')).to.be.false;
|
||||
});
|
||||
|
||||
it('should HIDE the TOOLBAR RECORDING button', async () => {
|
||||
await browser.get(`${url}&prejoin=false&toolbarRecordingButton=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('.mat-menu-content');
|
||||
expect(await utils.isPresent('.mat-menu-content')).to.be.true;
|
||||
|
||||
// Checking if recording button is not present
|
||||
expect(await utils.isPresent('#recording-btn')).to.be.false;
|
||||
});
|
||||
|
||||
it('should HIDE the TOOLBAR STREAMING button', async () => {
|
||||
await browser.get(`${url}&prejoin=false&toolbarStreamingButton=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('.mat-menu-content');
|
||||
expect(await utils.isPresent('.mat-menu-content')).to.be.true;
|
||||
|
||||
// Checking if streaming button is not present
|
||||
expect(await utils.isPresent('#streaming-btn')).to.be.false;
|
||||
});
|
||||
|
||||
it('should HIDE the TOOLBAR SETTINGS button', async () => {
|
||||
await browser.get(`${url}&prejoin=false&toolbarSettingsBtn=false`);
|
||||
|
||||
|
@ -617,6 +569,63 @@ describe('Testing API Directives', () => {
|
|||
expect(await element.getAttribute('innerText')).equal('"TEST_ERROR"');
|
||||
expect(await utils.isPresent('.recording-error')).to.be.true;
|
||||
});
|
||||
|
||||
it('should SHOW a STREAMING ERROR in activities panel', async () => {
|
||||
let element;
|
||||
const fixedUrl = `${url}&prejoin=false&streamingError=TEST_ERROR`;
|
||||
await browser.get(fixedUrl);
|
||||
|
||||
await utils.checkSessionIsPresent();
|
||||
|
||||
// Checking if toolbar is present
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
element = await utils.waitForElement('#activities-panel-btn');
|
||||
await element.click();
|
||||
|
||||
// Checking if participatns panel is displayed
|
||||
await utils.waitForElement('#default-activities-panel');
|
||||
expect(await utils.isPresent('#default-activities-panel')).to.be.true;
|
||||
|
||||
// Checking if streaming activity exists
|
||||
await utils.waitForElement('#activities-container');
|
||||
await utils.waitForElement('.activities-body-container');
|
||||
|
||||
await utils.waitForElement('ov-streaming-activity');
|
||||
expect(await utils.isPresent('ov-streaming-activity')).to.be.true;
|
||||
|
||||
const status = await utils.waitForElement('#streaming-status');
|
||||
expect(await status.getAttribute('innerText')).equals('FAILED');
|
||||
|
||||
// Open streaming
|
||||
await browser.sleep(1000);
|
||||
await utils.clickOn('ov-streaming-activity');
|
||||
|
||||
element = await utils.waitForElement('#streaming-error');
|
||||
expect(await element.getAttribute('innerText')).equal('TEST_ERROR');
|
||||
});
|
||||
|
||||
it('should HIDE the STREAMING ACTIVITY in activities panel', async () => {
|
||||
await browser.get(`${url}&prejoin=false&activitiesPanelStreamingActivity=false`);
|
||||
|
||||
await utils.checkSessionIsPresent();
|
||||
|
||||
// Checking if toolbar is present
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
await utils.waitForElement('#activities-panel-btn');
|
||||
await utils.clickOn('#activities-panel-btn')
|
||||
|
||||
// Checking if participatns panel is displayed
|
||||
await utils.waitForElement('#default-activities-panel');
|
||||
expect(await utils.isPresent('#default-activities-panel')).to.be.true;
|
||||
|
||||
// await browser.sleep(1000);
|
||||
|
||||
// Checking if recording activity exists
|
||||
await utils.waitForElement('.activities-body-container');
|
||||
expect(await utils.isPresent('ov-streaming-activity')).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('Testing videoconference EVENTS', () => {
|
||||
|
@ -647,10 +656,8 @@ describe('Testing videoconference EVENTS', () => {
|
|||
expect(await utils.isPresent('#prejoin-container')).to.be.true;
|
||||
|
||||
// Clicking to join button
|
||||
const joinButton = await utils.waitForElement('#join-button');
|
||||
expect(await utils.isPresent('#join-button')).to.be.true;
|
||||
expect(await joinButton.isEnabled()).to.be.true;
|
||||
await joinButton.click();
|
||||
await utils.waitForElement('#join-button');
|
||||
await utils.clickOn('#join-button');
|
||||
|
||||
// Checking if onJoinButtonClicked has been received
|
||||
await utils.waitForElement('#onJoinButtonClicked');
|
||||
|
@ -799,32 +806,75 @@ describe('Testing videoconference EVENTS', () => {
|
|||
});
|
||||
|
||||
it('should receive the onToolbarStartRecordingClicked event', async () => {
|
||||
let element;
|
||||
await browser.get(`${url}&prejoin=false`);
|
||||
|
||||
await utils.checkSessionIsPresent();
|
||||
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
// Open more options menu
|
||||
element = await utils.waitForElement('#more-options-btn');
|
||||
await utils.waitForElement('#more-options-btn');
|
||||
expect(await utils.isPresent('#more-options-btn')).to.be.true;
|
||||
await element.click();
|
||||
await utils.clickOn('#more-options-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
// Clicking to recording button
|
||||
await utils.waitForElement('.mat-menu-content');
|
||||
|
||||
const recordingButton = await utils.waitForElement('#recording-btn');
|
||||
await utils.waitForElement('#recording-btn');
|
||||
expect(await utils.isPresent('#recording-btn')).to.be.true;
|
||||
await recordingButton.click();
|
||||
await utils.clickOn('#recording-btn');
|
||||
|
||||
// Checking if onToolbarStartRecordingClicked has been received
|
||||
await utils.waitForElement('#onToolbarStartRecordingClicked');
|
||||
expect(await utils.isPresent('#onToolbarStartRecordingClicked')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the onToolbarStopStreamingClicked event', async () => {
|
||||
await browser.get(`${url}&prejoin=false`);
|
||||
|
||||
await utils.checkSessionIsPresent();
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
// Open more options menu
|
||||
await utils.waitForElement('#more-options-btn');
|
||||
expect(await utils.isPresent('#more-options-btn')).to.be.true;
|
||||
await utils.clickOn('#more-options-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('.mat-menu-content');
|
||||
|
||||
await utils.waitForElement('#streaming-btn');
|
||||
await utils.clickOn('#streaming-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('.sidenav-menu');
|
||||
await utils.waitForElement('#activities-container');
|
||||
|
||||
await utils.waitForElement('#streaming-url-input');
|
||||
const input = await utils.waitForElement('#rtmp-url-input');
|
||||
await input.sendKeys('RTMPurl');
|
||||
await utils.clickOn('#streaming-btn');
|
||||
|
||||
// Open more options menu
|
||||
await utils.waitForElement('#more-options-btn');
|
||||
expect(await utils.isPresent('#more-options-btn')).to.be.true;
|
||||
await utils.clickOn('#more-options-btn');
|
||||
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('.mat-menu-content');
|
||||
|
||||
await utils.waitForElement('#streaming-btn');
|
||||
await utils.clickOn('#streaming-btn');
|
||||
|
||||
// Checking if onToolbarStopStreamingClicked has been received
|
||||
await utils.waitForElement('#onToolbarStopStreamingClicked');
|
||||
expect(await utils.isPresent('#onToolbarStopStreamingClicked')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the onActivitiesPanelStartRecordingClicked event', async () => {
|
||||
let element;
|
||||
await browser.get(`${url}&prejoin=false`);
|
||||
|
@ -890,6 +940,50 @@ describe('Testing videoconference EVENTS', () => {
|
|||
expect(await utils.isPresent('#onActivitiesPanelDeleteRecordingClicked')).to.be.true;
|
||||
});
|
||||
|
||||
it('should receive the onActivitiesPanelStartStreaming and onActivitiesPanelStopStreamingClicked events', async () => {
|
||||
await browser.get(`${url}&prejoin=false`);
|
||||
|
||||
await utils.checkSessionIsPresent();
|
||||
await utils.checkToolbarIsPresent();
|
||||
|
||||
// Get activities button and click into it
|
||||
await utils.waitForElement('#activities-panel-btn');
|
||||
await utils.clickOn('#activities-panel-btn');
|
||||
await browser.sleep(500);
|
||||
|
||||
await utils.waitForElement('.sidenav-menu');
|
||||
await utils.waitForElement('#activities-container');
|
||||
expect(await utils.isPresent('#activities-container')).to.be.true;
|
||||
|
||||
await utils.waitForElement('#streaming-activity');
|
||||
await utils.clickOn('#streaming-activity');
|
||||
|
||||
await browser.sleep(1000);
|
||||
|
||||
const button = await utils.waitForElement('#streaming-btn');
|
||||
expect(await button.isEnabled()).to.be.false;
|
||||
|
||||
|
||||
const input = await utils.waitForElement('#rtmp-url-input');
|
||||
await input.sendKeys('RTMPurl');
|
||||
|
||||
await utils.clickOn('#streaming-btn');
|
||||
|
||||
// Checking if onActivitiesPanelStartStreamingClicked has been received
|
||||
await utils.waitForElement('#onActivitiesPanelStartStreamingClicked');
|
||||
expect(await utils.isPresent('#onActivitiesPanelStartStreamingClicked')).to.be.true;
|
||||
expect(await utils.isPresent('#streaming-tag')).to.be.true;
|
||||
|
||||
await utils.clickOn('#stop-streaming-btn');
|
||||
|
||||
// Checking if onActivitiesPanelStopStreamingClicked has been received
|
||||
await utils.waitForElement('#onActivitiesPanelStopStreamingClicked');
|
||||
expect(await utils.isPresent('#onActivitiesPanelStopStreamingClicked')).to.be.true;
|
||||
expect(await utils.isPresent('#streaming-tag')).to.be.false;
|
||||
|
||||
|
||||
});
|
||||
|
||||
it('should receive the onSessionCreated event', async () => {
|
||||
await browser.get(`${url}&prejoin=false`);
|
||||
|
||||
|
|
|
@ -653,9 +653,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz",
|
||||
"integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz",
|
||||
"integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -781,9 +781,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz",
|
||||
"integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz",
|
||||
"integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
|
@ -802,13 +802,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-regexp-features-plugin": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz",
|
||||
"integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz",
|
||||
"integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
"regexpu-core": "^5.1.0"
|
||||
"regexpu-core": "^5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -1051,29 +1051,29 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-wrap-function": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz",
|
||||
"integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz",
|
||||
"integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-function-name": "^7.19.0",
|
||||
"@babel/template": "^7.18.10",
|
||||
"@babel/traverse": "^7.19.0",
|
||||
"@babel/types": "^7.19.0"
|
||||
"@babel/traverse": "^7.20.5",
|
||||
"@babel/types": "^7.20.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz",
|
||||
"integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==",
|
||||
"version": "7.20.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz",
|
||||
"integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.18.10",
|
||||
"@babel/traverse": "^7.20.1",
|
||||
"@babel/types": "^7.20.0"
|
||||
"@babel/traverse": "^7.20.5",
|
||||
"@babel/types": "^7.20.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -1094,9 +1094,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz",
|
||||
"integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz",
|
||||
"integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
|
@ -1353,14 +1353,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-proposal-private-property-in-object": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz",
|
||||
"integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz",
|
||||
"integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
"@babel/helper-create-class-features-plugin": "^7.18.6",
|
||||
"@babel/helper-plugin-utils": "^7.18.6",
|
||||
"@babel/helper-create-class-features-plugin": "^7.20.5",
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/plugin-syntax-private-property-in-object": "^7.14.5"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1626,9 +1626,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz",
|
||||
"integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz",
|
||||
"integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.20.2"
|
||||
|
@ -1870,13 +1870,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
|
||||
"version": "7.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz",
|
||||
"integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz",
|
||||
"integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.19.0",
|
||||
"@babel/helper-plugin-utils": "^7.19.0"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.20.5",
|
||||
"@babel/helper-plugin-utils": "^7.20.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -1917,9 +1917,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-parameters": {
|
||||
"version": "7.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz",
|
||||
"integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz",
|
||||
"integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.20.2"
|
||||
|
@ -1947,13 +1947,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regenerator": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz",
|
||||
"integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz",
|
||||
"integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.18.6",
|
||||
"regenerator-transform": "^0.15.0"
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"regenerator-transform": "^0.15.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -2254,19 +2254,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz",
|
||||
"integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz",
|
||||
"integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.18.6",
|
||||
"@babel/generator": "^7.20.1",
|
||||
"@babel/generator": "^7.20.5",
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
"@babel/helper-function-name": "^7.19.0",
|
||||
"@babel/helper-hoist-variables": "^7.18.6",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
"@babel/parser": "^7.20.1",
|
||||
"@babel/types": "^7.20.0",
|
||||
"@babel/parser": "^7.20.5",
|
||||
"@babel/types": "^7.20.5",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
|
@ -2275,12 +2275,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/traverse/node_modules/@babel/generator": {
|
||||
"version": "7.20.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz",
|
||||
"integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz",
|
||||
"integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.20.2",
|
||||
"@babel/types": "^7.20.5",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"jsesc": "^2.5.1"
|
||||
},
|
||||
|
@ -2303,9 +2303,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz",
|
||||
"integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz",
|
||||
"integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.19.4",
|
||||
|
@ -3517,10 +3517,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@types/cors": {
|
||||
"version": "2.8.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
||||
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
|
||||
"dev": true
|
||||
"version": "2.8.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
|
||||
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "8.4.10",
|
||||
|
@ -4899,9 +4902,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001434",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
|
||||
"integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA==",
|
||||
"version": "1.0.30001439",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz",
|
||||
"integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -6000,9 +6003,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/cssdb": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.1.0.tgz",
|
||||
"integrity": "sha512-Sd99PrFgx28ez4GHu8yoQIufc/70h9oYowDf4EjeIKi8mac9whxRjhM3IaMr6EllP6KKKWtJrMfN6C7T9tIWvQ==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz",
|
||||
"integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
|
@ -6103,9 +6106,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==",
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
|
@ -6590,12 +6593,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.11.0.tgz",
|
||||
"integrity": "sha512-0Gcraf7gAJSQoPg+bTSXNhuzAYtXqLc4C011vb8S3B8XUSEkGYNBk20c68X9291VF4vvsCD8SPkr6Mza+DwU+g==",
|
||||
"version": "5.12.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
|
||||
"integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.9",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -7599,9 +7602,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
|
||||
"integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz",
|
||||
"integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
|
@ -8633,9 +8636,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
|
||||
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
|
||||
"integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
|
@ -10115,9 +10118,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/log4js": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz",
|
||||
"integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==",
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.1.tgz",
|
||||
"integrity": "sha512-lzbd0Eq1HRdWM2abSD7mk6YIVY0AogGJzb/z+lqzRk+8+XJP+M6L1MS5FUSc3jjGru4dbKjEMJmqlsoYYpuivQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"date-format": "^4.0.14",
|
||||
|
@ -10261,9 +10264,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz",
|
||||
"integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.4.tgz",
|
||||
"integrity": "sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
|
@ -10462,9 +10465,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz",
|
||||
"integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
|
@ -12360,9 +12363,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss-custom-properties": {
|
||||
"version": "12.1.10",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.10.tgz",
|
||||
"integrity": "sha512-U3BHdgrYhCrwTVcByFHs9EOBoqcKq4Lf3kXwbTi4hhq0qWhl/pDWq2THbv/ICX/Fl9KqeHBb8OVrTf2OaYF07A==",
|
||||
"version": "12.1.11",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz",
|
||||
"integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -14115,17 +14118,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/socket.io": {
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz",
|
||||
"integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==",
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
|
||||
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io": "~6.2.0",
|
||||
"engine.io": "~6.2.1",
|
||||
"socket.io-adapter": "~2.4.0",
|
||||
"socket.io-parser": "~4.2.0"
|
||||
"socket.io-parser": "~4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
|
@ -14274,6 +14277,7 @@
|
|||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||
"deprecated": "Please use @jridgewell/sourcemap-codec instead",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/spdx-correct": {
|
||||
|
@ -14784,14 +14788,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "6.1.12",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.12.tgz",
|
||||
"integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==",
|
||||
"version": "6.1.13",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
|
||||
"integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^3.0.0",
|
||||
"minipass": "^4.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
|
@ -14800,6 +14804,18 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/tar/node_modules/minipass": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz",
|
||||
"integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tcp-port-used": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz",
|
||||
|
@ -16962,9 +16978,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/compat-data": {
|
||||
"version": "7.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.1.tgz",
|
||||
"integrity": "sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz",
|
||||
"integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/core": {
|
||||
|
@ -17062,9 +17078,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz",
|
||||
"integrity": "sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz",
|
||||
"integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
|
@ -17077,13 +17093,13 @@
|
|||
}
|
||||
},
|
||||
"@babel/helper-create-regexp-features-plugin": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz",
|
||||
"integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz",
|
||||
"integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
"regexpu-core": "^5.1.0"
|
||||
"regexpu-core": "^5.2.1"
|
||||
}
|
||||
},
|
||||
"@babel/helper-define-polyfill-provider": {
|
||||
|
@ -17262,26 +17278,26 @@
|
|||
"dev": true
|
||||
},
|
||||
"@babel/helper-wrap-function": {
|
||||
"version": "7.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz",
|
||||
"integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz",
|
||||
"integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-function-name": "^7.19.0",
|
||||
"@babel/template": "^7.18.10",
|
||||
"@babel/traverse": "^7.19.0",
|
||||
"@babel/types": "^7.19.0"
|
||||
"@babel/traverse": "^7.20.5",
|
||||
"@babel/types": "^7.20.5"
|
||||
}
|
||||
},
|
||||
"@babel/helpers": {
|
||||
"version": "7.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.1.tgz",
|
||||
"integrity": "sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==",
|
||||
"version": "7.20.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz",
|
||||
"integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/template": "^7.18.10",
|
||||
"@babel/traverse": "^7.20.1",
|
||||
"@babel/types": "^7.20.0"
|
||||
"@babel/traverse": "^7.20.5",
|
||||
"@babel/types": "^7.20.5"
|
||||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
|
@ -17296,9 +17312,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.3.tgz",
|
||||
"integrity": "sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz",
|
||||
"integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
|
||||
|
@ -17459,14 +17475,14 @@
|
|||
}
|
||||
},
|
||||
"@babel/plugin-proposal-private-property-in-object": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz",
|
||||
"integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz",
|
||||
"integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
"@babel/helper-create-class-features-plugin": "^7.18.6",
|
||||
"@babel/helper-plugin-utils": "^7.18.6",
|
||||
"@babel/helper-create-class-features-plugin": "^7.20.5",
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/plugin-syntax-private-property-in-object": "^7.14.5"
|
||||
}
|
||||
},
|
||||
|
@ -17645,9 +17661,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.2.tgz",
|
||||
"integrity": "sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz",
|
||||
"integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.20.2"
|
||||
|
@ -17799,13 +17815,13 @@
|
|||
}
|
||||
},
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": {
|
||||
"version": "7.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz",
|
||||
"integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz",
|
||||
"integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.19.0",
|
||||
"@babel/helper-plugin-utils": "^7.19.0"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.20.5",
|
||||
"@babel/helper-plugin-utils": "^7.20.2"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-new-target": {
|
||||
|
@ -17828,9 +17844,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/plugin-transform-parameters": {
|
||||
"version": "7.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.3.tgz",
|
||||
"integrity": "sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz",
|
||||
"integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.20.2"
|
||||
|
@ -17846,13 +17862,13 @@
|
|||
}
|
||||
},
|
||||
"@babel/plugin-transform-regenerator": {
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz",
|
||||
"integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz",
|
||||
"integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.18.6",
|
||||
"regenerator-transform": "^0.15.0"
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"regenerator-transform": "^0.15.1"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-reserved-words": {
|
||||
|
@ -18076,30 +18092,30 @@
|
|||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.20.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.1.tgz",
|
||||
"integrity": "sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz",
|
||||
"integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.18.6",
|
||||
"@babel/generator": "^7.20.1",
|
||||
"@babel/generator": "^7.20.5",
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
"@babel/helper-function-name": "^7.19.0",
|
||||
"@babel/helper-hoist-variables": "^7.18.6",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
"@babel/parser": "^7.20.1",
|
||||
"@babel/types": "^7.20.0",
|
||||
"@babel/parser": "^7.20.5",
|
||||
"@babel/types": "^7.20.5",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/generator": {
|
||||
"version": "7.20.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.4.tgz",
|
||||
"integrity": "sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz",
|
||||
"integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.20.2",
|
||||
"@babel/types": "^7.20.5",
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"jsesc": "^2.5.1"
|
||||
}
|
||||
|
@ -18118,9 +18134,9 @@
|
|||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.2.tgz",
|
||||
"integrity": "sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==",
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz",
|
||||
"integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.19.4",
|
||||
|
@ -19005,10 +19021,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/cors": {
|
||||
"version": "2.8.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz",
|
||||
"integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==",
|
||||
"dev": true
|
||||
"version": "2.8.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
|
||||
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "8.4.10",
|
||||
|
@ -20147,9 +20166,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001434",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
|
||||
"integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA==",
|
||||
"version": "1.0.30001439",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz",
|
||||
"integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==",
|
||||
"dev": true
|
||||
},
|
||||
"chai": {
|
||||
|
@ -20982,9 +21001,9 @@
|
|||
}
|
||||
},
|
||||
"cssdb": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.1.0.tgz",
|
||||
"integrity": "sha512-Sd99PrFgx28ez4GHu8yoQIufc/70h9oYowDf4EjeIKi8mac9whxRjhM3IaMr6EllP6KKKWtJrMfN6C7T9tIWvQ==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz",
|
||||
"integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==",
|
||||
"dev": true
|
||||
},
|
||||
"cssesc": {
|
||||
|
@ -21058,9 +21077,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==",
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
|
||||
"dev": true
|
||||
},
|
||||
"deep-eql": {
|
||||
|
@ -21439,12 +21458,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.11.0.tgz",
|
||||
"integrity": "sha512-0Gcraf7gAJSQoPg+bTSXNhuzAYtXqLc4C011vb8S3B8XUSEkGYNBk20c68X9291VF4vvsCD8SPkr6Mza+DwU+g==",
|
||||
"version": "5.12.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
|
||||
"integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.9",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
}
|
||||
},
|
||||
|
@ -22130,9 +22149,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
|
||||
"integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz",
|
||||
"integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.4"
|
||||
|
@ -22897,9 +22916,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
|
||||
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
|
||||
"integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore-walk": {
|
||||
|
@ -24029,9 +24048,9 @@
|
|||
}
|
||||
},
|
||||
"log4js": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz",
|
||||
"integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==",
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.1.tgz",
|
||||
"integrity": "sha512-lzbd0Eq1HRdWM2abSD7mk6YIVY0AogGJzb/z+lqzRk+8+XJP+M6L1MS5FUSc3jjGru4dbKjEMJmqlsoYYpuivQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"date-format": "^4.0.14",
|
||||
|
@ -24143,9 +24162,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"marked": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.3.tgz",
|
||||
"integrity": "sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.4.tgz",
|
||||
"integrity": "sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==",
|
||||
"dev": true
|
||||
},
|
||||
"media-typer": {
|
||||
|
@ -24286,9 +24305,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz",
|
||||
"integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==",
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
|
@ -25706,9 +25725,9 @@
|
|||
}
|
||||
},
|
||||
"postcss-custom-properties": {
|
||||
"version": "12.1.10",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.10.tgz",
|
||||
"integrity": "sha512-U3BHdgrYhCrwTVcByFHs9EOBoqcKq4Lf3kXwbTi4hhq0qWhl/pDWq2THbv/ICX/Fl9KqeHBb8OVrTf2OaYF07A==",
|
||||
"version": "12.1.11",
|
||||
"resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz",
|
||||
"integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
|
@ -26952,17 +26971,17 @@
|
|||
"dev": true
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz",
|
||||
"integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==",
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz",
|
||||
"integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "~2.0.0",
|
||||
"debug": "~4.3.2",
|
||||
"engine.io": "~6.2.0",
|
||||
"engine.io": "~6.2.1",
|
||||
"socket.io-adapter": "~2.4.0",
|
||||
"socket.io-parser": "~4.2.0"
|
||||
"socket.io-parser": "~4.2.1"
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
|
@ -27475,17 +27494,28 @@
|
|||
"dev": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "6.1.12",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.12.tgz",
|
||||
"integrity": "sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==",
|
||||
"version": "6.1.13",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz",
|
||||
"integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^3.0.0",
|
||||
"minipass": "^4.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz",
|
||||
"integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp-port-used": {
|
||||
|
|
|
@ -17,39 +17,39 @@
|
|||
"zone.js": "0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "14.2.10",
|
||||
"@angular/cli": "14.2.10",
|
||||
"@angular/compiler": "14.2.10",
|
||||
"@angular/compiler-cli": "14.2.10",
|
||||
"@angular/elements": "14.2.10",
|
||||
"@compodoc/compodoc": "^1.1.19",
|
||||
"@types/chai": "4.3.0",
|
||||
"@types/mocha": "9.1.0",
|
||||
"@types/node": "16.11.6",
|
||||
"@types/selenium-webdriver": "4.1.5",
|
||||
"chai": "4.3.6",
|
||||
"chromedriver": "106.0.1",
|
||||
"codelyzer": "6.0.2",
|
||||
"concat": "^1.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"http-server": "14.1.1",
|
||||
"jasmine-core": "3.10.1",
|
||||
"jasmine-spec-reporter": "7.0.0",
|
||||
"karma": "^6.3.9",
|
||||
"karma-chrome-launcher": "3.1.1",
|
||||
"karma-coverage": "^2.0.3",
|
||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||
"karma-jasmine": "4.0.1",
|
||||
"karma-jasmine-html-reporter": "1.7.0",
|
||||
"karma-junit-reporter": "2.0.1",
|
||||
"karma-mocha-reporter": "2.2.5",
|
||||
"karma-notify-reporter": "1.3.0",
|
||||
"mocha": "9.2.2",
|
||||
"ng-packagr": "14.2.2",
|
||||
"selenium-webdriver": "4.5.0",
|
||||
"ts-node": "10.4.0",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "4.8.4",
|
||||
"@angular-devkit/build-angular": "14.2.10",
|
||||
"@angular/cli": "14.2.10",
|
||||
"@angular/compiler": "14.2.10",
|
||||
"@angular/compiler-cli": "14.2.10",
|
||||
"@angular/elements": "14.2.10",
|
||||
"@compodoc/compodoc": "^1.1.19",
|
||||
"@types/chai": "4.3.0",
|
||||
"@types/mocha": "9.1.0",
|
||||
"@types/node": "16.11.6",
|
||||
"@types/selenium-webdriver": "4.1.5",
|
||||
"chai": "4.3.6",
|
||||
"chromedriver": "106.0.1",
|
||||
"codelyzer": "6.0.2",
|
||||
"concat": "^1.0.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"http-server": "14.1.1",
|
||||
"jasmine-core": "3.10.1",
|
||||
"jasmine-spec-reporter": "7.0.0",
|
||||
"karma": "^6.3.9",
|
||||
"karma-chrome-launcher": "3.1.1",
|
||||
"karma-coverage": "^2.0.3",
|
||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||
"karma-jasmine": "4.0.1",
|
||||
"karma-jasmine-html-reporter": "1.7.0",
|
||||
"karma-junit-reporter": "2.0.1",
|
||||
"karma-mocha-reporter": "2.2.5",
|
||||
"karma-notify-reporter": "1.3.0",
|
||||
"mocha": "9.2.2",
|
||||
"ng-packagr": "14.2.2",
|
||||
"selenium-webdriver": "4.5.0",
|
||||
"ts-node": "10.4.0",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "4.8.4",
|
||||
"webpack-bundle-analyzer": "^4.5.0"
|
||||
},
|
||||
"name": "openvidu-components-testapp",
|
||||
|
@ -78,4 +78,4 @@
|
|||
"webcomponent:serve-testapp": "npx http-server ./e2e/webcomponent-app/ && echo http://localhost:8080/?OV_URL=https://localhost:4443&OV_SECRET=MY_SECRET&prejoin=false"
|
||||
},
|
||||
"version": "2.25.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, OnInit, QueryList, ViewChildren } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PanelEvent, PanelService } from '../../services/panel/panel.service';
|
||||
import { PanelService } from '../../services/panel/panel.service';
|
||||
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import { Session, SpeechToTextEvent } from 'openvidu-browser';
|
||||
import { CaptionModel, CaptionsLangOption } from '../../models/caption.model';
|
||||
import { PanelSettingsOptions, PanelType } from '../../models/panel.model';
|
||||
import { PanelEvent, PanelSettingsOptions, PanelType } from '../../models/panel.model';
|
||||
import { CaptionService } from '../../services/caption/caption.service';
|
||||
import { OpenViduService } from '../../services/openvidu/openvidu.service';
|
||||
import { ParticipantService } from '../../services/participant/participant.service';
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
}
|
||||
|
||||
::ng-deep .mat-expansion-panel-header {
|
||||
padding: 0px 10px !important;
|
||||
padding: 0px 5px !important;
|
||||
height: 65px !important;
|
||||
}
|
||||
|
||||
|
@ -54,3 +54,7 @@
|
|||
::ng-deep .mat-expansion-panel {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
::ng-deep .no-body .mat-expansion-panel-content {
|
||||
display: none !important;
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
</div>
|
||||
|
||||
<div class="activities-body-container" fxFlex="75%" fxLayoutAlign="space-evenly none">
|
||||
<mat-accordion>
|
||||
<mat-accordion [multi]="false">
|
||||
<ov-recording-activity
|
||||
*ngIf="showRecordingActivity"
|
||||
id="recording-activity"
|
||||
|
@ -16,6 +16,13 @@
|
|||
(onStopRecordingClicked)="_onStopRecordingClicked()"
|
||||
(onDeleteRecordingClicked)="_onDeleteRecordingClicked($event)"
|
||||
></ov-recording-activity>
|
||||
<ov-streaming-activity
|
||||
*ngIf="showStreamingActivity"
|
||||
id="streaming-activity"
|
||||
[expanded]="expandedPanel === 'streaming'"
|
||||
(onStartStreamingClicked)="_onStartStreamingClicked($event)"
|
||||
(onStopStreamingClicked)="_onStopStreamingClicked()"
|
||||
></ov-streaming-activity>
|
||||
</mat-accordion>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PanelType } from '../../../models/panel.model';
|
||||
import { PanelEvent, PanelType } from '../../../models/panel.model';
|
||||
import { OpenViduAngularConfigService } from '../../../services/config/openvidu-angular.config.service';
|
||||
import { PanelEvent, PanelService } from '../../../services/panel/panel.service';
|
||||
import { PanelService } from '../../../services/panel/panel.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ov-activities-panel',
|
||||
|
@ -13,7 +13,7 @@ import { PanelEvent, PanelService } from '../../../services/panel/panel.service'
|
|||
export class ActivitiesPanelComponent implements OnInit {
|
||||
/**
|
||||
* Provides event notifications that fire when start recording button has been clicked.
|
||||
* The recording should be stated using the OpenVidu REST API.
|
||||
* The recording should be started using the OpenVidu REST API.
|
||||
*/
|
||||
@Output() onStartRecordingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
|
@ -29,6 +29,17 @@ export class ActivitiesPanelComponent implements OnInit {
|
|||
*/
|
||||
@Output() onDeleteRecordingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button has been clicked.
|
||||
* The streaming should be started using the REST API.
|
||||
*/
|
||||
@Output() onStartStreamingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when stop streaming button has been clicked.
|
||||
* The streaming should be stopped using the REST API.
|
||||
*/
|
||||
@Output() onStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -38,8 +49,10 @@ export class ActivitiesPanelComponent implements OnInit {
|
|||
* @internal
|
||||
*/
|
||||
showRecordingActivity: boolean = true;
|
||||
showStreamingActivity: boolean = true;
|
||||
private panelSubscription: Subscription;
|
||||
private recordingActivitySub: Subscription;
|
||||
private streamingActivitySub: Subscription;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -60,6 +73,7 @@ export class ActivitiesPanelComponent implements OnInit {
|
|||
ngOnDestroy() {
|
||||
if (this.panelSubscription) this.panelSubscription.unsubscribe();
|
||||
if (this.recordingActivitySub) this.recordingActivitySub.unsubscribe();
|
||||
if (this.streamingActivitySub) this.streamingActivitySub.unsubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,14 +104,20 @@ export class ActivitiesPanelComponent implements OnInit {
|
|||
this.onDeleteRecordingClicked.emit(recordingId);
|
||||
}
|
||||
|
||||
_onStartStreamingClicked(rtmpUrl: string) {
|
||||
this.onStartStreamingClicked.emit(rtmpUrl);
|
||||
}
|
||||
|
||||
_onStopStreamingClicked() {
|
||||
this.onStopStreamingClicked.emit();
|
||||
}
|
||||
|
||||
private subscribeToPanelToggling() {
|
||||
this.panelSubscription = this.panelService.panelOpenedObs.subscribe(
|
||||
(ev: PanelEvent) => {
|
||||
if (ev.type === PanelType.ACTIVITIES && !!ev.expand) {
|
||||
this.expandedPanel = ev.expand;
|
||||
}
|
||||
this.panelSubscription = this.panelService.panelOpenedObs.subscribe((ev: PanelEvent) => {
|
||||
if (ev.type === PanelType.ACTIVITIES && !!ev.expand) {
|
||||
this.expandedPanel = ev.expand;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToActivitiesPanelDirective() {
|
||||
|
@ -105,5 +125,10 @@ export class ActivitiesPanelComponent implements OnInit {
|
|||
this.showRecordingActivity = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
|
||||
this.streamingActivitySub = this.libService.streamingActivity.subscribe((value: boolean) => {
|
||||
this.showStreamingActivity = value;
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#recording-status {
|
||||
color: var(--ov-text-color);
|
||||
display: inline;
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
padding: 3px;
|
||||
font-size: 11px;
|
||||
border-radius: var(--ov-panel-radius);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@
|
|||
}
|
||||
|
||||
mat-expansion-panel {
|
||||
margin: 0px 0px 15px 0px;
|
||||
margin: 0px 0px 5px 0px;
|
||||
}
|
||||
|
||||
.blink {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<mat-expansion-panel (opened)="panelOpened()" (closed)="panelClosed()" [expanded]="expanded">
|
||||
<mat-expansion-panel (opened)="panelOpened()" (closed)="panelClosed()" [expanded]="expanded" [ngClass]="{'no-body': !opened}">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-list>
|
||||
<mat-list-item>
|
||||
|
@ -12,7 +12,7 @@
|
|||
pending: recordingStatus === recStatusEnum.STARTING || recordingStatus === recStatusEnum.STOPPING
|
||||
}"
|
||||
>
|
||||
<mat-icon *ngIf="recordingStatus !== recStatusEnum.FAILED && recordingStatus !== recStatusEnum.STARTED">
|
||||
<mat-icon id="recording-icon" *ngIf="recordingStatus !== recStatusEnum.FAILED && recordingStatus !== recStatusEnum.STARTED">
|
||||
video_camera_front
|
||||
</mat-icon>
|
||||
<mat-icon *ngIf="recordingStatus === recStatusEnum.FAILED">error</mat-icon>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { OpenViduRole } from '../../../../models/participant.model';
|
||||
import { RecordingInfo, RecordingStatus } from '../../../../models/recording.model';
|
||||
import { ActionService } from '../../../../services/action/action.service';
|
||||
import { OpenViduAngularConfigService } from '../../../../services/config/openvidu-angular.config.service';
|
||||
|
@ -21,7 +20,7 @@ export class RecordingActivityComponent implements OnInit {
|
|||
|
||||
/**
|
||||
* Provides event notifications that fire when start recording button has been clicked.
|
||||
* The recording should be stopped using the REST API.
|
||||
* The recording should be started using the REST API.
|
||||
*/
|
||||
@Output() onStartRecordingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
|
@ -95,7 +94,7 @@ export class RecordingActivityComponent implements OnInit {
|
|||
ngOnInit(): void {
|
||||
this.subscribeToRecordingStatus();
|
||||
this.subscribeToRecordingActivityDirective();
|
||||
this.isSessionCreator = this.participantService.getMyRole() === OpenViduRole.MODERATOR;
|
||||
this.isSessionCreator = this.participantService.amIModerator();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
#streaming-status {
|
||||
color: var(--ov-text-color);
|
||||
display: inline;
|
||||
padding: 3px;
|
||||
font-size: 11px;
|
||||
border-radius: var(--ov-panel-radius);
|
||||
}
|
||||
|
||||
.time-container {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
color: var(--ov-warn-color);
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#streaming-icon {
|
||||
color: #5903ca;
|
||||
}
|
||||
|
||||
.streaming-duration {
|
||||
background-color: var(--ov-light-color);
|
||||
padding: 4px 8px;
|
||||
border-radius: var(--ov-panel-radius);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.streaming-duration mat-icon {
|
||||
font-size: 18px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.started {
|
||||
background-color: #5903ca !important;
|
||||
color: var(--ov-text-color);
|
||||
}
|
||||
|
||||
.activity-icon.started {
|
||||
background-color: #5903ca !important;
|
||||
color: var(--ov-text-color);
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: var(--ov-warn-color) !important;
|
||||
color: var(--ov-text-color);
|
||||
}
|
||||
.stopped {
|
||||
background-color: var(--ov-light-color);
|
||||
color: var(--ov-panel-text-color) !important;
|
||||
}
|
||||
|
||||
.pending {
|
||||
background-color: #ffd79b !important;
|
||||
color: var(--ov-panel-text-color) !important;
|
||||
}
|
||||
|
||||
.panel-body-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.panel-body-container > .content {
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-flex: 1;
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.streaming-error {
|
||||
color: var(--ov-warn-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
.streaming-name {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.not-allowed-message {
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.streaming-action-buttons {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* #start-streaming-btn {
|
||||
width: 100%;
|
||||
background-color: var(--ov-tertiary-color);
|
||||
color: var(--ov-text-color);
|
||||
} */
|
||||
|
||||
#stop-streaming-btn {
|
||||
/* background-color: var(--ov-warn-color); */
|
||||
color: var(--ov-warn-color);
|
||||
}
|
||||
|
||||
#reset-streaming-status-btn {
|
||||
width: 100%;
|
||||
background-color: var(--ov-light-color);
|
||||
}
|
||||
|
||||
mat-expansion-panel {
|
||||
margin: 0px 0px 5px 0px;
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation: blinker 1.5s linear infinite !important;
|
||||
}
|
||||
@keyframes blinker {
|
||||
50% {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.input-container {
|
||||
height: 25px;
|
||||
display: flex;
|
||||
background-color: var(--ov-light-color);
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
border-radius: var(--ov-panel-radius);
|
||||
}
|
||||
|
||||
.input-container input {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
margin: auto;
|
||||
background-color: transparent;
|
||||
display: block;
|
||||
border: none;
|
||||
padding: 0;
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
resize: none;
|
||||
outline: none;
|
||||
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
font-family: 'Roboto', 'RobotoDraft', Helvetica, Arial, sans-serif;
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,23 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StreamingActivityComponent } from './streaming-activity.component';
|
||||
|
||||
describe('StreamingActivityComponent', () => {
|
||||
let component: StreamingActivityComponent;
|
||||
let fixture: ComponentFixture<StreamingActivityComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ StreamingActivityComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(StreamingActivityComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,190 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Signal } from '../../../../models/signal.model';
|
||||
import { StreamingError, StreamingInfo, StreamingStatus } from '../../../../models/streaming.model';
|
||||
import { OpenViduAngularConfigService } from '../../../../services/config/openvidu-angular.config.service';
|
||||
import { OpenViduService } from '../../../../services/openvidu/openvidu.service';
|
||||
import { ParticipantService } from '../../../../services/participant/participant.service';
|
||||
import { StreamingService } from '../../../../services/streaming/streaming.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ov-streaming-activity',
|
||||
templateUrl: './streaming-activity.component.html',
|
||||
styleUrls: ['./streaming-activity.component.css', '../activities-panel.component.css'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class StreamingActivityComponent implements OnInit {
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button has been clicked.
|
||||
* The streaming should be started using the REST API.
|
||||
*/
|
||||
@Output() onStartStreamingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when stop streaming button has been clicked.
|
||||
* The streaming should be stopped using the REST API.
|
||||
*/
|
||||
@Output() onStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
urlRequiredError: boolean = false;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
oldStreamingStatus: StreamingStatus;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
rtmpUrl: string = '';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@Input() expanded: boolean;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
streamingError: StreamingError | undefined;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
streamingStatus: StreamingStatus = StreamingStatus.STOPPED;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
streamingStatusEnum = StreamingStatus;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
opened: boolean = false;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
isSessionCreator: boolean = false;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
isRtmpModuleAvailable: boolean = true;
|
||||
private streamingSub: Subscription;
|
||||
private streamingInfoSub: Subscription;
|
||||
private streamingErrorSub: Subscription;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(
|
||||
private streamingService: StreamingService,
|
||||
private participantService: ParticipantService,
|
||||
private openviduService: OpenViduService,
|
||||
private libService: OpenViduAngularConfigService,
|
||||
private cd: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.isSessionCreator = this.participantService.amIModerator();
|
||||
this.subscribeToStreamingStatus();
|
||||
this.subscribeToStreamingInfo();
|
||||
this.subscribeToStreamingError();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
if (this.streamingSub) this.streamingSub.unsubscribe();
|
||||
if (this.streamingInfoSub) this.streamingInfoSub.unsubscribe();
|
||||
if (this.streamingErrorSub) this.streamingErrorSub.unsubscribe();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
panelOpened() {
|
||||
this.opened = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
panelClosed() {
|
||||
this.opened = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
eventKeyPress(event) {
|
||||
// Pressed 'Enter' key
|
||||
if (event && event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
this.startStreaming();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
startStreaming() {
|
||||
if (!!this.rtmpUrl) {
|
||||
this.isRtmpModuleAvailable = true;
|
||||
this.streamingError = undefined;
|
||||
this.streamingService.updateStatus(StreamingStatus.STARTING);
|
||||
this.onStartStreamingClicked.emit(this.rtmpUrl);
|
||||
}
|
||||
this.urlRequiredError = !this.rtmpUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
stopStreaming() {
|
||||
this.onStopStreamingClicked.emit();
|
||||
this.streamingService.updateStatus(StreamingStatus.STOPPING);
|
||||
}
|
||||
|
||||
private subscribeToStreamingStatus() {
|
||||
this.streamingSub = this.streamingService.streamingStatusObs.subscribe(
|
||||
(ev: { status: StreamingStatus; time?: Date } | undefined) => {
|
||||
if (!!ev) {
|
||||
this.streamingStatus = ev.status;
|
||||
this.cd.markForCheck();
|
||||
if (this.isSessionCreator) {
|
||||
//TODO: Remove it when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
const signal =
|
||||
this.streamingStatus === StreamingStatus.STARTED ? Signal.STREAMING_STARTED : Signal.STREAMING_STOPPED;
|
||||
this.openviduService.sendSignal(signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: Remove this directive when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
private subscribeToStreamingInfo() {
|
||||
this.streamingInfoSub = this.libService.streamingInfoObs.subscribe((info: StreamingInfo | undefined) => {
|
||||
if (!!info) {
|
||||
this.streamingService.updateStatus(info.status);
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToStreamingError() {
|
||||
this.streamingErrorSub = this.libService.streamingErrorObs.subscribe((error: StreamingError | undefined) => {
|
||||
if (!!error) {
|
||||
this.streamingError = error;
|
||||
this.isRtmpModuleAvailable = error.rtmpAvailable;
|
||||
this.streamingService.updateStatus(StreamingStatus.FAILED);
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,14 +1,10 @@
|
|||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, OnInit, TemplateRef } from '@angular/core';
|
||||
import { skip, Subscription } from 'rxjs';
|
||||
import {
|
||||
ChatPanelDirective,
|
||||
AdditionalPanelsDirective,
|
||||
ParticipantsPanelDirective,
|
||||
BackgroundEffectsPanelDirective,
|
||||
ActivitiesPanelDirective
|
||||
ActivitiesPanelDirective, AdditionalPanelsDirective, ChatPanelDirective, ParticipantsPanelDirective
|
||||
} from '../../directives/template/openvidu-angular.directive';
|
||||
import { PanelType } from '../../models/panel.model';
|
||||
import { PanelEvent, PanelService } from '../../services/panel/panel.service';
|
||||
import { PanelEvent, PanelType } from '../../models/panel.model';
|
||||
import { PanelService } from '../../services/panel/panel.service';
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PanelSettingsOptions, PanelType } from '../../../models/panel.model';
|
||||
import { PanelEvent, PanelSettingsOptions, PanelType } from '../../../models/panel.model';
|
||||
import { OpenViduAngularConfigService } from '../../../services/config/openvidu-angular.config.service';
|
||||
import { PanelEvent, PanelService } from '../../../services/panel/panel.service';
|
||||
import { PanelService } from '../../../services/panel/panel.service';
|
||||
import { PlatformService } from '../../../services/platform/platform.service';
|
||||
|
||||
/**
|
||||
|
|
|
@ -32,8 +32,9 @@ import { animate, style, transition, trigger } from '@angular/animations';
|
|||
import { MatDrawerContainer, MatSidenav } from '@angular/material/sidenav';
|
||||
import { skip, Subscription } from 'rxjs';
|
||||
import { SidenavMode } from '../../models/layout.model';
|
||||
import { PanelType } from '../../models/panel.model';
|
||||
import { PanelEvent, PanelType } from '../../models/panel.model';
|
||||
import { Signal } from '../../models/signal.model';
|
||||
import { StreamingStatus } from '../../models/streaming.model';
|
||||
import { ActionService } from '../../services/action/action.service';
|
||||
import { CaptionService } from '../../services/caption/caption.service';
|
||||
import { ChatService } from '../../services/chat/chat.service';
|
||||
|
@ -41,10 +42,11 @@ import { OpenViduAngularConfigService } from '../../services/config/openvidu-ang
|
|||
import { LayoutService } from '../../services/layout/layout.service';
|
||||
import { LoggerService } from '../../services/logger/logger.service';
|
||||
import { OpenViduService } from '../../services/openvidu/openvidu.service';
|
||||
import { PanelEvent, PanelService } from '../../services/panel/panel.service';
|
||||
import { PanelService } from '../../services/panel/panel.service';
|
||||
import { ParticipantService } from '../../services/participant/participant.service';
|
||||
import { PlatformService } from '../../services/platform/platform.service';
|
||||
import { RecordingService } from '../../services/recording/recording.service';
|
||||
import { StreamingService } from '../../services/streaming/streaming.service';
|
||||
import { TranslateService } from '../../services/translate/translate.service';
|
||||
import { VirtualBackgroundService } from '../../services/virtual-background/virtual-background.service';
|
||||
|
||||
|
@ -99,6 +101,7 @@ export class SessionComponent implements OnInit, OnDestroy {
|
|||
protected layoutService: LayoutService,
|
||||
protected panelService: PanelService,
|
||||
private recordingService: RecordingService,
|
||||
private streamingService: StreamingService,
|
||||
private translateService: TranslateService,
|
||||
private captionService: CaptionService,
|
||||
private platformService: PlatformService,
|
||||
|
@ -182,10 +185,6 @@ export class SessionComponent implements OnInit, OnDestroy {
|
|||
this.subscribeToNicknameChanged();
|
||||
this.chatService.subscribeToChat();
|
||||
this.subscribeToReconnection();
|
||||
const recordingEnabled = this.libService.recordingButton.getValue() && this.libService.recordingActivity.getValue();
|
||||
if (recordingEnabled) {
|
||||
this.subscribeToRecordingEvents();
|
||||
}
|
||||
|
||||
await this.connectToSession();
|
||||
// ios devices appear with blank video. Muting and unmuting it fix this problem
|
||||
|
@ -193,6 +192,15 @@ export class SessionComponent implements OnInit, OnDestroy {
|
|||
await this.openviduService.publishVideo(false);
|
||||
await this.openviduService.publishVideo(true);
|
||||
}
|
||||
|
||||
if (this.libService.isRecordingEnabled()) {
|
||||
this.subscribeToRecordingEvents();
|
||||
}
|
||||
|
||||
if (this.libService.isStreamingEnabled() && !this.participantService.amIModerator()) {
|
||||
//TODO: Remove it when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
this.subscribeToStreamingEvents();
|
||||
}
|
||||
}
|
||||
this.preparing = false;
|
||||
this.cd.markForCheck();
|
||||
|
@ -438,6 +446,16 @@ export class SessionComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
private subscribeToStreamingEvents() {
|
||||
this.session.on(`signal:${Signal.STREAMING_STARTED}`, (event: any) => {
|
||||
this.streamingService.updateStatus(StreamingStatus.STARTED);
|
||||
});
|
||||
|
||||
this.session.on(`signal:${Signal.STREAMING_STOPPED}`, (event: any) => {
|
||||
this.streamingService.updateStatus(StreamingStatus.STOPPED);
|
||||
});
|
||||
}
|
||||
|
||||
private startUpdateLayoutInterval() {
|
||||
this.updateLayoutInterval = setInterval(() => {
|
||||
this.layoutService.update();
|
||||
|
|
|
@ -70,9 +70,9 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.recording-tag {
|
||||
.recording-tag,
|
||||
.streaming-tag {
|
||||
padding: 0 10px;
|
||||
background-color: var(--ov-warn-color);
|
||||
border-radius: var(--ov-panel-radius);
|
||||
width: fit-content;
|
||||
font-size: 12px;
|
||||
|
@ -80,13 +80,26 @@
|
|||
line-height: 20px;
|
||||
margin: auto;
|
||||
}
|
||||
.recording-tag mat-icon {
|
||||
|
||||
.recording-tag {
|
||||
background-color: var(--ov-warn-color);
|
||||
}
|
||||
.streaming-tag {
|
||||
background-color: #5903ca;
|
||||
}
|
||||
|
||||
.recording-tag mat-icon,
|
||||
.streaming-tag mat-icon {
|
||||
font-size: 16px;
|
||||
display: inline;
|
||||
vertical-align: sub;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#streaming-btn > mat-icon {
|
||||
color: #5903ca;
|
||||
}
|
||||
|
||||
.blink {
|
||||
animation: blinker 1.5s linear infinite;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
<div *ngIf="recordingStatus === _recordingStatus.STARTED" id="recording-tag" class="recording-tag">
|
||||
<mat-icon class="blink">radio_button_checked</mat-icon>
|
||||
<span class="blink">REC</span>
|
||||
<span> | {{ recordingTime | date: 'H:mm:ss' }}</span>
|
||||
<span> | {{ recordingTime | date : 'H:mm:ss' }}</span>
|
||||
</div>
|
||||
<div *ngIf="streamingStatus === _streamingStatus.STARTED" id="streaming-tag" class="streaming-tag">
|
||||
<mat-icon class="blink">sensors</mat-icon>
|
||||
<span class="blink">LIVE</span>
|
||||
<span> | {{ streamingTime | date : 'H:mm:ss' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -117,6 +122,29 @@
|
|||
</span>
|
||||
</button>
|
||||
|
||||
<!-- Streaming button -->
|
||||
<button
|
||||
*ngIf="!isMinimal && showStreamingButton"
|
||||
mat-menu-item
|
||||
id="streaming-btn"
|
||||
[disabled]="streamingStatus === _streamingStatus.STARTING || recordingStatus === _streamingStatus.STOPPING"
|
||||
(click)="toggleStreaming()"
|
||||
>
|
||||
<mat-icon>sensors</mat-icon>
|
||||
<span
|
||||
*ngIf="
|
||||
streamingStatus === _streamingStatus.STOPPED ||
|
||||
streamingStatus === _streamingStatus.STOPPING ||
|
||||
streamingStatus === _streamingStatus.FAILED
|
||||
"
|
||||
>
|
||||
{{ 'PANEL.STREAMING.START' | translate }}
|
||||
</span>
|
||||
<span *ngIf="streamingStatus === _streamingStatus.STARTED || streamingStatus === _streamingStatus.STARTING">
|
||||
{{ 'PANEL.STREAMING.STOP' | translate }}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- Virtual background button -->
|
||||
<button
|
||||
*ngIf="!isMinimal && showBackgroundEffectsButton"
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
import { skip, Subscription } from 'rxjs';
|
||||
import { ChatService } from '../../services/chat/chat.service';
|
||||
import { DocumentService } from '../../services/document/document.service';
|
||||
import { PanelEvent, PanelService } from '../../services/panel/panel.service';
|
||||
import { PanelService } from '../../services/panel/panel.service';
|
||||
|
||||
import { MediaChange } from '@angular/flex-layout';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
|
@ -26,9 +26,10 @@ import {
|
|||
} from '../../directives/template/openvidu-angular.directive';
|
||||
import { ChatMessage } from '../../models/chat.model';
|
||||
import { ILogger } from '../../models/logger.model';
|
||||
import { PanelType } from '../../models/panel.model';
|
||||
import { PanelEvent, PanelType } from '../../models/panel.model';
|
||||
import { OpenViduRole, ParticipantAbstractModel } from '../../models/participant.model';
|
||||
import { RecordingInfo, RecordingStatus } from '../../models/recording.model';
|
||||
import { StreamingStatus } from '../../models/streaming.model';
|
||||
import { ActionService } from '../../services/action/action.service';
|
||||
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
|
||||
import { DeviceService } from '../../services/device/device.service';
|
||||
|
@ -39,6 +40,7 @@ import { ParticipantService } from '../../services/participant/participant.servi
|
|||
import { PlatformService } from '../../services/platform/platform.service';
|
||||
import { RecordingService } from '../../services/recording/recording.service';
|
||||
import { StorageService } from '../../services/storage/storage.service';
|
||||
import { StreamingService } from '../../services/streaming/streaming.service';
|
||||
import { TranslateService } from '../../services/translate/translate.service';
|
||||
|
||||
/**
|
||||
|
@ -182,6 +184,11 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
*/
|
||||
@Output() onStartRecordingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button has been clicked.
|
||||
*/
|
||||
@Output() onStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when stop recording button has been clicked.
|
||||
*/
|
||||
|
@ -273,6 +280,11 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
*/
|
||||
showRecordingButton: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
showStreamingButton: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
@ -324,15 +336,28 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
* @ignore
|
||||
*/
|
||||
recordingStatus: RecordingStatus = RecordingStatus.STOPPED;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
streamingStatus: StreamingStatus = StreamingStatus.STOPPED;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
_recordingStatus = RecordingStatus;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
_streamingStatus = StreamingStatus;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
recordingTime: Date;
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
streamingTime: Date;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
|
@ -354,7 +379,9 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
private backgroundEffectsButtonSub: Subscription;
|
||||
private leaveButtonSub: Subscription;
|
||||
private recordingButtonSub: Subscription;
|
||||
private streamingButtonSub: Subscription;
|
||||
private recordingSubscription: Subscription;
|
||||
private streamingSubscription: Subscription;
|
||||
private activitiesPanelButtonSub: Subscription;
|
||||
private participantsPanelButtonSub: Subscription;
|
||||
private chatPanelButtonSub: Subscription;
|
||||
|
@ -382,6 +409,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
private libService: OpenViduAngularConfigService,
|
||||
private platformService: PlatformService,
|
||||
private recordingService: RecordingService,
|
||||
private streamingService: StreamingService,
|
||||
private translateService: TranslateService,
|
||||
private storageSrv: StorageService
|
||||
) {
|
||||
|
@ -424,6 +452,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.subscribeToMenuToggling();
|
||||
this.subscribeToChatMessages();
|
||||
this.subscribeToRecordingStatus();
|
||||
this.subscribeToStreamingStatus();
|
||||
this.subscribeToScreenSize();
|
||||
this.subscribeToCaptionsToggling();
|
||||
}
|
||||
|
@ -431,7 +460,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
ngAfterViewInit() {
|
||||
// Sometimes the connection is undefined so we have to check the role when the mat menu is opened
|
||||
this.menuTrigger?.menuOpened.subscribe(() => {
|
||||
this.isSessionCreator = this.participantService.getMyRole() === OpenViduRole.MODERATOR;
|
||||
this.isSessionCreator = this.participantService.amIModerator();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -444,6 +473,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
if (this.backgroundEffectsButtonSub) this.backgroundEffectsButtonSub.unsubscribe();
|
||||
if (this.leaveButtonSub) this.leaveButtonSub.unsubscribe();
|
||||
if (this.recordingButtonSub) this.recordingButtonSub.unsubscribe();
|
||||
if (this.streamingButtonSub) this.streamingButtonSub.unsubscribe();
|
||||
if (this.participantsPanelButtonSub) this.participantsPanelButtonSub.unsubscribe();
|
||||
if (this.chatPanelButtonSub) this.chatPanelButtonSub.unsubscribe();
|
||||
if (this.displayLogoSub) this.displayLogoSub.unsubscribe();
|
||||
|
@ -451,6 +481,7 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
if (this.minimalSub) this.minimalSub.unsubscribe();
|
||||
if (this.activitiesPanelButtonSub) this.activitiesPanelButtonSub.unsubscribe();
|
||||
if (this.recordingSubscription) this.recordingSubscription.unsubscribe();
|
||||
if (this.streamingSubscription) this.streamingSubscription.unsubscribe();
|
||||
if (this.screenSizeSub) this.screenSizeSub.unsubscribe();
|
||||
if (this.settingsButtonSub) this.settingsButtonSub.unsubscribe();
|
||||
if (this.captionsSubs) this.captionsSubs.unsubscribe();
|
||||
|
@ -537,6 +568,21 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
toggleStreaming() {
|
||||
if (this.streamingStatus === StreamingStatus.STARTED) {
|
||||
this.log.d('Stopping streaming');
|
||||
this.onStopStreamingClicked.emit();
|
||||
this.streamingService.updateStatus(StreamingStatus.STOPPING);
|
||||
} else if (this.streamingStatus === StreamingStatus.STOPPED) {
|
||||
if (this.showActivitiesPanelButton && !this.isActivitiesOpened) {
|
||||
this.toggleActivitiesPanel('streaming');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
@ -660,6 +706,20 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
});
|
||||
}
|
||||
|
||||
private subscribeToStreamingStatus() {
|
||||
this.streamingSubscription = this.streamingService.streamingStatusObs
|
||||
.pipe(skip(1))
|
||||
.subscribe((ev: { status: StreamingStatus, time?: Date } | undefined) => {
|
||||
if (!!ev) {
|
||||
this.streamingStatus = ev.status;
|
||||
if (ev.time) {
|
||||
this.streamingTime = ev.time;
|
||||
}
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private subscribeToToolbarDirectives() {
|
||||
this.minimalSub = this.libService.minimalObs.subscribe((value: boolean) => {
|
||||
this.isMinimal = value;
|
||||
|
@ -685,6 +745,12 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
this.cd.markForCheck();
|
||||
});
|
||||
|
||||
this.streamingButtonSub = this.libService.streamingButtonObs.subscribe((value: boolean) => {
|
||||
this.showStreamingButton = value;
|
||||
this.checkDisplayMoreOptions();
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
|
||||
this.settingsButtonSub = this.libService.toolbarSettingsButtonObs.subscribe((value: boolean) => {
|
||||
this.showSettingsButton = value;
|
||||
this.checkDisplayMoreOptions();
|
||||
|
@ -737,6 +803,10 @@ export class ToolbarComponent implements OnInit, OnDestroy, AfterViewInit {
|
|||
|
||||
private checkDisplayMoreOptions() {
|
||||
this.showMoreOptionsButton =
|
||||
this.showFullscreenButton || this.showBackgroundEffectsButton || this.showRecordingButton || this.showSettingsButton;
|
||||
this.showFullscreenButton ||
|
||||
this.showBackgroundEffectsButton ||
|
||||
this.showRecordingButton ||
|
||||
this.showStreamingButton ||
|
||||
this.showSettingsButton;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
(onActivitiesPanelButtonClicked)="onActivitiesPanelButtonClicked()"
|
||||
(onStartRecordingClicked)="onStartRecordingClicked('toolbar')"
|
||||
(onStopRecordingClicked)="onStopRecordingClicked('toolbar')"
|
||||
(onStopStreamingClicked)="onStopStreamingClicked('toolbar')"
|
||||
>
|
||||
<ng-template #toolbarAdditionalButtons>
|
||||
<ng-container *ngTemplateOutlet="openviduAngularToolbarAdditionalButtonsTemplate"></ng-container>
|
||||
|
@ -99,6 +100,8 @@
|
|||
(onStartRecordingClicked)="onStartRecordingClicked('panel')"
|
||||
(onStopRecordingClicked)="onStopRecordingClicked('panel')"
|
||||
(onDeleteRecordingClicked)="onDeleteRecordingClicked($event)"
|
||||
(onStartStreamingClicked)="onStartStreamingClicked($event)"
|
||||
(onStopStreamingClicked)="onStopStreamingClicked('panel')"
|
||||
></ov-activities-panel>
|
||||
</ng-template>
|
||||
|
||||
|
|
|
@ -383,6 +383,21 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
|||
*/
|
||||
@Output() onActivitiesPanelPlayRecordingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button is clicked from {@link ActivitiesPanelComponent}.
|
||||
*/
|
||||
@Output() onActivitiesPanelStartStreamingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button is clicked from {@link ActivitiesPanelComponent}.
|
||||
*/
|
||||
@Output() onActivitiesPanelStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button is clicked from {@link ToolbarComponent}.
|
||||
*/
|
||||
@Output() onToolbarStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when OpenVidu Session is created.
|
||||
* See {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html openvidu-browser Session}.
|
||||
|
@ -677,6 +692,35 @@ export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewIni
|
|||
this.onActivitiesPanelDeleteRecordingClicked.emit(recordingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onStartStreamingClicked(rtmpUrl: string) {
|
||||
// if (from === 'toolbar') {
|
||||
// this.onToolbarStartRecordingClicked.emit();
|
||||
// } else if (from === 'panel') {
|
||||
this.onActivitiesPanelStartStreamingClicked.emit(rtmpUrl);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onStopStreamingClicked(from: string) {
|
||||
if (from === 'toolbar') {
|
||||
this.onToolbarStopStreamingClicked.emit();
|
||||
} else if (from === 'panel') {
|
||||
this.onActivitiesPanelStopStreamingClicked.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_onSessionCreated(session: Session) {
|
||||
this.onSessionCreated.emit(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Directive, AfterViewInit, OnDestroy, Input, ElementRef } from '@angular/core';
|
||||
import { AfterViewInit, Directive, ElementRef, Input, OnDestroy } from '@angular/core';
|
||||
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
|
||||
|
||||
/**
|
||||
|
@ -49,4 +49,55 @@ export class ActivitiesPanelRecordingActivityDirective implements AfterViewInit,
|
|||
this.libService.recordingActivity.next(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The **streamingActivity** directive allows show/hide the streaming activity in {@link ActivitiesPanelComponent}.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `activitiesPanel` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [activitiesPanelStreamingActivity]="false"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link ActivitiesPanelComponent}.
|
||||
* @example
|
||||
* <ov-activities-panel *ovActivitiesPanel [streamingActivity]="false"></ov-activities-panel>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[activitiesPanelStreamingActivity], ov-activities-panel[streamingActivity]'
|
||||
})
|
||||
export class ActivitiesPanelStreamingActivityDirective implements AfterViewInit, OnDestroy {
|
||||
@Input() set activitiesPanelStreamingActivity(value: boolean) {
|
||||
this.streamingActivityValue = value;
|
||||
this.update(this.streamingActivityValue);
|
||||
}
|
||||
@Input() set streamingActivity(value: boolean) {
|
||||
this.streamingActivityValue = value;
|
||||
this.update(this.streamingActivityValue);
|
||||
}
|
||||
|
||||
streamingActivityValue: boolean = true;
|
||||
|
||||
constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.streamingActivityValue);
|
||||
}
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
clear() {
|
||||
this.streamingActivityValue = true;
|
||||
this.update(true);
|
||||
}
|
||||
|
||||
update(value: boolean) {
|
||||
if (this.libService.streamingActivity.getValue() !== value) {
|
||||
this.libService.streamingActivity.next(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { ActivitiesPanelRecordingActivityDirective } from './activities-panel.directive';
|
||||
import { ActivitiesPanelRecordingActivityDirective, ActivitiesPanelStreamingActivityDirective } from './activities-panel.directive';
|
||||
import { AdminLoginDirective, AdminRecordingsListDirective } from './admin.directive';
|
||||
import { LogoDirective } from './internals.directive';
|
||||
import { ParticipantPanelItemMuteButtonDirective } from './participant-panel-item.directive';
|
||||
|
@ -9,6 +9,7 @@ import {
|
|||
StreamDisplayParticipantNameDirective,
|
||||
StreamSettingsButtonDirective
|
||||
} from './stream.directive';
|
||||
import { StreamingActivityStreamingErrorDirective, StreamingActivityStreamingInfoDirective } from './streaming-activity.directive';
|
||||
import {
|
||||
ToolbarActivitiesPanelButtonDirective,
|
||||
ToolbarBackgroundEffectsButtonDirective,
|
||||
|
@ -21,11 +22,15 @@ import {
|
|||
ToolbarParticipantsPanelButtonDirective,
|
||||
ToolbarRecordingButtonDirective,
|
||||
ToolbarScreenshareButtonDirective,
|
||||
ToolbarSettingsButtonDirective
|
||||
ToolbarSettingsButtonDirective,
|
||||
ToolbarStreamingButtonDirective
|
||||
} from './toolbar.directive';
|
||||
import {
|
||||
AudioMutedDirective,
|
||||
CaptionsLangDirective, CaptionsLangOptionsDirective, LangDirective, MinimalDirective,
|
||||
CaptionsLangDirective,
|
||||
CaptionsLangOptionsDirective,
|
||||
LangDirective,
|
||||
MinimalDirective,
|
||||
ParticipantNameDirective,
|
||||
PrejoinDirective,
|
||||
VideoMutedDirective
|
||||
|
@ -46,6 +51,7 @@ import {
|
|||
ToolbarCaptionsButtonDirective,
|
||||
ToolbarLeaveButtonDirective,
|
||||
ToolbarRecordingButtonDirective,
|
||||
ToolbarStreamingButtonDirective,
|
||||
ToolbarParticipantsPanelButtonDirective,
|
||||
ToolbarChatPanelButtonDirective,
|
||||
ToolbarActivitiesPanelButtonDirective,
|
||||
|
@ -59,8 +65,11 @@ import {
|
|||
ParticipantPanelItemMuteButtonDirective,
|
||||
ParticipantNameDirective,
|
||||
ActivitiesPanelRecordingActivityDirective,
|
||||
ActivitiesPanelStreamingActivityDirective,
|
||||
RecordingActivityRecordingsListDirective,
|
||||
RecordingActivityRecordingErrorDirective,
|
||||
StreamingActivityStreamingErrorDirective,
|
||||
StreamingActivityStreamingInfoDirective,
|
||||
AdminRecordingsListDirective,
|
||||
AdminLoginDirective
|
||||
],
|
||||
|
@ -78,6 +87,7 @@ import {
|
|||
ToolbarCaptionsButtonDirective,
|
||||
ToolbarLeaveButtonDirective,
|
||||
ToolbarRecordingButtonDirective,
|
||||
ToolbarStreamingButtonDirective,
|
||||
ToolbarParticipantsPanelButtonDirective,
|
||||
ToolbarChatPanelButtonDirective,
|
||||
ToolbarActivitiesPanelButtonDirective,
|
||||
|
@ -91,8 +101,11 @@ import {
|
|||
ParticipantPanelItemMuteButtonDirective,
|
||||
ParticipantNameDirective,
|
||||
ActivitiesPanelRecordingActivityDirective,
|
||||
ActivitiesPanelStreamingActivityDirective,
|
||||
RecordingActivityRecordingsListDirective,
|
||||
RecordingActivityRecordingErrorDirective,
|
||||
StreamingActivityStreamingErrorDirective,
|
||||
StreamingActivityStreamingInfoDirective,
|
||||
AdminRecordingsListDirective,
|
||||
AdminLoginDirective
|
||||
]
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
import { AfterViewInit, Directive, ElementRef, Input, OnDestroy } from '@angular/core';
|
||||
import { StreamingError, StreamingInfo, StreamingStatus } from '../../models/streaming.model';
|
||||
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
|
||||
|
||||
|
||||
/**
|
||||
* The **streamingError** directive allows to show any possible error with the streaming in the {@link StreamingActivityComponent}.
|
||||
*
|
||||
* Default: `undefined`
|
||||
*
|
||||
* Type: {@link StreamingError}
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `streamingActivity` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [streamingActivityStreamingError]="error"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link StreamingActivityComponent}.
|
||||
* @example
|
||||
* <ov-streaming-activity [streamingError]="error"></ov-streaming-activity>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[streamingActivityStreamingError], ov-streaming-activity[streamingError]'
|
||||
})
|
||||
export class StreamingActivityStreamingErrorDirective implements AfterViewInit, OnDestroy {
|
||||
@Input() set streamingActivityStreamingError(value: StreamingError) {
|
||||
this.streamingErrorValue = value;
|
||||
this.update(this.streamingErrorValue);
|
||||
}
|
||||
@Input() set streamingError(value: StreamingError) {
|
||||
this.streamingErrorValue = value;
|
||||
this.update(this.streamingErrorValue);
|
||||
}
|
||||
|
||||
streamingErrorValue: StreamingError | undefined = undefined;
|
||||
|
||||
constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.streamingErrorValue);
|
||||
}
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
clear() {
|
||||
this.streamingErrorValue = undefined;
|
||||
this.update(undefined);
|
||||
}
|
||||
|
||||
update(value: StreamingError | undefined) {
|
||||
if (this.libService.streamingError.getValue() !== value) {
|
||||
this.libService.streamingError.next(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Remove this directive when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
|
||||
/**
|
||||
* The **streamingInfo** directive allows show the live streaming info in {@link StreamingActivityComponent}.
|
||||
*
|
||||
* Default: `undefined`
|
||||
*
|
||||
* Type: {@link StreamingInfo}
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `streamingActivity` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [streamingActivityStreamingInfo]="info"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link StreamingActivityComponent}.
|
||||
* @example
|
||||
* <ov-streaming-activity [streamingInfo]="info"></ov-streaming-activity>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[streamingActivityStreamingInfo], ov-streaming-activity[streamingInfo]'
|
||||
})
|
||||
export class StreamingActivityStreamingInfoDirective implements AfterViewInit, OnDestroy {
|
||||
@Input() set streamingActivityStreamingInfo(value: StreamingInfo) {
|
||||
this.streamingValue = value;
|
||||
this.update(this.streamingValue);
|
||||
}
|
||||
@Input() set streamingInfo(value: StreamingInfo) {
|
||||
this.streamingValue = value;
|
||||
this.update(this.streamingValue);
|
||||
}
|
||||
|
||||
streamingValue: StreamingInfo | undefined = undefined;
|
||||
|
||||
constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.streamingValue);
|
||||
}
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
clear() {
|
||||
this.streamingValue = undefined;
|
||||
this.update(undefined);
|
||||
}
|
||||
|
||||
update(value: StreamingInfo | undefined) {
|
||||
if (this.libService.streamingInfo.getValue() !== value) {
|
||||
if(value) {
|
||||
// Forced value to right enum
|
||||
const index = Object.values(StreamingStatus).indexOf(value.status.toLowerCase() as unknown as StreamingStatus);
|
||||
const key = Object.keys(StreamingStatus)[index];
|
||||
value.status = StreamingStatus[key];
|
||||
}
|
||||
this.libService.streamingInfo.next(value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -124,6 +124,66 @@ export class ToolbarRecordingButtonDirective implements AfterViewInit, OnDestroy
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The **streamingButton** directive allows show/hide the start/stop streaming toolbar button.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* It can be used in the parent element {@link VideoconferenceComponent} specifying the name of the `toolbar` component:
|
||||
*
|
||||
* @example
|
||||
* <ov-videoconference [toolbarStreamingButton]="false"></ov-videoconference>
|
||||
*
|
||||
* \
|
||||
* And it also can be used in the {@link ToolbarComponent}.
|
||||
* @example
|
||||
* <ov-toolbar [streamingButton]="false"></ov-toolbar>
|
||||
*
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ov-videoconference[toolbarStreamingButton], ov-toolbar[streamingButton]'
|
||||
})
|
||||
export class ToolbarStreamingButtonDirective implements AfterViewInit, OnDestroy {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set toolbarStreamingButton(value: boolean) {
|
||||
this.streamingValue = value;
|
||||
this.update(this.streamingValue);
|
||||
}
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
@Input() set streamingButton(value: boolean) {
|
||||
this.streamingValue = value;
|
||||
this.update(this.streamingValue);
|
||||
}
|
||||
private streamingValue: boolean = true;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
constructor(public elementRef: ElementRef, private libService: OpenViduAngularConfigService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.update(this.streamingValue);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
private clear() {
|
||||
this.streamingValue = true;
|
||||
this.update(true);
|
||||
}
|
||||
|
||||
private update(value: boolean) {
|
||||
if (this.libService.streamingButton.getValue() !== value) {
|
||||
this.libService.streamingButton.next(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The **fullscreenButton** directive allows show/hide the fullscreen toolbar button.
|
||||
*
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "关闭",
|
||||
"SEE_MORE": "查看更多",
|
||||
"PRO_FEATURE": "此功能属于OpenVidu PRO级别",
|
||||
"PAID_FEATURE": "此功能是 OpenVidu 商业服务的一部分。请通过 commercial@openvidu.io 联系我们了解更多信息。",
|
||||
"CHAT": {
|
||||
"TITLE": "聊天",
|
||||
"YOU": "你",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "下载",
|
||||
"RECORDINGS": "录制",
|
||||
"NO_MODERATOR": "只有主持人可以开始录音"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "直播",
|
||||
"SUBTITLE": "将会议直播给观众",
|
||||
"CONTENT_SUBTITLE": "OpenVidu需要RTMP直播平台的URL。",
|
||||
"START": "开始直播",
|
||||
"STOP": "结束直播",
|
||||
"URL": "输入您的RTMP URL",
|
||||
"CANCEL": "取消",
|
||||
"REQUIRED_URL": "RTMP url 是必需的",
|
||||
"NO_MODERATOR": "只有主持人才能开始流媒体"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Schließen",
|
||||
"SEE_MORE": "Mehr sehen",
|
||||
"PRO_FEATURE": "Diese Funktion ist Teil des OpenVidu PRO-Tiers",
|
||||
"PAID_FEATURE": "Diese Funktion ist Teil des kommerziellen Dienstes von OpenVidu. Bitte kontaktieren Sie uns über commercial@openvidu.io für weitere Informationen.",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "Sie",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "Download",
|
||||
"RECORDINGS": "AUFZEICHNUNGEN",
|
||||
"NO_MODERATOR": "Nur der MODERATOR kann die Aufzeichnung starten"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Streaming",
|
||||
"SUBTITLE": "Streamen Sie Ihr Meeting an Ihr Publikum",
|
||||
"CONTENT_SUBTITLE": "OpenVidu benötigt die RTMP-URL der Streaming-Plattform.",
|
||||
"START": "Streaming starten",
|
||||
"STOP": "Streaming beenden",
|
||||
"URL": "Geben Sie Ihre RTMP-URL ein",
|
||||
"CANCEL": "Absagen",
|
||||
"REQUIRED_URL": "RTMP url ist erforderlich",
|
||||
"NO_MODERATOR": "Nur der Moderator kann den Stream starten"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Close",
|
||||
"SEE_MORE": "See more",
|
||||
"PRO_FEATURE": "This feature is part of OpenVidu PRO tier",
|
||||
"PAID_FEATURE": "This feature is part of OpenVidu commercial service. Please contact us through commercial@openvidu.io for more information.",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "You",
|
||||
|
@ -102,6 +103,17 @@
|
|||
"DOWNLOAD": "Download",
|
||||
"RECORDINGS": "RECORDINGS",
|
||||
"NO_MODERATOR": "Only the MODERATOR can start the recording"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Streaming",
|
||||
"SUBTITLE": "Stream your meeting to your audience",
|
||||
"CONTENT_SUBTITLE": "OpenVidu need the RTMP url of the streaming platform.",
|
||||
"START": "Start streaming",
|
||||
"STOP": "End streaming",
|
||||
"URL": "Insert your RTMP url",
|
||||
"CANCEL": "Cancel",
|
||||
"REQUIRED_URL": "The RTMP url is required",
|
||||
"NO_MODERATOR": "Only the MODERATOR can start the streaming"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Cerrar",
|
||||
"SEE_MORE": "Ver más",
|
||||
"PRO_FEATURE": "Esta funcionalidad es parte de OpenVidu PRO",
|
||||
"PAID_FEATURE": "Esta función es parte del servicio comercial de OpenVidu. Contáctenos a través de commercial@openvidu.io para obtener más información",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "Tú",
|
||||
|
@ -101,6 +102,16 @@
|
|||
"DOWNLOAD": "Descargar",
|
||||
"RECORDINGS": "GRABACIONES",
|
||||
"NO_MODERATOR": "Sólo el MODERADOR puede iniciar la grabación"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Streaming",
|
||||
"SUBTITLE": "Comparte tu llamada con tu público",
|
||||
"CONTENT_SUBTITLE": "OpenVidu necesita la url RTMP de tu plataforma de streaming.",
|
||||
"START": "Empezar streaming",
|
||||
"STOP": "Finalizar streaming",
|
||||
"URL": "Inserta tu url RTMP",
|
||||
"CANCEL": "Cancelar",
|
||||
"NO_MODERATOR": "Solo el MODERADOR puede iniciar el streaming"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Fermer",
|
||||
"SEE_MORE": "Voir plus",
|
||||
"PRO_FEATURE": "Cette fonctionnalité fait partie de la gamme OpenVidu PRO",
|
||||
"PAID_FEATURE": "Cette fonctionnalité fait partie du service commercial d'OpenVidu. Veuillez nous contacter via commercial@openvidu.io pour plus d'informations.",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "Vous",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "Télécharger",
|
||||
"RECORDINGS": "ENREGISTREMENTS",
|
||||
"NO_MODERATOR": "Seul le MODERATEUR peut lancer l'enregistrement"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Diffusion",
|
||||
"SUBTITLE": "Diffusez votre réunion à votre public",
|
||||
"CONTENT_SUBTITLE": "OpenVidu a besoin de l'URL RTMP de la plateforme de diffusion.",
|
||||
"START": "Démarrer la diffusion",
|
||||
"STOP": "Arrêter la diffusion",
|
||||
"URL": "Insérez votre URL RTMP",
|
||||
"CANCEL": "Annuler",
|
||||
"REQUIRED_URL": "L'URL RTMP est obligatoire",
|
||||
"NO_MODERATOR": "Seul le MODÉRATEUR peut démarrer le streaming"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "बंद करें",
|
||||
"SEE_MORE": "और देखें",
|
||||
"PRO_FEATURE": "यह सुविधा OpenVidu PRO टायर का हिस्सा है",
|
||||
"PAID_FEATURE": "यह सुविधा OpenVidu वाणिज्यिक सेवा का हिस्सा है। अधिक जानकारी के लिए कृपया commercial@openvidu.io के माध्यम से हमसे संपर्क करें।",
|
||||
"CHAT": {
|
||||
"TITLE": "बातचीत",
|
||||
"YOU": "आप",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "डाउनलोड",
|
||||
"RECORDINGS": "रिकॉर्डिंग",
|
||||
"NO_MODERATOR": "केवल मॉडरेटर ही रिकॉर्डिंग शुरू कर सकता है"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "स्ट्रीमिंग",
|
||||
"SUBTITLE": "अपने मीटिंग को अपने दर्शकों को स्ट्रीम करें",
|
||||
"CONTENT_SUBTITLE": "OpenVidu को स्ट्रीमिंग प्लेटफॉर्म के RTMP url की आवश्यकता है।",
|
||||
"START": "स्ट्रीमिंग शुरू करें",
|
||||
"STOP": "स्ट्रीमिंग बंद करें",
|
||||
"URL": "अपना RTMP url दर्ज करें",
|
||||
"CANCEL": "रद्द करें",
|
||||
"REQUIRED_URL": "RTMP url आवश्यक है",
|
||||
"NO_MODERATOR": "केवल मोडेरेटर स्ट्रीमिंग शुरू कर सकते हैं"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Chiudi",
|
||||
"SEE_MORE": "Vedi di più",
|
||||
"PRO_FEATURE": "Questa funzione fa parte del livello OpenVidu PRO",
|
||||
"PAID_FEATURE": "Questa funzione fa parte del servizio commerciale di OpenVidu. Per ulteriori informazioni, contattaci tramite commercial@openvidu.io.",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "Tu",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "Scarica",
|
||||
"RECORDINGS": "REGISTRAZIONI",
|
||||
"NO_MODERATOR": "Solo il MODERATORE può avviare la registrazione"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Streaming",
|
||||
"SUBTITLE": "Trasmetti in streaming la tua riunione al tuo pubblico",
|
||||
"CONTENT_SUBTITLE": "OpenVidu necessita dell'URL RTMP della piattaforma di streaming",
|
||||
"START": "Avvia lo streaming",
|
||||
"STOP": "Termina lo streaming",
|
||||
"URL": "Inserisci il tuo URL RTMP",
|
||||
"CANCEL": "Annulla",
|
||||
"REQUIRED_URL": "RTMP url è obbligatorio",
|
||||
"NO_MODERATOR": "Solo il MODERATORE può iniziare la trasmissione"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "閉じる",
|
||||
"PRO_FEATURE": "この機能はOpenVidu PROの機能です",
|
||||
"SEE_MORE": "もっと見る",
|
||||
"PAID_FEATURE": "この機能は、OpenVidu 商用サービスの一部です。詳細については、commercial@openvidu.io までお問い合わせください。",
|
||||
"CHAT": {
|
||||
"TITLE": "チャット",
|
||||
"YOU": "あなた",
|
||||
|
@ -101,6 +102,18 @@
|
|||
"DOWNLOAD": "ダウンロード",
|
||||
"RECORDINGS": "録画",
|
||||
"NO_MODERATOR": "録音を開始できるのは、モデレーターのみです"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "ストリーミング",
|
||||
"SUBTITLE": "会議を観客にストリーミング",
|
||||
"CONTENT_SUBTITLE": "OpenViduはストリーミングプラットフォームのRTMP URLが必要です。",
|
||||
"START": "ストリーミングを開始",
|
||||
"STOP": "ストリーミングを終了",
|
||||
"URL": "RTMP URLを入力してください",
|
||||
"CANCEL": "キャンセル",
|
||||
"REQUIRED_URL": "RTMP url は必須です",
|
||||
"NO_MODERATOR": "モデレーターのみがストリーミングを開始できます"
|
||||
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Sluiten",
|
||||
"SEE_MORE": "Zie meer",
|
||||
"PRO_FEATURE": "Deze functie is onderdeel van OpenVidu PRO tier",
|
||||
"PAID_FEATURE": "Deze functie maakt deel uit van de commerciële service van OpenVidu. Neem voor meer informatie contact met ons op via commercial@openvidu.io.",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "Jij",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "Downloaden",
|
||||
"RECORDINGS": "OPNAME",
|
||||
"NO_MODERATOR": "Alleen de MOEDERATOR kan de opname starten"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Streamen",
|
||||
"SUBTITLE": "Stream je meeting naar je publiek",
|
||||
"CONTENT_SUBTITLE": "OpenVidu heeft de RTMP url van de streaming platform nodig.",
|
||||
"START": "Start streamen",
|
||||
"STOP": "Stop streamen",
|
||||
"URL": "Voer je RTMP url in",
|
||||
"CANCEL": "Annuleren",
|
||||
"REQUIRED_URL": "RTMP url is verplicht",
|
||||
"NO_MODERATOR": "Alleen de moderator kan de streaming starten"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
"CLOSE": "Fechar",
|
||||
"SEE_MORE": "Ver mais",
|
||||
"PRO_FEATURE": "Esta funcionalidade é parte do OpenVidu PRO tier",
|
||||
"PAID_FEATURE": "Este recurso faz parte do serviço comercial OpenVidu. Entre em contato conosco através de commercial@openvidu.io para obter mais informações.",
|
||||
"CHAT": {
|
||||
"TITLE": "Chat",
|
||||
"YOU": "Você",
|
||||
|
@ -101,6 +102,17 @@
|
|||
"DOWNLOAD": "Download",
|
||||
"RECORDINGS": "GRAVAÇÕES",
|
||||
"NO_MODERATOR": "Só o MODERADOR pode iniciar a gravação"
|
||||
},
|
||||
"STREAMING": {
|
||||
"TITLE": "Streaming",
|
||||
"SUBTITLE": "Transmita sua reunião para seu público",
|
||||
"CONTENT_SUBTITLE": "O OpenVidu precisa da url RTMP da plataforma de streaming.",
|
||||
"START": "Iniciar transmissão",
|
||||
"STOP": "Finalizar transmissão",
|
||||
"URL": "Insira seu url RTMP",
|
||||
"CANCEL": "Cancelar",
|
||||
"REQUIRED_URL": "O URL RTMP é obrigatório",
|
||||
"NO_MODERATOR": "Somente o MODERADOR pode iniciar a transmissão"
|
||||
}
|
||||
},
|
||||
"ERRORS": {
|
||||
|
|
|
@ -7,6 +7,13 @@ export enum PanelType {
|
|||
|
||||
}
|
||||
|
||||
export interface PanelEvent {
|
||||
opened: boolean;
|
||||
type?: PanelType | string;
|
||||
expand?: string;
|
||||
oldType?: PanelType | string;
|
||||
}
|
||||
|
||||
export enum PanelSettingsOptions {
|
||||
GENERAL = 'general',
|
||||
AUDIO = 'audio',
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
*/
|
||||
export enum Signal {
|
||||
NICKNAME_CHANGED = 'nicknameChanged',
|
||||
CHAT = 'chat'
|
||||
CHAT = 'chat',
|
||||
|
||||
//TODO: Remove them when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
STREAMING_STARTED = "streamingStarted",
|
||||
STREAMING_STOPPED = "streamingStopped"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
export enum StreamingStatus {
|
||||
STARTING = 'starting',
|
||||
STARTED = 'started',
|
||||
STOPPING = 'stopping',
|
||||
STOPPED = 'stopped',
|
||||
FAILED = 'failed'
|
||||
}
|
||||
|
||||
|
||||
export interface StreamingInfo {
|
||||
id: string,
|
||||
status: StreamingStatus
|
||||
}
|
||||
|
||||
|
||||
export interface StreamingError {
|
||||
message: string,
|
||||
// If streaming service is available or not
|
||||
rtmpAvailable: boolean
|
||||
}
|
|
@ -50,6 +50,7 @@ import { CaptionsComponent } from './components/captions/captions.component';
|
|||
import { ProFeatureDialogTemplateComponent } from './components/dialogs/pro-feature-dialog.component';
|
||||
import { ActivitiesPanelComponent } from './components/panel/activities-panel/activities-panel.component';
|
||||
import { RecordingActivityComponent } from './components/panel/activities-panel/recording-activity/recording-activity.component';
|
||||
import { StreamingActivityComponent } from './components/panel/activities-panel/streaming-activity/streaming-activity.component';
|
||||
import { BackgroundEffectsPanelComponent } from './components/panel/background-effects-panel/background-effects-panel.component';
|
||||
import { SettingsPanelComponent } from './components/panel/settings-panel/settings-panel.component';
|
||||
import { AudioDevicesComponent } from './components/settings/audio-devices/audio-devices.component';
|
||||
|
@ -69,6 +70,8 @@ const publicComponents = [
|
|||
ToolbarComponent,
|
||||
PanelComponent,
|
||||
ActivitiesPanelComponent,
|
||||
RecordingActivityComponent,
|
||||
StreamingActivityComponent,
|
||||
ParticipantsPanelComponent,
|
||||
ParticipantPanelItemComponent,
|
||||
ChatPanelComponent,
|
||||
|
@ -92,7 +95,6 @@ const privateComponents = [
|
|||
AudioDevicesComponent,
|
||||
NicknameInputComponent,
|
||||
LangSelectorComponent,
|
||||
RecordingActivityComponent,
|
||||
CaptionsSettingComponent
|
||||
];
|
||||
|
||||
|
|
|
@ -9,8 +9,13 @@ export class TranslatePipe implements PipeTransform {
|
|||
constructor(private translateService: TranslateService) {}
|
||||
|
||||
transform(str: string): string {
|
||||
|
||||
const translation = this.translateService.translate(str);
|
||||
return translation.replace('OpenVidu PRO', '<a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank">OpenVidu PRO</a>');
|
||||
if (translation?.includes('OpenVidu PRO')) {
|
||||
return translation.replace(
|
||||
'OpenVidu PRO',
|
||||
'<a href="https://docs.openvidu.io/en/stable/openvidu-pro/" target="_blank">OpenVidu PRO</a>'
|
||||
);
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Inject, Injectable } from '@angular/core';
|
|||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { OpenViduAngularConfig, ParticipantFactoryFunction } from '../../config/openvidu-angular.config';
|
||||
import { RecordingInfo } from '../../models/recording.model';
|
||||
import { StreamingError, StreamingInfo } from '../../models/streaming.model';
|
||||
|
||||
// import { version } from '../../../../package.json';
|
||||
|
||||
|
@ -61,15 +62,25 @@ export class OpenViduAngularConfigService {
|
|||
participantItemMuteButtonObs: Observable<boolean>;
|
||||
backgroundEffectsButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
backgroundEffectsButtonObs: Observable<boolean>;
|
||||
recordingsList = <BehaviorSubject<RecordingInfo[]>>new BehaviorSubject([]);
|
||||
recordingsList: BehaviorSubject<RecordingInfo[]> = new BehaviorSubject(<RecordingInfo[]>[]);
|
||||
recordingsListObs: Observable<RecordingInfo[]>;
|
||||
recordingButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
recordingButtonObs: Observable<boolean>;
|
||||
streamingButton = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
streamingButtonObs: Observable<boolean>;
|
||||
recordingActivity = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
recordingActivityObs: Observable<boolean>;
|
||||
streamingActivity = <BehaviorSubject<boolean>>new BehaviorSubject(true);
|
||||
streamingActivityObs: Observable<boolean>;
|
||||
recordingError = <BehaviorSubject<any>>new BehaviorSubject(null);
|
||||
recordingErrorObs: Observable<any>;
|
||||
adminRecordingsList = <BehaviorSubject<RecordingInfo[]>>new BehaviorSubject([]);
|
||||
streamingErrorObs: Observable<StreamingError | undefined>;
|
||||
streamingError = <BehaviorSubject<StreamingError | undefined>>new BehaviorSubject(undefined);
|
||||
streamingInfo = <BehaviorSubject<StreamingInfo | undefined>>new BehaviorSubject(undefined);
|
||||
|
||||
//TODO: Remove this directive when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
streamingInfoObs: Observable<StreamingInfo | undefined>;
|
||||
adminRecordingsList: BehaviorSubject<RecordingInfo[]> = new BehaviorSubject(<RecordingInfo[]>[]);
|
||||
adminRecordingsListObs: Observable<RecordingInfo[]>;
|
||||
adminLoginError = <BehaviorSubject<any>>new BehaviorSubject(null);
|
||||
adminLoginErrorObs: Observable<any>;
|
||||
|
@ -94,6 +105,7 @@ export class OpenViduAngularConfigService {
|
|||
this.displaySessionNameObs = this.displaySessionName.asObservable();
|
||||
this.displayLogoObs = this.displayLogo.asObservable();
|
||||
this.recordingButtonObs = this.recordingButton.asObservable();
|
||||
this.streamingButtonObs = this.streamingButton.asObservable();
|
||||
this.toolbarSettingsButtonObs = this.toolbarSettingsButton.asObservable();
|
||||
this.captionsButtonObs = this.captionsButton.asObservable();
|
||||
//Stream observables
|
||||
|
@ -106,6 +118,10 @@ export class OpenViduAngularConfigService {
|
|||
this.recordingActivityObs = this.recordingActivity.asObservable();
|
||||
this.recordingsListObs = this.recordingsList.asObservable();
|
||||
this.recordingErrorObs = this.recordingError.asObservable();
|
||||
// Streaming activity
|
||||
this.streamingActivityObs = this.streamingActivity.asObservable();
|
||||
this.streamingErrorObs = this.streamingError.asObservable();
|
||||
this.streamingInfoObs = this.streamingInfo.asObservable();
|
||||
// Admin dashboard
|
||||
this.adminRecordingsListObs = this.adminRecordingsList.asObservable();
|
||||
this.adminLoginErrorObs = this.adminLoginError.asObservable();
|
||||
|
@ -125,4 +141,12 @@ export class OpenViduAngularConfigService {
|
|||
getParticipantFactory(): ParticipantFactoryFunction {
|
||||
return this.getConfig().participantFactory;
|
||||
}
|
||||
|
||||
isRecordingEnabled(): boolean {
|
||||
return this.recordingButton.getValue() && this.recordingActivity.getValue();
|
||||
}
|
||||
|
||||
isStreamingEnabled(): boolean {
|
||||
return this.streamingButton.getValue() && this.streamingActivity.getValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { ILogger } from '../../models/logger.model';
|
||||
import { PanelSettingsOptions, PanelType } from '../../models/panel.model';
|
||||
import { PanelEvent, PanelSettingsOptions, PanelType } from '../../models/panel.model';
|
||||
import { LoggerService } from '../logger/logger.service';
|
||||
|
||||
export interface PanelEvent {
|
||||
opened: boolean;
|
||||
type?: PanelType | string;
|
||||
expand?: string;
|
||||
oldType?: PanelType | string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||
import { Publisher, Subscriber } from 'openvidu-browser';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { ILogger } from '../../models/logger.model';
|
||||
import { ParticipantAbstractModel, ParticipantModel, ParticipantProperties, StreamModel } from '../../models/participant.model';
|
||||
import { OpenViduRole, ParticipantAbstractModel, ParticipantModel, ParticipantProperties, StreamModel } from '../../models/participant.model';
|
||||
import { VideoType } from '../../models/video-type.model';
|
||||
import { OpenViduAngularConfigService } from '../config/openvidu-angular.config.service';
|
||||
import { LoggerService } from '../logger/logger.service';
|
||||
|
@ -156,6 +156,10 @@ export class ParticipantService {
|
|||
return this.localParticipant.getRole();
|
||||
}
|
||||
|
||||
amIModerator(): boolean {
|
||||
return this.getMyRole() === OpenViduRole.MODERATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -14,10 +14,10 @@ export class RecordingService {
|
|||
*/
|
||||
recordingStatusObs: Observable<{ info: RecordingInfo; time?: Date }>;
|
||||
|
||||
private recordingTime: Date;
|
||||
private recordingTime: Date | undefined;
|
||||
private recordingTimeInterval: NodeJS.Timer;
|
||||
private currentRecording: RecordingInfo = { status: RecordingStatus.STOPPED };
|
||||
private recordingStatus = <BehaviorSubject<{ info: RecordingInfo; time?: Date }>>new BehaviorSubject(null);
|
||||
private recordingStatus = <BehaviorSubject<{ info: RecordingInfo; time?: Date | undefined } | undefined>>new BehaviorSubject(undefined);
|
||||
private baseUrl = '/' + (!!window.location.pathname.split('/')[1] ? window.location.pathname.split('/')[1] + '/' : '');
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ export class RecordingService {
|
|||
stopRecording(event: RecordingEvent) {
|
||||
this.currentRecording.status = RecordingStatus.STOPPED;
|
||||
this.currentRecording.reason = event.reason;
|
||||
this.recordingStatus.next({ info: this.currentRecording, time: null });
|
||||
this.recordingStatus.next({ info: this.currentRecording, time: undefined });
|
||||
this.stopRecordingTime();
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,6 @@ export class RecordingService {
|
|||
|
||||
private stopRecordingTime() {
|
||||
clearInterval(this.recordingTimeInterval);
|
||||
this.recordingTime = null;
|
||||
this.recordingTime = undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { StreamingService } from './streaming.service';
|
||||
|
||||
describe('StreamingService', () => {
|
||||
let service: StreamingService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(StreamingService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { StreamingStatus } from '../../models/streaming.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class StreamingService {
|
||||
/**
|
||||
* Streaming status Observable which pushes the streaming state in every update.
|
||||
*/
|
||||
streamingStatusObs: Observable<{ status: StreamingStatus; time?: Date } | undefined>;
|
||||
|
||||
private streamingTime: Date | undefined;
|
||||
private streamingTimeInterval: NodeJS.Timer;
|
||||
private streamingStatus = <BehaviorSubject<{ status: StreamingStatus; time?: Date } | undefined>>new BehaviorSubject(undefined);
|
||||
|
||||
constructor() {
|
||||
this.streamingStatusObs = this.streamingStatus.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param status
|
||||
*/
|
||||
updateStatus(status: StreamingStatus) {
|
||||
if (status === StreamingStatus.STARTED) {
|
||||
this.startStreamingTime();
|
||||
} else {
|
||||
this.stopStreamingTime();
|
||||
}
|
||||
this.streamingStatus.next({ status, time: this.streamingTime });
|
||||
}
|
||||
|
||||
private startStreamingTime() {
|
||||
this.streamingTime = new Date();
|
||||
this.streamingTime.setHours(0, 0, 0, 0);
|
||||
this.streamingTimeInterval = setInterval(() => {
|
||||
this.streamingTime?.setSeconds(this.streamingTime.getSeconds() + 1);
|
||||
this.streamingTime = new Date(this.streamingTime.getTime());
|
||||
this.streamingStatus.next({ status: this.streamingStatus.getValue()?.status, time: this.streamingTime });
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private stopStreamingTime() {
|
||||
clearInterval(this.streamingTimeInterval);
|
||||
this.streamingTime = undefined;
|
||||
}
|
||||
}
|
|
@ -55,7 +55,7 @@ export class TranslateService {
|
|||
return this.langTitles;
|
||||
}
|
||||
|
||||
translate(key: string) {
|
||||
translate(key: string): string {
|
||||
let result = this.currentLang;
|
||||
|
||||
key.split('.').forEach((prop) => {
|
||||
|
|
|
@ -2,53 +2,53 @@
|
|||
* Public API Surface of openvidu-components-angular
|
||||
*/
|
||||
|
||||
export * from './lib/openvidu-angular.module';
|
||||
|
||||
// Services
|
||||
export * from './lib/services/openvidu/openvidu.service';
|
||||
export * from './lib/services/participant/participant.service';
|
||||
export * from './lib/services/chat/chat.service';
|
||||
export * from './lib/services/action/action.service';
|
||||
export * from './lib/services/layout/layout.service';
|
||||
export * from './lib/services/panel/panel.service';
|
||||
export * from './lib/services/recording/recording.service';
|
||||
|
||||
// Components
|
||||
export * from './lib/components/videoconference/videoconference.component';
|
||||
export * from './lib/components/toolbar/toolbar.component';
|
||||
export * from './lib/components/panel/panel.component';
|
||||
export * from './lib/components/panel/activities-panel/activities-panel.component';
|
||||
export * from './lib/components/panel/chat-panel/chat-panel.component';
|
||||
export * from './lib/components/panel/participants-panel/participants-panel/participants-panel.component';
|
||||
export * from './lib/components/panel/participants-panel/participant-panel-item/participant-panel-item.component';
|
||||
export * from './lib/components/layout/layout.component';
|
||||
export * from './lib/components/stream/stream.component';
|
||||
export * from './lib/admin/dashboard/dashboard.component';
|
||||
export * from './lib/admin/login/login.component';
|
||||
|
||||
// Models
|
||||
export * from './lib/models/participant.model';
|
||||
export * from './lib/components/layout/layout.component';
|
||||
export * from './lib/components/panel/activities-panel/activities-panel.component';
|
||||
export * from './lib/components/panel/activities-panel/recording-activity/recording-activity.component';
|
||||
export * from './lib/components/panel/activities-panel/streaming-activity/streaming-activity.component';
|
||||
export * from './lib/components/panel/chat-panel/chat-panel.component';
|
||||
export * from './lib/components/panel/panel.component';
|
||||
export * from './lib/components/panel/participants-panel/participant-panel-item/participant-panel-item.component';
|
||||
export * from './lib/components/panel/participants-panel/participants-panel/participants-panel.component';
|
||||
export * from './lib/components/stream/stream.component';
|
||||
export * from './lib/components/toolbar/toolbar.component';
|
||||
export * from './lib/components/videoconference/videoconference.component';
|
||||
export * from './lib/config/openvidu-angular.config';
|
||||
export * from './lib/models/video-type.model';
|
||||
export * from './lib/models/token.model';
|
||||
export * from './lib/models/signal.model';
|
||||
// Directives
|
||||
export * from './lib/directives/api/activities-panel.directive';
|
||||
export * from './lib/directives/api/admin.directive';
|
||||
export * from './lib/directives/api/api.directive.module';
|
||||
export * from './lib/directives/api/internals.directive';
|
||||
export * from './lib/directives/api/participant-panel-item.directive';
|
||||
export * from './lib/directives/api/recording-activity.directive';
|
||||
export * from './lib/directives/api/stream.directive';
|
||||
export * from './lib/directives/api/streaming-activity.directive';
|
||||
export * from './lib/directives/api/toolbar.directive';
|
||||
export * from './lib/directives/api/videoconference.directive';
|
||||
export * from './lib/directives/template/openvidu-angular.directive';
|
||||
export * from './lib/directives/template/openvidu-angular.directive.module';
|
||||
// Models
|
||||
export * from './lib/models/panel.model';
|
||||
export * from './lib/models/participant.model';
|
||||
export * from './lib/models/recording.model';
|
||||
|
||||
export * from './lib/models/signal.model';
|
||||
export * from './lib/models/streaming.model';
|
||||
export * from './lib/models/token.model';
|
||||
export * from './lib/models/video-type.model';
|
||||
export * from './lib/openvidu-angular.module';
|
||||
// Pipes
|
||||
export * from './lib/pipes/participant.pipe';
|
||||
export * from './lib/pipes/recording.pipe';
|
||||
// Services
|
||||
export * from './lib/services/action/action.service';
|
||||
export * from './lib/services/chat/chat.service';
|
||||
export * from './lib/services/layout/layout.service';
|
||||
export * from './lib/services/openvidu/openvidu.service';
|
||||
export * from './lib/services/panel/panel.service';
|
||||
export * from './lib/services/participant/participant.service';
|
||||
export * from './lib/services/recording/recording.service';
|
||||
export * from './lib/services/streaming/streaming.service';
|
||||
|
||||
// Directives
|
||||
export * from './lib/directives/template/openvidu-angular.directive.module';
|
||||
export * from './lib/directives/template/openvidu-angular.directive';
|
||||
|
||||
export * from './lib/directives/api/api.directive.module';
|
||||
export * from './lib/directives/api/internals.directive';
|
||||
export * from './lib/directives/api/toolbar.directive';
|
||||
export * from './lib/directives/api/stream.directive';
|
||||
export * from './lib/directives/api/videoconference.directive';
|
||||
export * from './lib/directives/api/participant-panel-item.directive';
|
||||
export * from './lib/directives/api/activities-panel.directive';
|
||||
export * from './lib/directives/api/recording-activity.directive';
|
||||
export * from './lib/directives/api/admin.directive';
|
||||
|
|
|
@ -19,8 +19,8 @@ export class AdminDashboardComponent implements OnInit {
|
|||
this.logged = true;
|
||||
this.recordings = resp.recordings;
|
||||
} catch (error) {
|
||||
|
||||
this.logged = true;
|
||||
this.logged = false;
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,34 @@
|
|||
<ov-videoconference
|
||||
[tokens]="tokens"
|
||||
[minimal]="false"
|
||||
[lang]="'en'"
|
||||
[captionsLang]=""
|
||||
[captionsLangOptions]="[{ name: 'Spanish', ISO: 'es-ES' },{ name: 'English', ISO: 'en-US' }]"
|
||||
[prejoin]="false"
|
||||
[participantName]="'Participant'"
|
||||
[videoMuted]="false"
|
||||
[audioMuted]="false"
|
||||
[toolbarScreenshareButton]="true"
|
||||
[toolbarFullscreenButton]="true"
|
||||
[toolbarCaptionsButton]="true"
|
||||
[toolbarRecordingButton]="true"
|
||||
[toolbarStreamingButton]="true"
|
||||
[toolbarBackgroundEffectsButton]="true"
|
||||
[toolbarLeaveButton]="true"
|
||||
[toolbarChatPanelButton]="true"
|
||||
[toolbarParticipantsPanelButton]="true"
|
||||
[toolbarDisplayLogo]="true"
|
||||
[toolbarDisplaySessionName]="true"
|
||||
[streamDisplayParticipantName]="true"
|
||||
[streamDisplayAudioDetection]="true"
|
||||
[streamSettingsButton]="true"
|
||||
[participantPanelItemMuteButton]="true"
|
||||
[activitiesPanelRecordingActivity]="true"
|
||||
[recordingActivityRecordingsList]="recordingList"
|
||||
[recordingActivityRecordingError]="recordingError"
|
||||
[streamingActivityStreamingError]="streamingError"
|
||||
[streamingActivityStreamingInfo]="streamingInfo"
|
||||
[toolbarSettingsButton]="true"
|
||||
(onJoinButtonClicked)="onJoinClicked()"
|
||||
(onToolbarLeaveButtonClicked)="onToolbarLeaveButtonClicked()"
|
||||
(onToolbarCameraButtonClicked)="onToolbarCameraButtonClicked()"
|
||||
|
@ -13,18 +42,14 @@
|
|||
(onActivitiesPanelStartRecordingClicked)="onStartRecordingClicked()"
|
||||
(onActivitiesPanelStopRecordingClicked)="onStopRecordingClicked()"
|
||||
(onActivitiesPanelDeleteRecordingClicked)="onDeleteRecordingClicked($event)"
|
||||
(onActivitiesPanelStartStreamingClicked)="onStartStreamingClicked($event)"
|
||||
(onActivitiesPanelStopStreamingClicked)="onStopStreamingClicked()"
|
||||
(onToolbarStopStreamingClicked)="onStopStreamingClicked()"
|
||||
(onNodeCrashed)="onNodeCrashed()"
|
||||
[minimal]="false"
|
||||
[prejoin]="false"
|
||||
[videoMuted]="false"
|
||||
[audioMuted]="false"
|
||||
[activitiesPanelRecordingActivity]="true"
|
||||
[recordingActivityRecordingsList]="recordingList"
|
||||
[recordingActivityRecordingError]="recordingError"
|
||||
[toolbarSettingsButton]="true"
|
||||
>
|
||||
<!-- <div *ovActivitiesPanel>HELLO</div> -->
|
||||
|
||||
<!-- <ov-toolbar *ovToolbar [activitiesPanelButton]="false"
|
||||
[chatPanelButton]="false"></ov-toolbar> -->
|
||||
|
||||
</ov-videoconference>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { RecordingInfo, RecordingService, TokenModel } from 'openvidu-angular';
|
||||
import { RecordingInfo, TokenModel } from 'openvidu-angular';
|
||||
import { RestService } from '../services/rest.service';
|
||||
|
||||
@Component({
|
||||
|
@ -8,7 +8,6 @@ import { RestService } from '../services/rest.service';
|
|||
styleUrls: ['./call.component.scss']
|
||||
})
|
||||
export class CallComponent implements OnInit {
|
||||
|
||||
sessionId = 'daily-call';
|
||||
tokens: TokenModel;
|
||||
|
||||
|
@ -17,8 +16,10 @@ export class CallComponent implements OnInit {
|
|||
isSessionAlive: boolean = false;
|
||||
recordingList: RecordingInfo[] = [];
|
||||
recordingError: any;
|
||||
streamingError: any;
|
||||
streamingInfo: any;
|
||||
|
||||
constructor(private restService: RestService, private recordingService: RecordingService) { }
|
||||
constructor(private restService: RestService) {}
|
||||
|
||||
async ngOnInit() {
|
||||
await this.requestForTokens();
|
||||
|
@ -81,25 +82,45 @@ export class CallComponent implements OnInit {
|
|||
console.log('TOOLBAR LEAVE CLICKED');
|
||||
}
|
||||
|
||||
async onStartStreamingClicked(rtmpUrl: string) {
|
||||
console.log('START STREAMING', rtmpUrl);
|
||||
try {
|
||||
this.streamingError = null;
|
||||
this.streamingInfo = await this.restService.startStreaming(rtmpUrl);
|
||||
console.log('Streaming response ', this.streamingInfo);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
this.streamingError = error.error;
|
||||
}
|
||||
}
|
||||
|
||||
async onStopStreamingClicked() {
|
||||
console.log('STOP STREAMING');
|
||||
try {
|
||||
this.streamingError = null;
|
||||
this.streamingInfo = await this.restService.stopStreaming();
|
||||
console.log('Streaming response ', this.streamingInfo);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
this.streamingError = error.message || error;
|
||||
}
|
||||
}
|
||||
|
||||
async onStartRecordingClicked() {
|
||||
console.warn('START RECORDING CLICKED');
|
||||
try {
|
||||
await this.restService.startRecording(this.sessionId);
|
||||
} catch (error) {
|
||||
this.recordingError = error;
|
||||
|
||||
}
|
||||
}
|
||||
async onStopRecordingClicked() {
|
||||
console.warn('STOP RECORDING CLICKED');
|
||||
try {
|
||||
// await this.restService.startRecording(this.sessionId);
|
||||
|
||||
this.recordingList = await this.restService.stopRecording(this.sessionId);
|
||||
console.log('RECORDING LIST ', this.recordingList);
|
||||
} catch (error) {
|
||||
this.recordingError = error;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +129,6 @@ export class CallComponent implements OnInit {
|
|||
|
||||
try {
|
||||
this.recordingList = await this.restService.deleteRecording(recordingId);
|
||||
|
||||
} catch (error) {
|
||||
this.recordingError = error;
|
||||
}
|
||||
|
@ -123,7 +143,5 @@ export class CallComponent implements OnInit {
|
|||
};
|
||||
|
||||
console.log('Token requested: ', this.tokens);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[audioMuted]="_audioMuted"
|
||||
[toolbarScreenshareButton]="_toolbarScreenshareButton"
|
||||
[toolbarRecordingButton]="_toolbarRecordingButton"
|
||||
[toolbarStreamingButton]="_toolbarStreamingButton"
|
||||
[toolbarFullscreenButton]="_toolbarFullscreenButton"
|
||||
[toolbarBackgroundEffectsButton]="_toolbarBackgroundEffectsButton"
|
||||
[toolbarSettingsButton]="_toolbarSettingsButton"
|
||||
|
@ -26,8 +27,11 @@
|
|||
[streamSettingsButton]="_streamSettingsButton"
|
||||
[participantPanelItemMuteButton]="_participantPanelItemMuteButton"
|
||||
[activitiesPanelRecordingActivity]="_activitiesPanelRecordingActivity"
|
||||
[activitiesPanelStreamingActivity]="_activitiesPanelStreamingActivity"
|
||||
[recordingActivityRecordingsList]="_recordingActivityRecordingsList"
|
||||
[recordingActivityRecordingError]="_recordingActivityRecordingError"
|
||||
[streamingActivityStreamingInfo]="_streamingActivityStreamingInfo"
|
||||
[streamingActivityStreamingError]="_streamingActivityStreamingError"
|
||||
(onJoinButtonClicked)="_onJoinButtonClicked()"
|
||||
(onToolbarLeaveButtonClicked)="_onToolbarLeaveButtonClicked()"
|
||||
(onToolbarCameraButtonClicked)="_onToolbarCameraButtonClicked()"
|
||||
|
@ -39,10 +43,13 @@
|
|||
(onToolbarFullscreenButtonClicked)="_onToolbarFullscreenButtonClicked()"
|
||||
(onToolbarStartRecordingClicked)="onStartRecordingClicked('toolbar')"
|
||||
(onToolbarStopRecordingClicked)="onStopRecordingClicked('toolbar')"
|
||||
(onToolbarStopStreamingClicked)="onStopStreamingClicked('toolbar')"
|
||||
(onActivitiesPanelStartRecordingClicked)="onStartRecordingClicked('panel')"
|
||||
(onActivitiesPanelStopRecordingClicked)="onStopRecordingClicked('panel')"
|
||||
(onActivitiesPanelDownloadRecordingClicked)="_onActivitiesDownloadRecordingClicked($event)"
|
||||
(onActivitiesPanelDeleteRecordingClicked)="_onActivitiesDeleteRecordingClicked($event)"
|
||||
(onActivitiesPanelStartStreamingClicked)="onStartStreamingClicked($event)"
|
||||
(onActivitiesPanelStopStreamingClicked)="onStopStreamingClicked('panel')"
|
||||
(onSessionCreated)="_onSessionCreated($event)"
|
||||
(onParticipantCreated)="_onParticipantCreated($event)"
|
||||
></ov-videoconference>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@use '@angular/material' as mat;
|
||||
@import '~@angular/material/theming';
|
||||
@import '@angular/material/theming';
|
||||
|
||||
// Plus imports for other components in your app.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output } from '@ang
|
|||
import { OpenViduService, ParticipantAbstractModel, RecordingInfo, TokenModel } from 'openvidu-angular';
|
||||
import { Session } from 'openvidu-browser';
|
||||
import { CaptionsLangOption } from '../../../projects/openvidu-angular/src/lib/models/caption.model';
|
||||
import { StreamingInfo } from '../../../projects/openvidu-angular/src/lib/models/streaming.model';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -63,6 +64,10 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
* @internal
|
||||
*/
|
||||
_toolbarRecordingButton: boolean = true;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_toolbarStreamingButton: boolean = true;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
@ -127,12 +132,27 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
* @internal
|
||||
*/
|
||||
_activitiesPanelRecordingActivity: boolean = true;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_activitiesPanelStreamingActivity: boolean = true;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_recordingActivityRecordingsList: RecordingInfo[] = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* TODO: Remove this directive when RTMP Exported was included on OV and streaming ready event was fired.
|
||||
*/
|
||||
_streamingActivityStreamingInfo: StreamingInfo;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_streamingActivityStreamingError: any;
|
||||
|
||||
/**
|
||||
* The **minimal** attribute applies a minimal UI hiding all controls except for cam and mic.
|
||||
*
|
||||
|
@ -189,7 +209,7 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
* @example
|
||||
* <openvidu-webcomponent captions-lang-options="[{name:'Spanish', ISO: 'es-ES'}]"></openvidu-webcomponent>
|
||||
*/
|
||||
@Input() set captionsLangOptions(value: string | CaptionsLangOption []) {
|
||||
@Input() set captionsLangOptions(value: string | CaptionsLangOption[]) {
|
||||
this._captionsLangOptions = this.castToArray(value);
|
||||
}
|
||||
/**
|
||||
|
@ -273,6 +293,21 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
@Input() set toolbarRecordingButton(value: string | boolean) {
|
||||
this._toolbarRecordingButton = this.castToBoolean(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The **toolbarStreamingButton** attribute allows show/hide the start/stop streaming 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-streaming-button="false"></openvidu-webcomponent>
|
||||
*/
|
||||
@Input() set toolbarStreamingButton(value: string | boolean) {
|
||||
this._toolbarStreamingButton = this.castToBoolean(value);
|
||||
}
|
||||
/**
|
||||
* The **toolbarFullscreenButton** attribute allows show/hide the fullscreen toolbar button.
|
||||
*
|
||||
|
@ -497,6 +532,43 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
this._activitiesPanelRecordingActivity = this.castToBoolean(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The **activitiesPanelStreamingActivity** attribute allows show/hide the streaming activity in {@link ActivitiesPanelComponent}.
|
||||
*
|
||||
* Default: `true`
|
||||
*
|
||||
* @example
|
||||
* <openvidu-webcomponent activity-panel-streaming-activity="false"></openvidu-webcomponent>
|
||||
*/
|
||||
@Input() set activitiesPanelStreamingActivity(value: string | boolean) {
|
||||
this._activitiesPanelStreamingActivity = this.castToBoolean(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* The **streamingActivityStreamingInfo** attribute allows show to show the live streaming info in {@link StreamingActivityComponent}.
|
||||
*
|
||||
* Default: `undefined`
|
||||
*
|
||||
* @example
|
||||
* <openvidu-webcomponent streaming-activity-streaming-info="streamingInfo"></openvidu-webcomponent>
|
||||
*/
|
||||
@Input() set streamingActivityStreamingInfo(value: StreamingInfo) {
|
||||
this._streamingActivityStreamingInfo = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The **streamingActivityStreamingError** attribute allows to show any possible error with the streaming in the {@link StreamingActivityComponent}.
|
||||
*
|
||||
* Default: `undefined`
|
||||
*
|
||||
* @example
|
||||
* <openvidu-webcomponent streaming-activity-streaming-error="streamingError"></openvidu-webcomponent>
|
||||
*/
|
||||
@Input() set streamingActivityStreamingError(value: any) {
|
||||
this._streamingActivityStreamingError = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The **recordingActivityRecordingList** attribute allows show to show the recordings available for the session in {@link RecordingActivityComponent}.
|
||||
*
|
||||
|
@ -554,6 +626,10 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
*/
|
||||
@Output() onToolbarActivitiesPanelButtonClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start recording button is clicked from {@link ToolbarComponent}.
|
||||
* The recording should be started using the REST API.
|
||||
*/
|
||||
@Output() onToolbarStartRecordingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
/**
|
||||
* Provides event notifications that fire when stop recording button is clicked from {@link ToolbarComponent}.
|
||||
|
@ -562,9 +638,15 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
@Output() onToolbarStopRecordingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start recording button is clicked {@link ActivitiesPanelComponent}.
|
||||
* Provides event notifications that fire when stop streaming button is clicked from {@link ToolbarComponent}.
|
||||
* The recording should be stopped using the REST API.
|
||||
*/
|
||||
@Output() onToolbarStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start recording button is clicked {@link ActivitiesPanelComponent}.
|
||||
* The recording should be started using the REST API.
|
||||
*/
|
||||
@Output() onActivitiesPanelStartRecordingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
/**
|
||||
* Provides event notifications that fire when stop recording button is clicked from {@link ActivitiesPanelComponent}.
|
||||
|
@ -584,6 +666,18 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
*/
|
||||
@Output() onActivitiesPanelDeleteRecordingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when start streaming button is clicked {@link ActivitiesPanelComponent}.
|
||||
* The streaming should be started using the REST API.
|
||||
*/
|
||||
@Output() onActivitiesPanelStartStreamingClicked: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when stop streaming button is clicked {@link ActivitiesPanelComponent}.
|
||||
* The streaming should be stopped using the REST API.
|
||||
*/
|
||||
@Output() onActivitiesPanelStopStreamingClicked: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
/**
|
||||
* Provides event notifications that fire when OpenVidu Session is created.
|
||||
* See {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Session.html openvidu-browser Session}.
|
||||
|
@ -698,6 +792,9 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
_onToolbarFullscreenButtonClicked() {
|
||||
this.onToolbarFullscreenButtonClicked.emit();
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onStartRecordingClicked(from: string) {
|
||||
if (from === 'toolbar') {
|
||||
this.onToolbarStartRecordingClicked.emit();
|
||||
|
@ -731,6 +828,28 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
this.onActivitiesPanelDeleteRecordingClicked.emit(recordingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onStartStreamingClicked(rtmpUrl: string) {
|
||||
// if (from === 'toolbar') {
|
||||
// this.onToolbarStartRecordingClicked.emit();
|
||||
// } else if (from === 'panel') {
|
||||
this.onActivitiesPanelStartStreamingClicked.emit(rtmpUrl);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
onStopStreamingClicked(from: string) {
|
||||
if (from === 'toolbar') {
|
||||
this.onToolbarStopStreamingClicked.emit();
|
||||
} else if (from === 'panel') {
|
||||
this.onActivitiesPanelStopStreamingClicked.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
@ -778,7 +897,7 @@ export class OpenviduWebComponentComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
private castToArray(value: CaptionsLangOption [] | string) {
|
||||
private castToArray(value: CaptionsLangOption[] | string) {
|
||||
if (typeof value === 'string') {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { RecordingInfo } from 'openvidu-angular';
|
||||
import { catchError, lastValueFrom } from 'rxjs';
|
||||
import { throwError as observableThrowError } from 'rxjs/internal/observable/throwError';
|
||||
import { RecordingInfo } from 'openvidu-angular';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -41,6 +41,22 @@ export class RestService {
|
|||
}
|
||||
}
|
||||
|
||||
async startStreaming(rtmpUrl: string) {
|
||||
try {
|
||||
const options = {
|
||||
headers: new HttpHeaders({
|
||||
'Content-Type': 'application/json'
|
||||
})
|
||||
};
|
||||
return lastValueFrom(this.http.post<any>(this.baseHref + 'streamings/start', { rtmpUrl}, options));
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
throw { status: error.status, message: 'Cannot connect with backend. ' + error.url + ' not found' };
|
||||
}
|
||||
throw error.error;
|
||||
}
|
||||
}
|
||||
|
||||
async stopRecording(sessionId: string) {
|
||||
try {
|
||||
return lastValueFrom(this.http.post<any>(this.baseHref + 'recordings/stop', { sessionId }));
|
||||
|
@ -52,10 +68,22 @@ export class RestService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
async stopStreaming() {
|
||||
try {
|
||||
return lastValueFrom(this.http.delete<any>(`${this.baseHref}streamings/stop`));
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
throw { status: error.status, message: 'Cannot connect with backend. ' + error.url + ' not found' };
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async login(password: string): Promise<any[]> {
|
||||
try {
|
||||
return lastValueFrom(
|
||||
this.http.post<any>(`${this.baseHref}admin/login`, {
|
||||
this.http.post<any>(`${this.baseHref}auth/admin/login`, {
|
||||
password
|
||||
})
|
||||
);
|
||||
|
|
|
@ -51,8 +51,12 @@
|
|||
<span>
|
||||
<ul>
|
||||
<li *ngFor="let dir of directive.directives">
|
||||
<mat-checkbox [id]="dir + '-checkbox'" (change)="updateApiDirective(dir, $event.checked)" [checked]="true">
|
||||
{{ dir }}
|
||||
<mat-checkbox
|
||||
[id]="dir.name + '-checkbox'"
|
||||
(change)="updateApiDirective(dir.name, $event.checked)"
|
||||
[checked]="dir.checked"
|
||||
>
|
||||
{{ dir.name }}
|
||||
</mat-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -80,6 +84,7 @@
|
|||
[chatPanelButton]="chatPanelBtn"
|
||||
[displaySessionName]="displaySessionId"
|
||||
[displayLogo]="displayLogo"
|
||||
[streamingButton]="streamingBtn"
|
||||
(onLeaveButtonClicked)="appendElement('onLeaveButtonClicked')"
|
||||
(onCameraButtonClicked)="appendElement('onCameraButtonClicked')"
|
||||
(onMicrophoneButtonClicked)="appendElement('onMicrophoneButtonClicked')"
|
||||
|
@ -197,7 +202,15 @@
|
|||
</ng-template>
|
||||
|
||||
<ng-template [ngIf]="!ovPanelSelected && ovActivitiesPanelSelected">
|
||||
<ov-activities-panel *ovActivitiesPanel [recordingActivity]="recordingActivity" id="custom-activities-panel"></ov-activities-panel>
|
||||
<ov-activities-panel
|
||||
*ovActivitiesPanel
|
||||
[recordingActivity]="recordingActivity"
|
||||
[streamingActivity]="streamingActivity"
|
||||
id="custom-activities-panel"
|
||||
>
|
||||
<ov-recording-activity *ngIf="recordingActivity"></ov-recording-activity>
|
||||
<ov-streaming-activity *ngIf="streamingActivity" [streamingInfo]="streamingInfo" [streamingError]="streamingError"></ov-streaming-activity>
|
||||
</ov-activities-panel>
|
||||
</ng-template>
|
||||
|
||||
<ng-template [ngIf]="!ovPanelSelected && ovParticipantsPanelSelected">
|
||||
|
|
|
@ -2,7 +2,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { PanelService } from 'openvidu-angular';
|
||||
import { PanelService, StreamingError, StreamingInfo, StreamingStatus } from 'openvidu-angular';
|
||||
import { Subscription, throwError as observableThrowError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
|
@ -13,7 +13,7 @@ interface TemplateDirectives {
|
|||
|
||||
interface APIDirectives {
|
||||
component: string;
|
||||
directives: AttributeDirective[];
|
||||
directives: { name: AttributeDirective; checked: boolean }[];
|
||||
}
|
||||
|
||||
enum StructuralDirectives {
|
||||
|
@ -31,6 +31,7 @@ enum StructuralDirectives {
|
|||
STREAM = 'ovStream'
|
||||
}
|
||||
|
||||
|
||||
export enum AttributeDirective {
|
||||
// MINIMAL = 'minimal',
|
||||
// PARTICIPANT_NAME = 'participantName',
|
||||
|
@ -39,6 +40,7 @@ export enum AttributeDirective {
|
|||
// AUDIO_MUTED = 'audioMuted',
|
||||
TOOLBAR_SCREENSHARE = 'screenshareButton',
|
||||
TOOLBAR_FULLSCREEN = 'fullscreenButton',
|
||||
TOOLBAR_STREAMING = 'streamingButton',
|
||||
TOOLBAR_LEAVE = 'leaveButton',
|
||||
TOOLBAR_PARTICIPANTS_PANEL = 'participantsPanelButton',
|
||||
TOOLBAR_ACTIVITIES_PANEL = 'activitiesPanelButton',
|
||||
|
@ -49,7 +51,10 @@ export enum AttributeDirective {
|
|||
STREAM_AUDIO_DETECTION = 'displayAudioDetection',
|
||||
STREAM_SETTINGS = 'settingsButton',
|
||||
PARTICIPANT_ITEM_MUTE = 'muteButton',
|
||||
RECORDING_ACTIVITY = 'recordingActivity'
|
||||
ACTIVITIES_PANEL_RECORDING_ACTIVITY = 'recordingActivity',
|
||||
ACTIVITIES_PANEL_STREAMING_ACTIVITY = 'streamingActivity',
|
||||
ACTIVITIES_PANEL_STREAMING_INFO = 'streamingInfo',
|
||||
ACTIVITIES_PANEL_STREAMING_ERROR = "streamingError"
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -93,31 +98,37 @@ export class TestingComponent implements OnInit {
|
|||
{
|
||||
component: StructuralDirectives.TOOLBAR,
|
||||
directives: [
|
||||
AttributeDirective.TOOLBAR_CHAT_PANEL,
|
||||
AttributeDirective.TOOLBAR_DISPLAY_LOGO,
|
||||
AttributeDirective.TOOLBAR_DISPLAY_SESSION,
|
||||
AttributeDirective.TOOLBAR_FULLSCREEN,
|
||||
AttributeDirective.TOOLBAR_LEAVE,
|
||||
AttributeDirective.TOOLBAR_PARTICIPANTS_PANEL,
|
||||
AttributeDirective.TOOLBAR_ACTIVITIES_PANEL,
|
||||
AttributeDirective.TOOLBAR_SCREENSHARE
|
||||
{ name: AttributeDirective.TOOLBAR_CHAT_PANEL, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_DISPLAY_LOGO, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_DISPLAY_SESSION, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_FULLSCREEN, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_STREAMING, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_LEAVE, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_PARTICIPANTS_PANEL, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_ACTIVITIES_PANEL, checked: true },
|
||||
{ name: AttributeDirective.TOOLBAR_SCREENSHARE, checked: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
component: StructuralDirectives.STREAM,
|
||||
directives: [
|
||||
AttributeDirective.STREAM_AUDIO_DETECTION,
|
||||
AttributeDirective.STREAM_PARTICIPANT_NAME,
|
||||
AttributeDirective.STREAM_SETTINGS
|
||||
{ name: AttributeDirective.STREAM_AUDIO_DETECTION, checked: true },
|
||||
{ name: AttributeDirective.STREAM_PARTICIPANT_NAME, checked: true },
|
||||
{ name: AttributeDirective.STREAM_SETTINGS, checked: true }
|
||||
]
|
||||
},
|
||||
{
|
||||
component: StructuralDirectives.PARTICIPANTS_PANEL_ITEM,
|
||||
directives: [AttributeDirective.PARTICIPANT_ITEM_MUTE]
|
||||
directives: [{ name: AttributeDirective.PARTICIPANT_ITEM_MUTE, checked: true }]
|
||||
},
|
||||
{
|
||||
component: StructuralDirectives.ACTIVITIES_PANEL,
|
||||
directives: [AttributeDirective.RECORDING_ACTIVITY]
|
||||
directives: [
|
||||
{ name: AttributeDirective.ACTIVITIES_PANEL_RECORDING_ACTIVITY, checked: true },
|
||||
{ name: AttributeDirective.ACTIVITIES_PANEL_STREAMING_ACTIVITY, checked: true },
|
||||
{ name: AttributeDirective.ACTIVITIES_PANEL_STREAMING_INFO, checked: false },
|
||||
{ name: AttributeDirective.ACTIVITIES_PANEL_STREAMING_ERROR, checked: false }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -143,15 +154,18 @@ export class TestingComponent implements OnInit {
|
|||
participantsPanelBtn = true;
|
||||
activitiesPanelBtn = true;
|
||||
screenshareBtn = true;
|
||||
|
||||
audioDetection = true;
|
||||
participantName = true;
|
||||
settingsBtn = true;
|
||||
participantItemMuteBtn = true;
|
||||
streamingActivity = true;
|
||||
streamingBtn = true;
|
||||
streamingInfo: StreamingInfo = undefined;
|
||||
|
||||
tokens: { webcam: any; screen: any };
|
||||
|
||||
subscription: Subscription;
|
||||
streamingError: StreamingError | undefined;
|
||||
|
||||
recordingActivity = true;
|
||||
|
||||
|
@ -254,6 +268,10 @@ export class TestingComponent implements OnInit {
|
|||
this.fullscreenBtn = value;
|
||||
break;
|
||||
|
||||
case AttributeDirective.TOOLBAR_STREAMING:
|
||||
this.streamingBtn = value;
|
||||
break;
|
||||
|
||||
case AttributeDirective.TOOLBAR_LEAVE:
|
||||
this.leaveBtn = value;
|
||||
break;
|
||||
|
@ -279,9 +297,22 @@ export class TestingComponent implements OnInit {
|
|||
case AttributeDirective.PARTICIPANT_ITEM_MUTE:
|
||||
this.participantItemMuteBtn = value;
|
||||
break;
|
||||
case AttributeDirective.RECORDING_ACTIVITY:
|
||||
case AttributeDirective.ACTIVITIES_PANEL_RECORDING_ACTIVITY:
|
||||
this.recordingActivity = value;
|
||||
break;
|
||||
case AttributeDirective.ACTIVITIES_PANEL_STREAMING_ACTIVITY:
|
||||
this.streamingActivity = value;
|
||||
break;
|
||||
|
||||
case AttributeDirective.ACTIVITIES_PANEL_STREAMING_INFO:
|
||||
this.streamingInfo = { status: StreamingStatus.STARTED, id: '01' };
|
||||
break;
|
||||
|
||||
case AttributeDirective.ACTIVITIES_PANEL_STREAMING_ERROR:
|
||||
this.streamingError = {message: 'TEST_ERROR', rtmpAvailable: true};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,7 +338,7 @@ export class TestingComponent implements OnInit {
|
|||
|
||||
async getToken(sessionId: string): Promise<string> {
|
||||
const id = await this.createSession(sessionId);
|
||||
return await this.createToken(id);
|
||||
return await this.createConnection(id);
|
||||
}
|
||||
|
||||
createSession(sessionId: string) {
|
||||
|
@ -352,9 +383,9 @@ export class TestingComponent implements OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
createToken(sessionId): Promise<string> {
|
||||
createConnection(sessionId): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const body = {};
|
||||
const body = {role: 'MODERATOR'};
|
||||
const options = {
|
||||
headers: new HttpHeaders({
|
||||
Authorization: 'Basic ' + btoa('OPENVIDUAPP:' + this.OPENVIDU_SERVER_SECRET),
|
||||
|
|
Loading…
Reference in New Issue