mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: filter support
parent
95a078b14a
commit
ccd8d7a8b9
|
@ -129,7 +129,8 @@ export class Connection {
|
|||
videoActive: opts.videoActive,
|
||||
typeOfVideo: opts.typeOfVideo,
|
||||
frameRate: opts.frameRate,
|
||||
videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined
|
||||
videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined,
|
||||
filter: !!opts.filter ? opts.filter : {}
|
||||
};
|
||||
const stream = new Stream(this.session, streamOptions);
|
||||
|
||||
|
|
|
@ -188,7 +188,8 @@ export class OpenVidu {
|
|||
publishAudio: (typeof properties.publishAudio !== 'undefined') ? properties.publishAudio : true,
|
||||
publishVideo: (typeof properties.publishVideo !== 'undefined') ? properties.publishVideo : true,
|
||||
resolution: this.isMediaStreamTrack(properties.videoSource) ? undefined : ((typeof properties.resolution !== 'undefined') ? properties.resolution : '640x480'),
|
||||
videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined
|
||||
videoSource: (typeof properties.videoSource !== 'undefined') ? properties.videoSource : undefined,
|
||||
filter: properties.filter
|
||||
};
|
||||
} else {
|
||||
|
||||
|
|
|
@ -492,6 +492,99 @@ export class Session implements EventDispatcher {
|
|||
});
|
||||
}
|
||||
|
||||
applyFilter(stream: Stream, type: string, options: string): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.info('Applying filter to stream ' + stream.streamId);
|
||||
this.openvidu.sendRequest(
|
||||
'applyFilter',
|
||||
{ streamId: stream.streamId, type, options },
|
||||
(error, response) => {
|
||||
if (error) {
|
||||
console.error('Error applying filter for Stream ' + stream.streamId, error);
|
||||
if (error.code === 401) {
|
||||
reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter"));
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
console.info('Filter successfully applied on Stream ' + stream.streamId);
|
||||
const oldValue = JSON.parse(JSON.stringify(stream.filter));
|
||||
stream.filter = { type, options };
|
||||
this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this, stream, 'filter', stream.filter, oldValue, 'applyFilter')]);
|
||||
stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(stream.streamManager, stream, 'filter', stream.filter, oldValue, 'applyFilter')]);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
execFilterMethod(stream: Stream, method: string, params: Object): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.info('Executing filter method to stream ' + stream.streamId);
|
||||
let stringParams;
|
||||
if (typeof params !== 'string') {
|
||||
try {
|
||||
stringParams = JSON.stringify(params);
|
||||
} catch (error) {
|
||||
const errorMsg = "'params' property must be a JSON formatted object";
|
||||
console.error(errorMsg);
|
||||
reject(errorMsg);
|
||||
}
|
||||
} else {
|
||||
stringParams = <string>params;
|
||||
}
|
||||
this.openvidu.sendRequest(
|
||||
'execFilterMethod',
|
||||
{ streamId: stream.streamId, method, params: stringParams },
|
||||
(error, response) => {
|
||||
if (error) {
|
||||
console.error('Error executing filter method for Stream ' + stream.streamId, error);
|
||||
if (error.code === 401) {
|
||||
reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method"));
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
console.info('Filter method successfully executed on Stream ' + stream.streamId);
|
||||
const oldValue = JSON.parse(JSON.stringify(stream.filter));
|
||||
stream.filter.lastExecMethod = { method, params: JSON.parse(stringParams) };
|
||||
this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this, stream, 'filter', stream.filter, oldValue, 'execFilterMethod')]);
|
||||
stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(stream.streamManager, stream, 'filter', stream.filter, oldValue, 'execFilterMethod')]);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
removeFilter(stream: Stream): Promise<any> {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.info('Removing filter of stream ' + stream.streamId);
|
||||
this.openvidu.sendRequest(
|
||||
'removeFilter',
|
||||
{ streamId: stream.streamId },
|
||||
(error, response) => {
|
||||
if (error) {
|
||||
console.error('Error removing filter for Stream ' + stream.streamId, error);
|
||||
if (error.code === 401) {
|
||||
reject(new OpenViduError(OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter"));
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
console.info('Filter successfully removed from Stream ' + stream.streamId);
|
||||
const oldValue = JSON.parse(JSON.stringify(stream.filter));
|
||||
stream.filter = new Object();
|
||||
this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this, stream, 'filter', stream.filter, oldValue, 'applyFilter')]);
|
||||
stream.streamManager.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(stream.streamManager, stream, 'filter', stream.filter, oldValue, 'applyFilter')]);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends one signal. `signal` object has the following optional properties:
|
||||
|
@ -792,6 +885,10 @@ export class Session implements EventDispatcher {
|
|||
msg.newValue = JSON.parse(JSON.parse(msg.newValue));
|
||||
stream.videoDimensions = msg.newValue;
|
||||
break;
|
||||
case 'filter':
|
||||
oldValue = stream.filter;
|
||||
stream.filter = msg.newValue;
|
||||
break;
|
||||
}
|
||||
|
||||
this.ee.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this, stream, msg.property, msg.newValue, oldValue, msg.reason)]);
|
||||
|
|
|
@ -100,6 +100,21 @@ export class Stream {
|
|||
*/
|
||||
videoDimensions: { width: number, height: number };
|
||||
|
||||
/**
|
||||
* **WARNING**: experimental option. This interface may change in the near future
|
||||
*
|
||||
* Filter applied to the Stream. You can apply filters by calling [[Session.applyFilter]], execute methods of the applied filter with
|
||||
* [[Session.execFilterMethod]] and remove it with [[Session.removeFilter]]. Be aware that the client calling this methods must have the
|
||||
* necessary permissions: the token owned by the client must have been initialized with the appropriated `allowedFilters` array.
|
||||
*/
|
||||
filter: {
|
||||
type?: string,
|
||||
options?: Object,
|
||||
lastExecMethod?: {
|
||||
method: string, params: Object
|
||||
}
|
||||
} = {};
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
@ -163,6 +178,12 @@ export class Stream {
|
|||
this.frameRate = (this.inboundStreamOpts.frameRate === -1) ? undefined : this.inboundStreamOpts.frameRate;
|
||||
this.videoDimensions = this.inboundStreamOpts.videoDimensions;
|
||||
}
|
||||
if (!!this.inboundStreamOpts.filter) {
|
||||
if (!!this.inboundStreamOpts.filter.lastExecMethod && Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) {
|
||||
delete this.inboundStreamOpts.filter.lastExecMethod;
|
||||
}
|
||||
this.filter = this.inboundStreamOpts.filter;
|
||||
}
|
||||
} else {
|
||||
// OutboundStreamOptions: stream belongs to a Publisher
|
||||
this.outboundStreamOpts = <OutboundStreamOptions>options;
|
||||
|
@ -182,6 +203,9 @@ export class Stream {
|
|||
this.typeOfVideo = this.isSendScreen() ? 'SCREEN' : 'CAMERA';
|
||||
}
|
||||
}
|
||||
if (!!this.outboundStreamOpts.publisherProperties.filter) {
|
||||
this.filter = this.outboundStreamOpts.publisherProperties.filter;
|
||||
}
|
||||
}
|
||||
|
||||
this.ee.on('mediastream-updated', () => {
|
||||
|
@ -467,7 +491,8 @@ export class Stream {
|
|||
videoActive: this.videoActive,
|
||||
typeOfVideo,
|
||||
frameRate: !!this.frameRate ? this.frameRate : -1,
|
||||
videoDimensions: JSON.stringify(this.videoDimensions)
|
||||
videoDimensions: JSON.stringify(this.videoDimensions),
|
||||
filter: this.outboundStreamOpts.publisherProperties.filter
|
||||
}, (error, response) => {
|
||||
if (error) {
|
||||
if (error.code === 401) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
import { Connection } from '../../../OpenVidu/Connection';
|
||||
import { Filter } from '../Public/Filter';
|
||||
|
||||
export interface InboundStreamOptions {
|
||||
id: string;
|
||||
|
@ -27,4 +28,5 @@ export interface InboundStreamOptions {
|
|||
typeOfVideo: string;
|
||||
frameRate: number;
|
||||
videoDimensions: { width: number, height: number };
|
||||
filter: Filter;
|
||||
}
|
|
@ -15,6 +15,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import { Filter } from '../Public/Filter';
|
||||
|
||||
export interface StreamOptionsServer {
|
||||
id: string;
|
||||
hasAudio: boolean;
|
||||
|
@ -24,4 +26,5 @@ export interface StreamOptionsServer {
|
|||
typeOfVideo: string;
|
||||
frameRate: number;
|
||||
videoDimensions: string;
|
||||
filter: Filter;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* (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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **WARNING**: experimental option. This interface may change in the near future. See [[Stream.filter]]
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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 = "pitch pitch=0.8 tempo=1.0"`
|
||||
*/
|
||||
options?: Object;
|
||||
|
||||
/**
|
||||
* Value passed the last time [[Session.execFilterMethod]] or [[Session.forceExecFilterMethod]] were called
|
||||
* for the Stream owning this filter. If `undefined` those methods have not been called yet.
|
||||
*
|
||||
* You can use this value to know the current status of any applied filter
|
||||
*/
|
||||
lastExecMethod?: {
|
||||
method: string,
|
||||
params: Object
|
||||
};
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import { Filter } from './Filter';
|
||||
import { VideoInsertMode } from '../../Enums/VideoInsertMode';
|
||||
|
||||
/**
|
||||
|
@ -80,4 +81,11 @@ export interface PublisherProperties {
|
|||
*/
|
||||
videoSource?: string | MediaStreamTrack | boolean;
|
||||
|
||||
/**
|
||||
* **WARNING**: experimental option. This property may change in the near future
|
||||
*
|
||||
* Define a filter to apply in the Publisher's stream
|
||||
*/
|
||||
filter?: Filter;
|
||||
|
||||
}
|
|
@ -25,6 +25,7 @@ export { StreamPropertyChangedEvent } from './OpenViduInternal/Events/StreamProp
|
|||
export { Capabilities } from './OpenViduInternal/Interfaces/Public/Capabilities';
|
||||
export { Device } from './OpenViduInternal/Interfaces/Public/Device';
|
||||
export { EventDispatcher } from './OpenViduInternal/Interfaces/Public/EventDispatcher';
|
||||
export { Filter } from './OpenViduInternal/Interfaces/Public/Filter';
|
||||
export { OpenViduAdvancedConfiguration } from './OpenViduInternal/Interfaces/Public/OpenViduAdvancedConfiguration';
|
||||
export { PublisherProperties } from './OpenViduInternal/Interfaces/Public/PublisherProperties';
|
||||
export { SignalOptions } from './OpenViduInternal/Interfaces/Public/SignalOptions';
|
||||
|
|
Loading…
Reference in New Issue