From 07bf11b1c54fe2434bb9190ca502760df5ca3212 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Fri, 3 Aug 2018 14:56:36 +0200 Subject: [PATCH] openvidu-browser: filter events feature --- openvidu-browser/src/OpenVidu/OpenVidu.ts | 1 + openvidu-browser/src/OpenVidu/Session.ts | 63 ++++++++++++++++++- openvidu-browser/src/OpenVidu/Stream.ts | 49 ++++++++++++++- .../src/OpenViduInternal/Events/Event.ts | 5 +- .../OpenViduInternal/Events/FilterEvent.ts | 60 ++++++++++++++++++ .../Interfaces/Public/Filter.ts | 13 +++- openvidu-browser/src/index.ts | 1 + 7 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 openvidu-browser/src/OpenViduInternal/Events/FilterEvent.ts diff --git a/openvidu-browser/src/OpenVidu/OpenVidu.ts b/openvidu-browser/src/OpenVidu/OpenVidu.ts index 7fe6a461..0810d715 100644 --- a/openvidu-browser/src/OpenVidu/OpenVidu.ts +++ b/openvidu-browser/src/OpenVidu/OpenVidu.ts @@ -575,6 +575,7 @@ export class OpenVidu { recordingStopped: this.session.onRecordingStopped.bind(this.session), sendMessage: this.session.onNewMessage.bind(this.session), streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session), + filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session), iceCandidate: this.session.recvIceCandidate.bind(this.session), mediaError: this.session.onMediaError.bind(this.session) } diff --git a/openvidu-browser/src/OpenVidu/Session.ts b/openvidu-browser/src/OpenVidu/Session.ts index 73080fc3..37baebd8 100644 --- a/openvidu-browser/src/OpenVidu/Session.ts +++ b/openvidu-browser/src/OpenVidu/Session.ts @@ -29,6 +29,7 @@ import { ConnectionOptions } from '../OpenViduInternal/Interfaces/Private/Connec import { ObjMap } from '../OpenViduInternal/Interfaces/Private/ObjMap'; import { SessionOptions } from '../OpenViduInternal/Interfaces/Private/SessionOptions'; import { ConnectionEvent } from '../OpenViduInternal/Events/ConnectionEvent'; +import { FilterEvent } from '../OpenViduInternal/Events/FilterEvent'; import { PublisherSpeakingEvent } from '../OpenViduInternal/Events/PublisherSpeakingEvent'; import { RecordingEvent } from '../OpenViduInternal/Events/RecordingEvent'; import { SessionDisconnectedEvent } from '../OpenViduInternal/Events/SessionDisconnectedEvent'; @@ -589,6 +590,51 @@ export class Session implements EventDispatcher { }); } + addFilterEventListener(stream: Stream, eventType: string): Promise { + return new Promise((resolve, reject) => { + console.info('Adding filter event listener to event ' + eventType + ' to stream ' + stream.streamId); + this.openvidu.sendRequest( + 'addFilterEventListener', + { streamId: stream.streamId, type: eventType }, + (error, response) => { + if (error) { + console.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } else { + reject(error); + } + } else { + console.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + stream.streamId); + resolve(); + } + } + ); + }); + } + + removeFilterEventListener(stream: Stream, eventType: string): Promise { + return new Promise((resolve, reject) => { + console.info('Removing filter event listener to event ' + eventType + ' to stream ' + stream.streamId); + this.openvidu.sendRequest( + 'removeFilterEventListener', + { streamId: stream.streamId, type: eventType }, + (error, response) => { + if (error) { + console.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + stream.streamId, error); + if (error.code === 401) { + reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener")); + } else { + reject(error); + } + } else { + console.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + stream.streamId); + resolve(); + } + } + ); + }); + } /** * Sends one signal. `signal` object has the following optional properties: @@ -638,7 +684,7 @@ export class Session implements EventDispatcher { /** * See [[EventDispatcher.on]] */ - on(type: string, handler: (event: SessionDisconnectedEvent | SignalEvent | StreamEvent | ConnectionEvent | PublisherSpeakingEvent | RecordingEvent) => void): EventDispatcher { + on(type: string, handler: (event: SessionDisconnectedEvent | SignalEvent | StreamEvent | ConnectionEvent | PublisherSpeakingEvent | RecordingEvent | FilterEvent) => void): EventDispatcher { this.ee.on(type, event => { if (event) { @@ -1006,6 +1052,21 @@ export class Session implements EventDispatcher { this.ee.emitEvent('recordingStopped', [new RecordingEvent(this, 'recordingStopped', response.id, response.name)]); } + /** + * @hidden + * response = {connectionId: string, streamId: string, type: string, data: Object} + */ + onFilterEventDispatched(response): void { + const connectionId: string = response.connectionId; + const streamId: string = response.streamId; + this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId) + .then(connection => { + const stream: Stream = connection.stream; + stream.ee.emitEvent('filterEventDispatched', [new FilterEvent(stream, stream.filter, response.eventType, response.data)]); + this.ee.emitEvent('filterEventDispatched', [new FilterEvent(stream, stream.filter, response.eventType, response.data)]); + }); + } + /** * @hidden */ diff --git a/openvidu-browser/src/OpenVidu/Stream.ts b/openvidu-browser/src/OpenVidu/Stream.ts index 9f15f99b..efed8c21 100644 --- a/openvidu-browser/src/OpenVidu/Stream.ts +++ b/openvidu-browser/src/OpenVidu/Stream.ts @@ -16,8 +16,10 @@ */ import { Connection } from './Connection'; +import { Event } from '../OpenViduInternal/Events/Event'; import { Session } from './Session'; import { StreamManager } from './StreamManager'; +import { EventDispatcher } from '../OpenViduInternal/Interfaces/Public/EventDispatcher'; import { InboundStreamOptions } from '../OpenViduInternal/Interfaces/Private/InboundStreamOptions'; import { OutboundStreamOptions } from '../OpenViduInternal/Interfaces/Private/OutboundStreamOptions'; import { WebRtcPeer, WebRtcPeerSendonly, WebRtcPeerRecvonly, WebRtcPeerSendrecv } from '../OpenViduInternal/WebRtcPeer/WebRtcPeer'; @@ -34,7 +36,7 @@ import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/Open * Each [[Publisher]] and [[Subscriber]] has an attribute of type Stream, as they give access * to one of them (sending and receiving it, respectively) */ -export class Stream { +export class Stream implements EventDispatcher { /** * The Connection object that is publishing the stream @@ -215,6 +217,51 @@ export class Stream { } + /** + * See [[EventDispatcher.on]] + */ + on(type: string, handler: (event: Event) => void): EventDispatcher { + this.ee.on(type, event => { + if (event) { + console.info("Event '" + type + "' triggered by stream '" + this.streamId + "'", event); + } else { + console.info("Event '" + type + "' triggered by stream '" + this.streamId + "'"); + } + handler(event); + }); + return this; + } + + + /** + * See [[EventDispatcher.once]] + */ + once(type: string, handler: (event: Event) => void): EventDispatcher { + this.ee.once(type, event => { + if (event) { + console.info("Event '" + type + "' triggered once by stream '" + this.streamId + "'", event); + } else { + console.info("Event '" + type + "' triggered once by stream '" + this.streamId + "'"); + } + handler(event); + }); + return this; + } + + + /** + * See [[EventDispatcher.off]] + */ + off(type: string, handler?: (event: Event) => void): EventDispatcher { + if (!handler) { + this.ee.removeAllListeners(type); + } else { + this.ee.off(type, handler); + } + return this; + } + + /* Hidden methods */ /** diff --git a/openvidu-browser/src/OpenViduInternal/Events/Event.ts b/openvidu-browser/src/OpenViduInternal/Events/Event.ts index 0645278f..565d71a0 100644 --- a/openvidu-browser/src/OpenViduInternal/Events/Event.ts +++ b/openvidu-browser/src/OpenViduInternal/Events/Event.ts @@ -17,6 +17,7 @@ import { StreamManager } from '../../OpenVidu/StreamManager'; import { Session } from '../../OpenVidu/Session'; +import { Stream } from '../../OpenVidu/Stream'; export abstract class Event { @@ -28,7 +29,7 @@ export abstract class Event { /** * The object that dispatched the event */ - target: Session | StreamManager; + target: Session | Stream | StreamManager; /** * The type of event. This is the same string you pass as first parameter when calling method `on()` of any object implementing [[EventDispatcher]] interface @@ -40,7 +41,7 @@ export abstract class Event { /** * @hidden */ - constructor(cancelable: boolean, target: Session | StreamManager, type: string) { + constructor(cancelable: boolean, target: Session | Stream | StreamManager, type: string) { this.cancelable = cancelable; this.target = target; this.type = type; diff --git a/openvidu-browser/src/OpenViduInternal/Events/FilterEvent.ts b/openvidu-browser/src/OpenViduInternal/Events/FilterEvent.ts new file mode 100644 index 00000000..868e1dbb --- /dev/null +++ b/openvidu-browser/src/OpenViduInternal/Events/FilterEvent.ts @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2017-2018 OpenVidu (https://openvidu.io/) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { Event } from './Event'; +import { Stream } from '../../OpenVidu/Stream'; +import { Filter } from '../Interfaces/Public/Filter'; + + +/** + * Defines the following events: + * - `filterEventDispatched`: dispatched by [[Stream]]. Only triggered if `Stream.on('filterEventDispatched', event => {})` was called + */ +export class FilterEvent extends Event { + + /** + * Filter affected + */ + filter: Filter; + + /** + * Type of the event + */ + eventType: string; + + /** + * Data of the event + */ + data: Object; + + /** + * @hidden + */ + constructor(target: Stream, filter: Filter, eventType: string, data: Object) { + super(false, target, 'filterEventDispatched'); + this.filter = filter; + this.eventType = eventType; + this.data = data; + } + + /** + * @hidden + */ + // tslint:disable-next-line:no-empty + callDefaultBehavior() { } + +} \ No newline at end of file diff --git a/openvidu-browser/src/OpenViduInternal/Interfaces/Public/Filter.ts b/openvidu-browser/src/OpenViduInternal/Interfaces/Public/Filter.ts index 81d23171..2572aa73 100644 --- a/openvidu-browser/src/OpenViduInternal/Interfaces/Public/Filter.ts +++ b/openvidu-browser/src/OpenViduInternal/Interfaces/Public/Filter.ts @@ -22,14 +22,21 @@ export interface Filter { /** * Type of filter applied. This is the name of the remote class identifying the filter to apply in Kurento Media Server. - * For example: `"FaceOverlayFilter"`, `"GStreamerFilter"`. If `undefined` no filter is applied to the Stream + * For example: `"FaceOverlayFilter"`, `"GStreamerFilter"`. + * + * You can get this property in `*.kmd.json` files defining the Kurento filters: for GStreamerFilter that's + * [here](https://github.com/Kurento/kms-filters/blob/53a452fac71d61795952e3d2202156c6b00f6d65/src/server/interface/filters.GStreamerFilter.kmd.json#L4) */ type?: string; /** * Parameters used to initialized the filter. - * These correspond to the constructor parameters used in the filter in Kurento Media Server. - * For example: for `filter.type = "GStreamerFilter"` could be `filter.options = {"command": "pitch pitch=0.8 tempo=1.0"}` + * These correspond to the constructor parameters used in the filter in Kurento Media Server (except for `mediaPipeline` parameter, which is never needed). + * + * For example: for `filter.type = "GStreamerFilter"` could be `filter.options = {"command": "videobalance saturation=0.0"}` + * + * You can get this property in `*.kmd.json` files defining the Kurento filters: for GStreamerFilter that's + * [here](https://github.com/Kurento/kms-filters/blob/53a452fac71d61795952e3d2202156c6b00f6d65/src/server/interface/filters.GStreamerFilter.kmd.json#L13-L31) */ options?: Object; diff --git a/openvidu-browser/src/index.ts b/openvidu-browser/src/index.ts index cd39fe7c..ec11f32d 100644 --- a/openvidu-browser/src/index.ts +++ b/openvidu-browser/src/index.ts @@ -21,6 +21,7 @@ export { StreamEvent } from './OpenViduInternal/Events/StreamEvent'; export { StreamManagerEvent } from './OpenViduInternal/Events/StreamManagerEvent'; export { VideoElementEvent } from './OpenViduInternal/Events/VideoElementEvent'; export { StreamPropertyChangedEvent } from './OpenViduInternal/Events/StreamPropertyChangedEvent'; +export { FilterEvent } from './OpenViduInternal/Events/FilterEvent'; export { Capabilities } from './OpenViduInternal/Interfaces/Public/Capabilities'; export { Device } from './OpenViduInternal/Interfaces/Public/Device';