Update to version v2.7.0

pull/173/head
jenkinsopenvidu 2018-12-14 13:01:16 +00:00
parent 8b8e4a4cfb
commit 1e2dd2fe8c
55 changed files with 9161 additions and 8544 deletions

View File

@ -3,7 +3,9 @@ import { LocalRecorderState } from '../OpenViduInternal/Enums/LocalRecorderState
/** /**
* Easy recording of [[Stream]] objects straightaway from the browser. Initialized with [[OpenVidu.initLocalRecorder]] method * Easy recording of [[Stream]] objects straightaway from the browser. Initialized with [[OpenVidu.initLocalRecorder]] method
* *
* > WARNING: Performing browser local recording of **remote streams** may cause some troubles. A long waiting time may be required after calling _LocalRecorder.stop()_ in this case * > WARNINGS:
* - Performing browser local recording of **remote streams** may cause some troubles. A long waiting time may be required after calling _LocalRecorder.stop()_ in this case
* - Only Chrome and Firefox support local stream recording
*/ */
export declare class LocalRecorder { export declare class LocalRecorder {
private stream; private stream;
@ -12,10 +14,8 @@ export declare class LocalRecorder {
private mediaRecorder; private mediaRecorder;
private chunks; private chunks;
private blob; private blob;
private count;
private id; private id;
private videoPreviewSrc; private videoPreviewSrc;
private htmlParentElementId;
private videoPreview; private videoPreview;
/** /**
* @hidden * @hidden

View File

@ -17,10 +17,13 @@
*/ */
exports.__esModule = true; exports.__esModule = true;
var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState"); var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState");
var platform = require("platform");
/** /**
* Easy recording of [[Stream]] objects straightaway from the browser. Initialized with [[OpenVidu.initLocalRecorder]] method * Easy recording of [[Stream]] objects straightaway from the browser. Initialized with [[OpenVidu.initLocalRecorder]] method
* *
* > WARNING: Performing browser local recording of **remote streams** may cause some troubles. A long waiting time may be required after calling _LocalRecorder.stop()_ in this case * > WARNINGS:
* - Performing browser local recording of **remote streams** may cause some troubles. A long waiting time may be required after calling _LocalRecorder.stop()_ in this case
* - Only Chrome and Firefox support local stream recording
*/ */
var LocalRecorder = /** @class */ (function () { var LocalRecorder = /** @class */ (function () {
/** /**
@ -29,7 +32,6 @@ var LocalRecorder = /** @class */ (function () {
function LocalRecorder(stream) { function LocalRecorder(stream) {
this.stream = stream; this.stream = stream;
this.chunks = []; this.chunks = [];
this.count = 0;
this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection'; this.connectionId = (!!this.stream.connection) ? this.stream.connection.connectionId : 'default-connection';
this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord'; this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord';
this.state = LocalRecorderState_1.LocalRecorderState.READY; this.state = LocalRecorderState_1.LocalRecorderState.READY;
@ -168,15 +170,16 @@ var LocalRecorder = /** @class */ (function () {
this.videoPreview = document.createElement('video'); this.videoPreview = document.createElement('video');
this.videoPreview.id = this.id; this.videoPreview.id = this.id;
this.videoPreview.autoplay = true; this.videoPreview.autoplay = true;
if (platform.name === 'Safari') {
this.videoPreview.setAttribute('playsinline', 'true');
}
if (typeof parentElement === 'string') { if (typeof parentElement === 'string') {
this.htmlParentElementId = parentElement;
var parentElementDom = document.getElementById(parentElement); var parentElementDom = document.getElementById(parentElement);
if (parentElementDom) { if (parentElementDom) {
this.videoPreview = parentElementDom.appendChild(this.videoPreview); this.videoPreview = parentElementDom.appendChild(this.videoPreview);
} }
} }
else { else {
this.htmlParentElementId = parentElement.id;
this.videoPreview = parentElement.appendChild(this.videoPreview); this.videoPreview = parentElement.appendChild(this.videoPreview);
} }
this.videoPreview.src = this.videoPreviewSrc; this.videoPreview.src = this.videoPreviewSrc;
@ -190,7 +193,6 @@ var LocalRecorder = /** @class */ (function () {
var f = function () { var f = function () {
delete _this.blob; delete _this.blob;
_this.chunks = []; _this.chunks = [];
_this.count = 0;
delete _this.mediaRecorder; delete _this.mediaRecorder;
_this.state = LocalRecorderState_1.LocalRecorderState.READY; _this.state = LocalRecorderState_1.LocalRecorderState.READY;
}; };

File diff suppressed because one or more lines are too long

View File

@ -70,7 +70,7 @@ export declare class OpenVidu {
*/ */
checkSystemRequirements(): number; checkSystemRequirements(): number;
/** /**
* Checks if the browser supports screen-sharing. Chrome, Firefox and Opera support screen-sharing * Checks if the browser supports screen-sharing. Desktop Chrome, Firefox and Opera support screen-sharing
* @returns 1 if the browser supports screen-sharing, 0 otherwise * @returns 1 if the browser supports screen-sharing, 0 otherwise
*/ */
checkScreenSharingCapabilities(): number; checkScreenSharingCapabilities(): number;

View File

@ -26,6 +26,7 @@ var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Captur
var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing"); var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing");
var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc"); var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc");
var platform = require("platform"); var platform = require("platform");
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1;
/** /**
* Entrypoint of OpenVidu Browser library. * Entrypoint of OpenVidu Browser library.
* Use it to initialize objects of type [[Session]], [[Publisher]] and [[LocalRecorder]] * Use it to initialize objects of type [[Session]], [[Publisher]] and [[LocalRecorder]]
@ -50,28 +51,42 @@ var OpenVidu = /** @class */ (function () {
*/ */
this.advancedConfiguration = {}; this.advancedConfiguration = {};
console.info("'OpenVidu' initialized"); console.info("'OpenVidu' initialized");
if (platform.name.toLowerCase().indexOf('mobile') !== -1) { if (platform.os.family === 'iOS' || platform.os.family === 'Android') {
// Listen to orientationchange only on mobile browsers // Listen to orientationchange only on mobile devices
window.onorientationchange = function () { window.addEventListener('orientationchange', function () {
_this.publishers.forEach(function (publisher) { _this.publishers.forEach(function (publisher) {
if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) { if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) {
var attempts_1 = 0; var attempts_1 = 0;
var oldWidth_1 = publisher.stream.videoDimensions.width; var oldWidth_1 = publisher.stream.videoDimensions.width;
var oldHeight_1 = publisher.stream.videoDimensions.height; var oldHeight_1 = publisher.stream.videoDimensions.height;
// New resolution got from different places for Chrome and Firefox. Chrome needs a videoWidth and videoHeight of a videoElement. var getNewVideoDimensions_1 = function () {
// Firefox needs getSettings from the videoTrack return new Promise(function (resolve, reject) {
var firefoxSettings_1 = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); if (platform['isIonicIos']) {
var newWidth_1 = (platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings_1.width : publisher.videoReference.videoWidth; // iOS Ionic. Limitation: must get new dimensions from an existing video element already inserted into DOM
var newHeight_1 = (platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings_1.height : publisher.videoReference.videoHeight; resolve({
newWidth: publisher.stream.streamManager.videos[0].video.videoWidth,
newHeight: publisher.stream.streamManager.videos[0].video.videoHeight
});
}
else {
// Rest of platforms
// New resolution got from different places for Chrome and Firefox. Chrome needs a videoWidth and videoHeight of a videoElement.
// Firefox needs getSettings from the videoTrack
var firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings();
var newWidth = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth);
var newHeight = ((platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight);
resolve({ newWidth: newWidth, newHeight: newHeight });
}
});
};
var repeatUntilChange_1 = setInterval(function () { var repeatUntilChange_1 = setInterval(function () {
firefoxSettings_1 = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings(); getNewVideoDimensions_1().then(function (newDimensions) {
newWidth_1 = (platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings_1.width : publisher.videoReference.videoWidth; sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newDimensions.newWidth, newDimensions.newHeight);
newHeight_1 = (platform.name.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings_1.height : publisher.videoReference.videoHeight; });
sendStreamPropertyChangedEvent_1(oldWidth_1, oldHeight_1, newWidth_1, newHeight_1); }, 75);
}, 100);
var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) { var sendStreamPropertyChangedEvent_1 = function (oldWidth, oldHeight, newWidth, newHeight) {
attempts_1++; attempts_1++;
if (attempts_1 > 4) { if (attempts_1 > 10) {
clearTimeout(repeatUntilChange_1); clearTimeout(repeatUntilChange_1);
} }
if (newWidth !== oldWidth || newHeight !== oldHeight) { if (newWidth !== oldWidth || newHeight !== oldHeight) {
@ -98,14 +113,13 @@ var OpenVidu = /** @class */ (function () {
}; };
} }
}); });
}; });
} }
} }
/** /**
* Returns new session * Returns new session
*/ */
OpenVidu.prototype.initSession = function () { OpenVidu.prototype.initSession = function () {
console.warn("OEeeeeee");
this.session = new Session_1.Session(this); this.session = new Session_1.Session(this);
return this.session; return this.session;
}; };
@ -212,11 +226,19 @@ var OpenVidu = /** @class */ (function () {
*/ */
OpenVidu.prototype.checkSystemRequirements = function () { OpenVidu.prototype.checkSystemRequirements = function () {
var browser = platform.name; var browser = platform.name;
var version = platform.version; var family = platform.os.family;
if ((browser !== 'Chrome') && (browser !== 'Chrome Mobile') && var userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
(browser !== 'Firefox') && (browser !== 'Firefox Mobile') && (browser !== 'Firefox for iOS') && // Reject iPhones and iPads if not Safari ('Safari' also covers Ionic for iOS)
if (family === 'iOS' && (browser !== 'Safari' || userAgent.indexOf('CriOS') !== -1 || userAgent.indexOf('FxiOS') !== -1)) {
return 0;
}
// Accept: Chrome (desktop and Android), Firefox (desktop and Android), Opera (desktop and Android),
// Safari (OSX and iOS), Ionic (Android and iOS)
if ((browser !== 'Safari') &&
(browser !== 'Chrome') && (browser !== 'Chrome Mobile') &&
(browser !== 'Firefox') && (browser !== 'Firefox Mobile') &&
(browser !== 'Opera') && (browser !== 'Opera Mobile') && (browser !== 'Opera') && (browser !== 'Opera Mobile') &&
(browser !== 'Safari') && (browser !== 'Android Browser')) { (browser !== 'Android Browser')) {
return 0; return 0;
} }
else { else {
@ -224,11 +246,16 @@ var OpenVidu = /** @class */ (function () {
} }
}; };
/** /**
* Checks if the browser supports screen-sharing. Chrome, Firefox and Opera support screen-sharing * Checks if the browser supports screen-sharing. Desktop Chrome, Firefox and Opera support screen-sharing
* @returns 1 if the browser supports screen-sharing, 0 otherwise * @returns 1 if the browser supports screen-sharing, 0 otherwise
*/ */
OpenVidu.prototype.checkScreenSharingCapabilities = function () { OpenVidu.prototype.checkScreenSharingCapabilities = function () {
var browser = platform.name; var browser = platform.name;
var family = platform.os.family;
// Reject mobile devices
if (family === 'iOS' || family === 'Android') {
return 0;
}
if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera')) { if ((browser !== 'Chrome') && (browser !== 'Firefox') && (browser !== 'Opera')) {
return 0; return 0;
} }
@ -402,7 +429,7 @@ var OpenVidu = /** @class */ (function () {
if (publisherProperties.videoSource === 'screen' || if (publisherProperties.videoSource === 'screen' ||
(platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window')) { (platform.name.indexOf('Firefox') !== -1 && publisherProperties.videoSource === 'window')) {
if (platform.name !== 'Chrome' && platform.name.indexOf('Firefox') === -1 && platform.name !== 'Opera') { if (platform.name !== 'Chrome' && platform.name.indexOf('Firefox') === -1 && platform.name !== 'Opera') {
var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome and Firefox. Detected browser: ' + platform.name); var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox or Opera. Detected browser: ' + platform.name);
console.error(error); console.error(error);
reject(error); reject(error);
} }

File diff suppressed because one or more lines are too long

View File

@ -45,6 +45,8 @@ export declare class Publisher extends StreamManager {
* *
* #### Events dispatched * #### Events dispatched
* *
* > _Only if `Session.publish(Publisher)` has been called for this Publisher_
*
* The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"audioActive"` and `reason` set to `"publishAudio"` * The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"audioActive"` and `reason` set to `"publishAudio"`
* The [[Publisher]] object of the local participant will also dispatch the exact same event * The [[Publisher]] object of the local participant will also dispatch the exact same event
* *
@ -61,6 +63,8 @@ export declare class Publisher extends StreamManager {
* *
* #### Events dispatched * #### Events dispatched
* *
* > _Only if `Session.publish(Publisher)` has been called for this Publisher_
*
* The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"videoActive"` and `reason` set to `"publishVideo"` * The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"videoActive"` and `reason` set to `"publishVideo"`
* The [[Publisher]] object of the local participant will also dispatch the exact same event * The [[Publisher]] object of the local participant will also dispatch the exact same event
* *

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -37,6 +37,7 @@ var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPro
var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var platform = require("platform"); var platform = require("platform");
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1;
/** /**
* Packs local media streams. Participants can publish it to a session. Initialized with [[OpenVidu.initPublisher]] method * Packs local media streams. Participants can publish it to a session. Initialized with [[OpenVidu.initPublisher]] method
*/ */
@ -71,6 +72,8 @@ var Publisher = /** @class */ (function (_super) {
* *
* #### Events dispatched * #### Events dispatched
* *
* > _Only if `Session.publish(Publisher)` has been called for this Publisher_
*
* The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"audioActive"` and `reason` set to `"publishAudio"` * The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"audioActive"` and `reason` set to `"publishAudio"`
* The [[Publisher]] object of the local participant will also dispatch the exact same event * The [[Publisher]] object of the local participant will also dispatch the exact same event
* *
@ -87,20 +90,22 @@ var Publisher = /** @class */ (function (_super) {
this.stream.getMediaStream().getAudioTracks().forEach(function (track) { this.stream.getMediaStream().getAudioTracks().forEach(function (track) {
track.enabled = value; track.enabled = value;
}); });
this.session.openvidu.sendRequest('streamPropertyChanged', { if (!!this.session && !!this.stream.streamId) {
streamId: this.stream.streamId, this.session.openvidu.sendRequest('streamPropertyChanged', {
property: 'audioActive', streamId: this.stream.streamId,
newValue: value, property: 'audioActive',
reason: 'publishAudio' newValue: value,
}, function (error, response) { reason: 'publishAudio'
if (error) { }, function (error, response) {
console.error("Error sending 'streamPropertyChanged' event", error); if (error) {
} console.error("Error sending 'streamPropertyChanged' event", error);
else { }
_this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]); else {
_this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]); _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', value, !value, 'publishAudio')]);
} _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', value, !value, 'publishAudio')]);
}); }
});
}
this.stream.audioActive = value; this.stream.audioActive = value;
console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream'); console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its audio stream');
} }
@ -110,6 +115,8 @@ var Publisher = /** @class */ (function (_super) {
* *
* #### Events dispatched * #### Events dispatched
* *
* > _Only if `Session.publish(Publisher)` has been called for this Publisher_
*
* The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"videoActive"` and `reason` set to `"publishVideo"` * The [[Session]] object of the local participant will dispatch a `streamPropertyChanged` event with `changedProperty` set to `"videoActive"` and `reason` set to `"publishVideo"`
* The [[Publisher]] object of the local participant will also dispatch the exact same event * The [[Publisher]] object of the local participant will also dispatch the exact same event
* *
@ -126,20 +133,22 @@ var Publisher = /** @class */ (function (_super) {
this.stream.getMediaStream().getVideoTracks().forEach(function (track) { this.stream.getMediaStream().getVideoTracks().forEach(function (track) {
track.enabled = value; track.enabled = value;
}); });
this.session.openvidu.sendRequest('streamPropertyChanged', { if (!!this.session && !!this.stream.streamId) {
streamId: this.stream.streamId, this.session.openvidu.sendRequest('streamPropertyChanged', {
property: 'videoActive', streamId: this.stream.streamId,
newValue: value, property: 'videoActive',
reason: 'publishVideo' newValue: value,
}, function (error, response) { reason: 'publishVideo'
if (error) { }, function (error, response) {
console.error("Error sending 'streamPropertyChanged' event", error); if (error) {
} console.error("Error sending 'streamPropertyChanged' event", error);
else { }
_this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]); else {
_this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]); _this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', value, !value, 'publishVideo')]);
} _this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', value, !value, 'publishVideo')]);
}); }
});
}
this.stream.videoActive = value; this.stream.videoActive = value;
console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream'); console.info("'Publisher' has " + (value ? 'published' : 'unpublished') + ' its video stream');
} }
@ -259,6 +268,9 @@ var Publisher = /** @class */ (function (_super) {
mediaStream.getVideoTracks()[0].enabled = enabled; mediaStream.getVideoTracks()[0].enabled = enabled;
} }
_this.videoReference = document.createElement('video'); _this.videoReference = document.createElement('video');
if (platform.name === 'Safari') {
_this.videoReference.setAttribute('playsinline', 'true');
}
_this.videoReference.srcObject = mediaStream; _this.videoReference.srcObject = mediaStream;
_this.stream.setMediaStream(mediaStream); _this.stream.setMediaStream(mediaStream);
if (!_this.stream.displayMyRemote()) { if (!_this.stream.displayMyRemote()) {
@ -272,26 +284,56 @@ var Publisher = /** @class */ (function (_super) {
delete _this.firstVideoElement; delete _this.firstVideoElement;
if (_this.stream.isSendVideo()) { if (_this.stream.isSendVideo()) {
if (!_this.stream.isSendScreen()) { if (!_this.stream.isSendScreen()) {
// With no screen share, video dimension can be set directly from MediaStream (getSettings) if (platform['isIonicIos'] || platform.name === 'Safari') {
// Orientation must be checked for mobile devices (width and height are reversed) // iOS Ionic or Safari. Limitation: cannot set videoDimensions directly, as the videoReference is not loaded
//const { width, height } = mediaStream.getVideoTracks()[0].getSettings(); // if not added to DOM. Must add it to DOM and wait for videoWidth and videoHeight properties to be defined
var width = 700; _this.videoReference.style.display = 'none';
var height = 480; document.body.appendChild(_this.videoReference);
if (platform.name.toLowerCase().indexOf('mobile') !== -1 && (window.innerHeight > window.innerWidth)) { var videoDimensionsSet_1 = function () {
// Mobile portrait mode _this.stream.videoDimensions = {
_this.stream.videoDimensions = { width: _this.videoReference.videoWidth,
width: height || 0, height: _this.videoReference.videoHeight
height: width || 0 };
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
document.body.removeChild(_this.videoReference);
};
var interval_1;
_this.videoReference.onloadedmetadata = function () {
if (_this.videoReference.videoWidth === 0) {
interval_1 = setInterval(function () {
if (_this.videoReference.videoWidth !== 0) {
videoDimensionsSet_1();
clearInterval(interval_1);
}
}, 10);
}
else {
videoDimensionsSet_1();
}
}; };
} }
else { else {
_this.stream.videoDimensions = { // Rest of platforms
width: width || 0, // With no screen share, video dimension can be set directly from MediaStream (getSettings)
height: height || 0 // Orientation must be checked for mobile devices (width and height are reversed)
}; var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height;
if ((platform.os.family === 'iOS' || platform.os.family === 'Android') && (window.innerHeight > window.innerWidth)) {
// Mobile portrait mode
_this.stream.videoDimensions = {
width: height || 0,
height: width || 0
};
}
else {
_this.stream.videoDimensions = {
width: width || 0,
height: height || 0
};
}
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
} }
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
} }
else { else {
// With screen share, video dimension must be got from a video element (onloadedmetadata event) // With screen share, video dimension must be got from a video element (onloadedmetadata event)
@ -302,8 +344,8 @@ var Publisher = /** @class */ (function (_super) {
}; };
_this.screenShareResizeInterval = setInterval(function () { _this.screenShareResizeInterval = setInterval(function () {
var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings(); var firefoxSettings = mediaStream.getVideoTracks()[0].getSettings();
var newWidth = (platform.name === 'Chrome') ? _this.videoReference.videoWidth : firefoxSettings.width; var newWidth = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoWidth : firefoxSettings.width;
var newHeight = (platform.name === 'Chrome') ? _this.videoReference.videoHeight : firefoxSettings.height; var newHeight = (platform.name === 'Chrome' || platform.name === 'Opera') ? _this.videoReference.videoHeight : firefoxSettings.height;
if (_this.stream.isLocalStreamPublished && if (_this.stream.isLocalStreamPublished &&
(newWidth !== _this.stream.videoDimensions.width || (newWidth !== _this.stream.videoDimensions.width ||
newHeight !== _this.stream.videoDimensions.height)) { newHeight !== _this.stream.videoDimensions.height)) {
@ -389,6 +431,10 @@ var Publisher = /** @class */ (function (_super) {
successCallback(mediaStream); successCallback(mediaStream);
})["catch"](function (error) { })["catch"](function (error) {
_this.clearPermissionDialogTimer(startTime_1, timeForDialogEvent); _this.clearPermissionDialogTimer(startTime_1, timeForDialogEvent);
if (error.name === 'Error') {
// Safari OverConstrainedError has as name property 'Error' instead of 'OverConstrainedError'
error.name = error.constructor.name;
}
var errorName, errorMessage; var errorName, errorMessage;
switch (error.name.toLowerCase()) { switch (error.name.toLowerCase()) {
case 'notfounderror': case 'notfounderror':
@ -420,6 +466,10 @@ var Publisher = /** @class */ (function (_super) {
} }
})["catch"](function (error) { })["catch"](function (error) {
_this.clearPermissionDialogTimer(startTime_1, timeForDialogEvent); _this.clearPermissionDialogTimer(startTime_1, timeForDialogEvent);
if (error.name === 'Error') {
// Safari OverConstrainedError has as name property 'Error' instead of 'OverConstrainedError'
error.name = error.constructor.name;
}
var errorName, errorMessage; var errorName, errorMessage;
switch (error.name.toLowerCase()) { switch (error.name.toLowerCase()) {
case 'notfounderror': case 'notfounderror':

File diff suppressed because one or more lines are too long

View File

@ -44,6 +44,14 @@ export declare class Session implements EventDispatcher {
* @hidden * @hidden
*/ */
remoteStreamsCreated: ObjMap<boolean>; remoteStreamsCreated: ObjMap<boolean>;
/**
* @hidden
*/
isFirstIonicIosSubscriber: boolean;
/**
* @hidden
*/
countDownForIonicIosSubscribers: boolean;
/** /**
* @hidden * @hidden
*/ */

View File

@ -28,8 +28,8 @@ var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var platform = require("platform");
var EventEmitter = require("wolfy87-eventemitter"); var EventEmitter = require("wolfy87-eventemitter");
var platform = require("platform");
/** /**
* Represents a video call. It can also be seen as a videoconference room where multiple users can connect. * Represents a video call. It can also be seen as a videoconference room where multiple users can connect.
* Participants who publish their videos to a session can be seen by the rest of users connected to that specific session. * Participants who publish their videos to a session can be seen by the rest of users connected to that specific session.
@ -49,6 +49,14 @@ var Session = /** @class */ (function () {
* @hidden * @hidden
*/ */
this.remoteStreamsCreated = {}; this.remoteStreamsCreated = {};
/**
* @hidden
*/
this.isFirstIonicIosSubscriber = true;
/**
* @hidden
*/
this.countDownForIonicIosSubscribers = true;
/** /**
* @hidden * @hidden
*/ */
@ -63,7 +71,7 @@ var Session = /** @class */ (function () {
/** /**
* Connects to the session using `token`. Parameter `metadata` allows you to pass extra data to share with other users when * Connects to the session using `token`. Parameter `metadata` allows you to pass extra data to share with other users when
* they receive `streamCreated` event. The structure of `metadata` string is up to you (maybe some standardized format * they receive `streamCreated` event. The structure of `metadata` string is up to you (maybe some standardized format
* as JSON or XML is a good idea), the only restriction is a maximum length of 10000 chars. * as JSON or XML is a good idea).
* *
* This metadata is not considered secure, as it is generated in the client side. To pass secure data, add it as a parameter in the * This metadata is not considered secure, as it is generated in the client side. To pass secure data, add it as a parameter in the
* token generation operation (through the API REST, openvidu-java-client or openvidu-node-client). * token generation operation (through the API REST, openvidu-java-client or openvidu-node-client).
@ -105,7 +113,7 @@ var Session = /** @class */ (function () {
}); });
} }
else { else {
reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' ' + platform.version + ' is not supported in OpenVidu')); reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' + platform.name + ' for ' + platform.os.family + ' is not supported in OpenVidu'));
} }
}); });
}; };
@ -466,7 +474,7 @@ var Session = /** @class */ (function () {
// If there are already available remote streams, enable hark 'speaking' event in all of them // If there are already available remote streams, enable hark 'speaking' event in all of them
for (var connectionId in this.remoteConnections) { for (var connectionId in this.remoteConnections) {
var str = this.remoteConnections[connectionId].stream; var str = this.remoteConnections[connectionId].stream;
if (!!str && !str.speechEvent && str.hasAudio) { if (!!str && str.hasAudio) {
str.enableSpeakingEvents(); str.enableSpeakingEvents();
} }
} }
@ -491,7 +499,7 @@ var Session = /** @class */ (function () {
// If there are already available remote streams, enable hark in all of them // If there are already available remote streams, enable hark in all of them
for (var connectionId in this.remoteConnections) { for (var connectionId in this.remoteConnections) {
var str = this.remoteConnections[connectionId].stream; var str = this.remoteConnections[connectionId].stream;
if (!!str && !str.speechEvent && str.hasAudio) { if (!!str && str.hasAudio) {
str.enableOnceSpeakingEvents(); str.enableOnceSpeakingEvents();
} }
} }
@ -513,7 +521,7 @@ var Session = /** @class */ (function () {
// If there are already available remote streams, disable hark in all of them // If there are already available remote streams, disable hark in all of them
for (var connectionId in this.remoteConnections) { for (var connectionId in this.remoteConnections) {
var str = this.remoteConnections[connectionId].stream; var str = this.remoteConnections[connectionId].stream;
if (!!str && !!str.speechEvent) { if (!!str) {
str.disableSpeakingEvents(); str.disableSpeakingEvents();
} }
} }
@ -550,6 +558,10 @@ var Session = /** @class */ (function () {
_this.ee.emitEvent('streamDestroyed', [streamEvent]); _this.ee.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior(); streamEvent.callDefaultBehavior();
delete _this.remoteStreamsCreated[stream.streamId]; delete _this.remoteStreamsCreated[stream.streamId];
if (Object.keys(_this.remoteStreamsCreated).length === 0) {
_this.isFirstIonicIosSubscriber = true;
_this.countDownForIonicIosSubscribers = true;
}
} }
delete _this.remoteConnections[connection.connectionId]; delete _this.remoteConnections[connection.connectionId];
_this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]); _this.ee.emitEvent('connectionDestroyed', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, msg.reason)]);
@ -609,6 +621,10 @@ var Session = /** @class */ (function () {
// Deleting the remote stream // Deleting the remote stream
var streamId = connection.stream.streamId; var streamId = connection.stream.streamId;
delete _this.remoteStreamsCreated[streamId]; delete _this.remoteStreamsCreated[streamId];
if (Object.keys(_this.remoteStreamsCreated).length === 0) {
_this.isFirstIonicIosSubscriber = true;
_this.countDownForIonicIosSubscribers = true;
}
connection.removeStream(streamId); connection.removeStream(streamId);
})["catch"](function (openViduError) { })["catch"](function (openViduError) {
console.error(openViduError); console.error(openViduError);

File diff suppressed because one or more lines are too long

View File

@ -117,6 +117,18 @@ export declare class Stream implements EventDispatcher {
* @hidden * @hidden
*/ */
speechEvent: any; speechEvent: any;
/**
* @hidden
*/
publisherStartSpeakingEventEnabled: boolean;
/**
* @hidden
*/
publisherStopSpeakingEventEnabled: boolean;
/**
* @hidden
*/
volumeChangeEventEnabled: boolean;
/** /**
* @hidden * @hidden
*/ */
@ -224,6 +236,18 @@ export declare class Stream implements EventDispatcher {
* @hidden * @hidden
*/ */
disableSpeakingEvents(): void; disableSpeakingEvents(): void;
/**
* @hidden
*/
enableVolumeChangeEvent(): void;
/**
* @hidden
*/
enableOnceVolumeChangeEvent(): void;
/**
* @hidden
*/
disableVolumeChangeEvent(): void;
/** /**
* @hidden * @hidden
*/ */

View File

@ -20,10 +20,13 @@ var Filter_1 = require("./Filter");
var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer"); var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer");
var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats"); var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats");
var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent"); var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent");
var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent"); var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var EventEmitter = require("wolfy87-eventemitter"); var EventEmitter = require("wolfy87-eventemitter");
var hark = require("hark"); var hark = require("hark");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError"); var platform = require("platform");
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1;
/** /**
* Represents each one of the media streams available in OpenVidu Server for certain session. * Represents each one of the media streams available in OpenVidu Server for certain session.
* Each [[Publisher]] and [[Subscriber]] has an attribute of type Stream, as they give access * Each [[Publisher]] and [[Subscriber]] has an attribute of type Stream, as they give access
@ -52,6 +55,18 @@ var Stream = /** @class */ (function () {
* @hidden * @hidden
*/ */
this.publishedOnce = false; this.publishedOnce = false;
/**
* @hidden
*/
this.publisherStartSpeakingEventEnabled = false;
/**
* @hidden
*/
this.publisherStopSpeakingEventEnabled = false;
/**
* @hidden
*/
this.volumeChangeEventEnabled = false;
this.session = session; this.session = session;
if (options.hasOwnProperty('id')) { if (options.hasOwnProperty('id')) {
// InboundStreamOptions: stream belongs to a Subscriber // InboundStreamOptions: stream belongs to a Subscriber
@ -308,6 +323,7 @@ var Stream = /** @class */ (function () {
} }
if (this.speechEvent) { if (this.speechEvent) {
this.speechEvent.stop(); this.speechEvent.stop();
delete this.speechEvent;
} }
this.stopWebRtcStats(); this.stopWebRtcStats();
console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed'); console.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') + "WebRTCPeer from 'Stream' with id [" + this.streamId + '] is now closed');
@ -373,12 +389,18 @@ var Stream = /** @class */ (function () {
Stream.prototype.enableSpeakingEvents = function () { Stream.prototype.enableSpeakingEvents = function () {
var _this = this; var _this = this;
this.setSpeechEventIfNotExists(); this.setSpeechEventIfNotExists();
this.speechEvent.on('speaking', function () { if (!this.publisherStartSpeakingEventEnabled) {
_this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); this.publisherStartSpeakingEventEnabled = true;
}); this.speechEvent.on('speaking', function () {
this.speechEvent.on('stopped_speaking', function () { _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]);
_this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); });
}); }
if (!this.publisherStopSpeakingEventEnabled) {
this.publisherStopSpeakingEventEnabled = true;
this.speechEvent.on('stopped_speaking', function () {
_this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]);
});
}
}; };
/** /**
* @hidden * @hidden
@ -386,21 +408,87 @@ var Stream = /** @class */ (function () {
Stream.prototype.enableOnceSpeakingEvents = function () { Stream.prototype.enableOnceSpeakingEvents = function () {
var _this = this; var _this = this;
this.setSpeechEventIfNotExists(); this.setSpeechEventIfNotExists();
this.speechEvent.on('speaking', function () { if (!this.publisherStartSpeakingEventEnabled) {
_this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]); this.publisherStartSpeakingEventEnabled = true;
_this.disableSpeakingEvents(); this.speechEvent.once('speaking', function () {
}); _this.session.emitEvent('publisherStartSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)]);
this.speechEvent.on('stopped_speaking', function () { _this.disableSpeakingEvents();
_this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]); });
_this.disableSpeakingEvents(); }
}); if (!this.publisherStopSpeakingEventEnabled) {
this.publisherStopSpeakingEventEnabled = true;
this.speechEvent.once('stopped_speaking', function () {
_this.session.emitEvent('publisherStopSpeaking', [new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)]);
_this.disableSpeakingEvents();
});
}
}; };
/** /**
* @hidden * @hidden
*/ */
Stream.prototype.disableSpeakingEvents = function () { Stream.prototype.disableSpeakingEvents = function () {
this.speechEvent.stop(); if (!!this.speechEvent) {
this.speechEvent = undefined; if (this.volumeChangeEventEnabled) {
// 'streamAudioVolumeChange' event is enabled. Cannot stop the hark process
this.speechEvent.off('speaking');
this.speechEvent.off('stopped_speaking');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
this.publisherStartSpeakingEventEnabled = false;
this.publisherStopSpeakingEventEnabled = false;
};
/**
* @hidden
*/
Stream.prototype.enableVolumeChangeEvent = function () {
var _this = this;
this.setSpeechEventIfNotExists();
if (!this.volumeChangeEventEnabled) {
this.volumeChangeEventEnabled = true;
this.speechEvent.on('volume_change', function (harkEvent) {
var oldValue = _this.speechEvent.oldVolumeValue;
var value = { newValue: harkEvent, oldValue: oldValue };
_this.speechEvent.oldVolumeValue = harkEvent;
_this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]);
});
}
};
/**
* @hidden
*/
Stream.prototype.enableOnceVolumeChangeEvent = function () {
var _this = this;
this.setSpeechEventIfNotExists();
if (!this.volumeChangeEventEnabled) {
this.volumeChangeEventEnabled = true;
this.speechEvent.once('volume_change', function (harkEvent) {
var oldValue = _this.speechEvent.oldVolumeValue;
var value = { newValue: harkEvent, oldValue: oldValue };
_this.speechEvent.oldVolumeValue = harkEvent;
_this.disableVolumeChangeEvent();
_this.streamManager.emitEvent('streamAudioVolumeChange', [new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)]);
});
}
};
/**
* @hidden
*/
Stream.prototype.disableVolumeChangeEvent = function () {
if (!!this.speechEvent) {
if (this.session.speakingEventsEnabled) {
// 'publisherStartSpeaking' and/or publisherStopSpeaking` events are enabled. Cannot stop the hark process
this.speechEvent.off('volume_change');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
this.volumeChangeEventEnabled = false;
}; };
/** /**
* @hidden * @hidden
@ -474,7 +562,7 @@ var Stream = /** @class */ (function () {
} }
} }
else { else {
_this.webRtcPeer.processAnswer(response.sdpAnswer) _this.webRtcPeer.processAnswer(response.sdpAnswer, false)
.then(function () { .then(function () {
_this.streamId = response.id; _this.streamId = response.id;
_this.isLocalStreamPublished = true; _this.isLocalStreamPublished = true;
@ -530,7 +618,16 @@ var Stream = /** @class */ (function () {
reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error))); reject(new Error('Error on recvVideoFrom: ' + JSON.stringify(error)));
} }
else { else {
_this.webRtcPeer.processAnswer(response.sdpAnswer).then(function () { // Ios Ionic. Limitation: some bug in iosrtc cordova plugin makes
// it necessary to add a timeout before processAnswer method
if (_this.session.isFirstIonicIosSubscriber) {
_this.session.isFirstIonicIosSubscriber = false;
_this.session['iosInterval'] = setTimeout(function () {
_this.session.countDownForIonicIosSubscribers = false;
}, 400);
}
var needsTimeoutOnProcessAswer = _this.session.countDownForIonicIosSubscribers;
_this.webRtcPeer.processAnswer(response.sdpAnswer, needsTimeoutOnProcessAswer).then(function () {
_this.remotePeerSuccessfullyEstablished(); _this.remotePeerSuccessfullyEstablished();
_this.initWebRtcStats(); _this.initWebRtcStats();
resolve(); resolve();
@ -550,17 +647,21 @@ var Stream = /** @class */ (function () {
}); });
}; };
Stream.prototype.remotePeerSuccessfullyEstablished = function () { Stream.prototype.remotePeerSuccessfullyEstablished = function () {
/*this.mediaStream = new MediaStream(); if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
let receiver: RTCRtpReceiver; var pc1 = this.webRtcPeer.pc;
for (receiver of this.webRtcPeer.pc.getReceivers()) { this.mediaStream = pc1.getRemoteStreams()[0];
if (!!receiver.track) { }
this.mediaStream.addTrack(receiver.track); else {
this.mediaStream = new MediaStream();
var receiver = void 0;
for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) {
receiver = _a[_i];
if (!!receiver.track) {
this.mediaStream.addTrack(receiver.track);
}
} }
}*/ }
var pc2 = this.webRtcPeer.pc;
console.warn("GET REMOTE STREAMS", pc2.getRemoteStreams());
this.mediaStream = pc2.getRemoteStreams()[0];
console.debug('Peer remote stream', this.mediaStream); console.debug('Peer remote stream', this.mediaStream);
if (!!this.mediaStream) { if (!!this.mediaStream) {
this.ee.emitEvent('mediastream-updated'); this.ee.emitEvent('mediastream-updated');

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,8 @@ var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEven
var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent"); var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode"); var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var EventEmitter = require("wolfy87-eventemitter"); var EventEmitter = require("wolfy87-eventemitter");
var platform = require("platform");
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1;
/** /**
* Interface in charge of displaying the media streams in the HTML DOM. This wraps any [[Publisher]] and [[Subscriber]] object. * Interface in charge of displaying the media streams in the HTML DOM. This wraps any [[Publisher]] and [[Subscriber]] object.
* You can insert as many video players fo the same Stream as you want by calling [[StreamManager.addVideoElement]] or * You can insert as many video players fo the same Stream as you want by calling [[StreamManager.addVideoElement]] or
@ -64,6 +66,9 @@ var StreamManager = /** @class */ (function () {
video: document.createElement('video'), video: document.createElement('video'),
id: '' id: ''
}; };
if (platform.name === 'Safari') {
this.firstVideoElement.video.setAttribute('playsinline', 'true');
}
this.targetElement = targEl; this.targetElement = targEl;
this.element = targEl; this.element = targEl;
} }
@ -83,7 +88,7 @@ var StreamManager = /** @class */ (function () {
console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing'); console.info("Remote 'Stream' with id [" + _this.stream.streamId + '] video is now playing');
_this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]); _this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(_this.videos[0].video, _this, 'videoPlaying')]);
} }
_this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this)]); _this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]);
}; };
} }
/** /**
@ -112,10 +117,13 @@ var StreamManager = /** @class */ (function () {
this.videos[0].video.paused === false && this.videos[0].video.paused === false &&
this.videos[0].video.ended === false && this.videos[0].video.ended === false &&
this.videos[0].video.readyState === 4) { this.videos[0].video.readyState === 4) {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this)]); this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]);
this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
} }
} }
if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) {
this.stream.enableVolumeChangeEvent();
}
return this; return this;
}; };
/** /**
@ -142,10 +150,13 @@ var StreamManager = /** @class */ (function () {
this.videos[0].video.paused === false && this.videos[0].video.paused === false &&
this.videos[0].video.ended === false && this.videos[0].video.ended === false &&
this.videos[0].video.readyState === 4) { this.videos[0].video.readyState === 4) {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this)]); this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]);
this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]); this.ee.emitEvent('videoPlaying', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoPlaying')]);
} }
} }
if (type === 'streamAudioVolumeChange' && this.stream.hasAudio) {
this.stream.enableOnceVolumeChangeEvent();
}
return this; return this;
}; };
/** /**
@ -158,6 +169,9 @@ var StreamManager = /** @class */ (function () {
else { else {
this.ee.off(type, handler); this.ee.off(type, handler);
} }
if (type === 'streamAudioVolumeChange') {
this.stream.disableVolumeChangeEvent();
}
return this; return this;
}; };
/** /**
@ -270,6 +284,9 @@ var StreamManager = /** @class */ (function () {
} }
video.autoplay = true; video.autoplay = true;
video.controls = false; video.controls = false;
if (platform.name === 'Safari') {
video.setAttribute('playsinline', 'true');
}
if (!video.id) { if (!video.id) {
video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId; video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId;
// DEPRECATED property: assign once the property id if the user provided a valid targetElement // DEPRECATED property: assign once the property id if the user provided a valid targetElement
@ -342,11 +359,13 @@ var StreamManager = /** @class */ (function () {
StreamManager.prototype.updateMediaStream = function (mediaStream) { StreamManager.prototype.updateMediaStream = function (mediaStream) {
this.videos.forEach(function (streamManagerVideo) { this.videos.forEach(function (streamManagerVideo) {
streamManagerVideo.video.srcObject = mediaStream; streamManagerVideo.video.srcObject = mediaStream;
console.warn("document.getElementID"); if (platform['isIonicIos']) {
var videoDiv = document.getElementById('remoteVideo'); // iOS Ionic. LIMITATION: must reinsert the video in the DOM for
if (videoDiv) { // the media stream to be updated
streamManagerVideo.video.setAttribute('playsinline', 'true'); var vParent = streamManagerVideo.video.parentElement;
videoDiv.appendChild(streamManagerVideo.video); var newVideo = streamManagerVideo.video;
vParent.replaceChild(newVideo, streamManagerVideo.video);
streamManagerVideo.video = newVideo;
} }
}); });
}; };
@ -364,8 +383,10 @@ var StreamManager = /** @class */ (function () {
} }
}; };
StreamManager.prototype.mirrorVideo = function (video) { StreamManager.prototype.mirrorVideo = function (video) {
video.style.transform = 'rotateY(180deg)'; if (!platform['isIonicIos']) {
video.style.webkitTransform = 'rotateY(180deg)'; video.style.transform = 'rotateY(180deg)';
video.style.webkitTransform = 'rotateY(180deg)';
}
}; };
StreamManager.prototype.removeMirrorVideo = function (video) { StreamManager.prototype.removeMirrorVideo = function (video) {
video.style.transform = 'unset'; video.style.transform = 'unset';

File diff suppressed because one or more lines are too long

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -12,14 +12,14 @@ export declare class ConnectionEvent extends Event {
*/ */
connection: Connection; connection: Connection;
/** /**
* For 'connectionDestroyed' event: * For `connectionDestroyed` event:
* - "disconnect": the remote user has called `Session.disconnect()` * - "disconnect": the remote user has called `Session.disconnect()`
* - "forceDisconnectByUser": the remote user has been evicted from the Session by other user calling `Session.forceDisconnect()` * - "forceDisconnectByUser": the remote user has been evicted from the Session by other user calling `Session.forceDisconnect()`
* - "forceDisconnectByServer": the remote user has been evicted from the Session by the application * - "forceDisconnectByServer": the remote user has been evicted from the Session by the application
* - "sessionClosedByServer": the Session has been closed by the application * - "sessionClosedByServer": the Session has been closed by the application
* - "networkDisconnect": the remote user network connection has dropped * - "networkDisconnect": the remote user network connection has dropped
* *
* For 'connectionCreated' empty string * For `connectionCreated` event an empty string
*/ */
reason: string; reason: string;
/** /**

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -2,13 +2,25 @@ import { Event } from './Event';
import { StreamManager } from '../../OpenVidu/StreamManager'; import { StreamManager } from '../../OpenVidu/StreamManager';
/** /**
* Defines the following events: * Defines the following events:
* - `streamPlaying`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) * - `streamPlaying`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) whenever its media stream starts playing (one of its videos has media
* and has begun to play)
* - `streamAudioVolumeChange`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) when the volume of its Stream's audio track
* changes. Only applies if [[Stream.hasAudio]] is `true`. The frequency this event is fired with is defined by property `interval` of
* [[OpenViduAdvancedConfiguration.publisherSpeakingEventsOptions]] (default 50ms)
*/ */
export declare class StreamManagerEvent extends Event { export declare class StreamManagerEvent extends Event {
/**
* For `streamAudioVolumeChange` event:
* - `{newValue: number, oldValue: number}`: new and old audio volume values. These values are between -100 (silence) and 0 (loudest possible volume).
* They are not exact and depend on how the browser is managing the audio track, but -100 and 0 can be taken as limit values.
*
* For `streamPlaying` event undefined
*/
value: Object | undefined;
/** /**
* @hidden * @hidden
*/ */
constructor(target: StreamManager); constructor(target: StreamManager, type: string, value: Object | undefined);
/** /**
* @hidden * @hidden
*/ */

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -32,15 +32,21 @@ exports.__esModule = true;
var Event_1 = require("./Event"); var Event_1 = require("./Event");
/** /**
* Defines the following events: * Defines the following events:
* - `streamPlaying`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) * - `streamPlaying`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) whenever its media stream starts playing (one of its videos has media
* and has begun to play)
* - `streamAudioVolumeChange`: dispatched by [[StreamManager]] ([[Publisher]] and [[Subscriber]]) when the volume of its Stream's audio track
* changes. Only applies if [[Stream.hasAudio]] is `true`. The frequency this event is fired with is defined by property `interval` of
* [[OpenViduAdvancedConfiguration.publisherSpeakingEventsOptions]] (default 50ms)
*/ */
var StreamManagerEvent = /** @class */ (function (_super) { var StreamManagerEvent = /** @class */ (function (_super) {
__extends(StreamManagerEvent, _super); __extends(StreamManagerEvent, _super);
/** /**
* @hidden * @hidden
*/ */
function StreamManagerEvent(target) { function StreamManagerEvent(target, type, value) {
return _super.call(this, false, target, 'streamPlaying') || this; var _this = _super.call(this, false, target, type) || this;
_this.value = value;
return _this;
} }
/** /**
* @hidden * @hidden

View File

@ -1 +1 @@
{"version":3,"file":"StreamManagerEvent.js","sourceRoot":"","sources":["../../../src/OpenViduInternal/Events/StreamManagerEvent.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;;;;AAEH,iCAAgC;AAGhC;;;GAGG;AACH;IAAwC,sCAAK;IAEzC;;OAEG;IACH,4BAAY,MAAqB;eAC7B,kBAAM,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,oCAAoC;IACpC,gDAAmB,GAAnB,cAAwB,CAAC;IAE7B,yBAAC;AAAD,CAAC,AAfD,CAAwC,aAAK,GAe5C;AAfY,gDAAkB"} {"version":3,"file":"StreamManagerEvent.js","sourceRoot":"","sources":["../../../src/OpenViduInternal/Events/StreamManagerEvent.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;;;;;;;;;;;;AAEH,iCAAgC;AAGhC;;;;;;;GAOG;AACH;IAAwC,sCAAK;IAWzC;;OAEG;IACH,4BAAY,MAAqB,EAAE,IAAY,EAAE,KAAyB;QAA1E,YACI,kBAAM,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,SAE7B;QADG,KAAI,CAAC,KAAK,GAAG,KAAK,CAAC;;IACvB,CAAC;IAED;;OAEG;IACH,oCAAoC;IACpC,gDAAmB,GAAnB,cAAwB,CAAC;IAE7B,yBAAC;AAAD,CAAC,AAzBD,CAAwC,aAAK,GAyB5C;AAzBY,gDAAkB"}

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }

View File

@ -7,7 +7,7 @@ export interface WebRtcPeerConfiguration {
onicecandidate: (event: any) => void; onicecandidate: (event: any) => void;
iceServers: RTCIceServer[] | undefined; iceServers: RTCIceServer[] | undefined;
mediaStream?: MediaStream; mediaStream?: MediaStream;
mode?: string; mode?: 'sendonly' | 'recvonly' | 'sendrecv';
id?: string; id?: string;
} }
export declare class WebRtcPeer { export declare class WebRtcPeer {
@ -45,7 +45,7 @@ export declare class WebRtcPeer {
* 3) Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer * 3) Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer
* just needs to set the answer as its remote description * just needs to set the answer as its remote description
*/ */
processAnswer(sdpAnswer: string): Promise<string>; processAnswer(sdpAnswer: string, needsTimeoutOnProcessAswer: boolean): Promise<string>;
/** /**
* Callback function invoked when an ICE candidate is received * Callback function invoked when an ICE candidate is received
*/ */

View File

@ -21,7 +21,7 @@ var __extends = (this && this.__extends) || (function () {
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b); return extendStatics(d, b);
} };
return function (d, b) { return function (d, b) {
extendStatics(d, b); extendStatics(d, b);
function __() { this.constructor = d; } function __() { this.constructor = d; }
@ -31,6 +31,8 @@ var __extends = (this && this.__extends) || (function () {
exports.__esModule = true; exports.__esModule = true;
var freeice = require("freeice"); var freeice = require("freeice");
var uuid = require("uuid"); var uuid = require("uuid");
var platform = require("platform");
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua.indexOf('Safari') === -1;
var WebRtcPeer = /** @class */ (function () { var WebRtcPeer = /** @class */ (function () {
function WebRtcPeer(configuration) { function WebRtcPeer(configuration) {
var _this = this; var _this = this;
@ -78,13 +80,17 @@ var WebRtcPeer = /** @class */ (function () {
reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue'); reject('The peer connection object is in "closed" state. This is most likely due to an invocation of the dispose method before accepting in the dialogue');
} }
if (!!_this.configuration.mediaStream) { if (!!_this.configuration.mediaStream) {
for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) { if (platform['isIonicIos']) {
var track = _a[_i]; // iOS Ionic. LIMITATION: must use deprecated WebRTC API
//this.pc.addTrack(track, this.configuration.mediaStream);
console.warn("ADDSTREAM");
var pc2 = _this.pc; var pc2 = _this.pc;
pc2.addStream(_this.configuration.mediaStream); pc2.addStream(_this.configuration.mediaStream);
} }
else {
for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) {
var track = _a[_i];
_this.pc.addTrack(track, _this.configuration.mediaStream);
}
}
resolve(); resolve();
} }
}); });
@ -101,20 +107,42 @@ var WebRtcPeer = /** @class */ (function () {
} }
this.remoteCandidatesQueue = []; this.remoteCandidatesQueue = [];
this.localCandidatesQueue = []; this.localCandidatesQueue = [];
// Stop senders if (platform['isIonicIos']) {
var pc1 = this.pc; // iOS Ionic. LIMITATION: must use deprecated WebRTC API
for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) { // Stop senders deprecated
var sender = _a[_i]; var pc1 = this.pc;
if (!videoSourceIsMediaStreamTrack) { for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) {
sender.stop(); var sender = _a[_i];
if (!videoSourceIsMediaStreamTrack) {
sender.stop();
}
pc1.removeStream(sender);
}
// Stop receivers deprecated
for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) {
var receiver = _c[_b];
if (!!receiver.track) {
receiver.stop();
}
} }
pc1.removeStream(sender);
} }
// Stop receivers else {
for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) { // Stop senders
var receiver = _c[_b]; for (var _d = 0, _e = this.pc.getSenders(); _d < _e.length; _d++) {
if (!!receiver.track) { var sender = _e[_d];
receiver.stop(); if (!videoSourceIsMediaStreamTrack) {
if (!!sender.track) {
sender.track.stop();
}
}
this.pc.removeTrack(sender);
}
// Stop receivers
for (var _f = 0, _g = this.pc.getReceivers(); _f < _g.length; _f++) {
var receiver = _g[_f];
if (!!receiver.track) {
receiver.track.stop();
}
} }
} }
this.pc.close(); this.pc.close();
@ -144,19 +172,50 @@ var WebRtcPeer = /** @class */ (function () {
offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo) offerToReceiveVideo: (_this.configuration.mode !== 'sendonly' && offerVideo)
}; };
console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints)); console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints));
_this.pc.createOffer(constraints).then(function (offer) { if (platform.name === 'Safari' && platform.ua.indexOf('Safari') !== -1) {
console.debug('Created SDP offer'); // Safari (excluding Ionic), at least on iOS just seems to support unified plan, whereas in other browsers is not yet ready and considered experimental
return _this.pc.setLocalDescription(offer); if (offerAudio) {
}).then(function () { _this.pc.addTransceiver('audio', {
var localDescription = _this.pc.localDescription; direction: _this.configuration.mode
if (!!localDescription) { });
console.debug('Local description set', localDescription.sdp);
resolve(localDescription.sdp);
} }
else { if (offerVideo) {
reject('Local description is not defined'); _this.pc.addTransceiver('video', {
direction: _this.configuration.mode
});
} }
})["catch"](function (error) { return reject(error); }); _this.pc
.createOffer()
.then(function (offer) {
console.debug('Created SDP offer');
return _this.pc.setLocalDescription(offer);
})
.then(function () {
var localDescription = _this.pc.localDescription;
if (!!localDescription) {
console.debug('Local description set', localDescription.sdp);
resolve(localDescription.sdp);
}
else {
reject('Local description is not defined');
}
})["catch"](function (error) { return reject(error); });
}
else {
_this.pc.createOffer(constraints).then(function (offer) {
console.debug('Created SDP offer');
return _this.pc.setLocalDescription(offer);
}).then(function () {
var localDescription = _this.pc.localDescription;
if (!!localDescription) {
console.debug('Local description set', localDescription.sdp);
resolve(localDescription.sdp);
}
else {
reject('Local description is not defined');
}
})["catch"](function (error) { return reject(error); });
}
}); });
}; };
/** /**
@ -196,7 +255,7 @@ var WebRtcPeer = /** @class */ (function () {
* 3) Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer * 3) Function invoked when a SDP answer is received. Final step in SDP negotiation, the peer
* just needs to set the answer as its remote description * just needs to set the answer as its remote description
*/ */
WebRtcPeer.prototype.processAnswer = function (sdpAnswer) { WebRtcPeer.prototype.processAnswer = function (sdpAnswer, needsTimeoutOnProcessAswer) {
var _this = this; var _this = this;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var answer = { var answer = {
@ -207,7 +266,15 @@ var WebRtcPeer = /** @class */ (function () {
if (_this.pc.signalingState === 'closed') { if (_this.pc.signalingState === 'closed') {
reject('RTCPeerConnection is closed'); reject('RTCPeerConnection is closed');
} }
_this.pc.setRemoteDescription(answer).then(function () { return resolve(); })["catch"](function (error) { return reject(error); }); if (needsTimeoutOnProcessAswer && platform['isIonicIos']) {
setTimeout(function () {
console.info('setRemoteDescription run after timout for iOS device');
_this.pc.setRemoteDescription(answer).then(function () { return resolve(); })["catch"](function (error) { return reject(error); });
}, 250);
}
else {
_this.pc.setRemoteDescription(answer).then(function () { return resolve(); })["catch"](function (error) { return reject(error); });
}
}); });
}; };
/** /**

File diff suppressed because one or more lines are too long

View File

@ -57,7 +57,7 @@ var WebRtcStats = /** @class */ (function () {
WebRtcStats.prototype.initWebRtcStats = function () { WebRtcStats.prototype.initWebRtcStats = function () {
var _this = this; var _this = this;
var elastestInstrumentation = localStorage.getItem('elastest-instrumentation'); var elastestInstrumentation = localStorage.getItem('elastest-instrumentation');
if (elastestInstrumentation) { if (!!elastestInstrumentation) {
// ElasTest instrumentation object found in local storage // ElasTest instrumentation object found in local storage
console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId); console.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
this.webRtcStatsEnabled = true; this.webRtcStatsEnabled = true;

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "openvidu-browser", "name": "openvidu-browser",
"version": "2.6.0", "version": "2.7.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -43,5 +43,5 @@
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"types": "lib/index.d.ts", "types": "lib/index.d.ts",
"version": "2.6.0" "version": "2.7.0"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,7 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<name>OpenVidu Server</name> <name>OpenVidu Server</name>
<version>2.6.0</version> <version>2.7.0</version>
<description>OpenVidu Server</description> <description>OpenVidu Server</description>
<url>https://github.com/OpenVidu/openvidu</url> <url>https://github.com/OpenVidu/openvidu</url>

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
"@angular/router": "7.1.3", "@angular/router": "7.1.3",
"core-js": "2.6.0", "core-js": "2.6.0",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
"openvidu-browser": "2.6.0", "openvidu-browser": "2.7.0",
"rxjs": "6.3.3", "rxjs": "6.3.3",
"zone.js": "0.8.26" "zone.js": "0.8.26"
}, },

View File

@ -1,6 +1,3 @@
wolfy87-eventemitter
Unlicense
openvidu-browser openvidu-browser
Apache-2.0 Apache-2.0
Apache License Apache License
@ -206,6 +203,55 @@ Apache-2.0
limitations under the License. limitations under the License.
platform
MIT
Copyright 2014-2018 Benjamin Tan <https://demoneaux.github.io/>
Copyright 2011-2013 John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
webpack
MIT
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tslib tslib
Apache-2.0 Apache-2.0
Apache License Apache License
@ -296,55 +342,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
platform
MIT
Copyright 2014-2018 Benjamin Tan <https://demoneaux.github.io/>
Copyright 2011-2013 John-David Dalton <http://allyoucanleet.com/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
webpack
MIT
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
hammerjs hammerjs
MIT MIT
The MIT License (MIT) The MIT License (MIT)
@ -370,6 +367,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
wolfy87-eventemitter
Unlicense
hark hark
MIT MIT
@ -627,9 +627,6 @@ Apache-2.0
@angular/compiler
MIT
@angular/core @angular/core
MIT MIT

View File

@ -12,12 +12,12 @@
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<link rel="stylesheet" href="styles.3c42cbf6ef67a1bc9d17.css"></head> <link rel="stylesheet" href="styles.096dd62fdaea80b95567.css"></head>
<body> <body>
<app-root> <app-root>
<mat-spinner></mat-spinner> <mat-spinner></mat-spinner>
</app-root> </app-root>
<script type="text/javascript" src="runtime.ec2944dd8b20ec099bf3.js"></script><script type="text/javascript" src="polyfills.a3731fd9d2797873ec38.js"></script><script type="text/javascript" src="main.de545a73be053d734497.js"></script></body> <script type="text/javascript" src="runtime.ec2944dd8b20ec099bf3.js"></script><script type="text/javascript" src="polyfills.7a6ddec22ac0ed842927.js"></script><script type="text/javascript" src="main.776524b58cb43c706ecd.js"></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,48 +1,48 @@
{ {
"dependencies": { "dependencies": {
"@angular/animations": "7.1.3", "@angular/animations": "7.1.3",
"@angular/cdk": "7.1.1", "@angular/cdk": "7.1.1",
"@angular/common": "7.1.3", "@angular/common": "7.1.3",
"@angular/compiler": "7.1.3", "@angular/compiler": "7.1.3",
"@angular/core": "7.1.3", "@angular/core": "7.1.3",
"@angular/flex-layout": "7.0.0-beta.19", "@angular/flex-layout": "7.0.0-beta.19",
"@angular/forms": "7.1.3", "@angular/forms": "7.1.3",
"@angular/http": "7.1.3", "@angular/http": "7.1.3",
"@angular/material": "7.1.1", "@angular/material": "7.1.1",
"@angular/platform-browser": "7.1.3", "@angular/platform-browser": "7.1.3",
"@angular/platform-browser-dynamic": "7.1.3", "@angular/platform-browser-dynamic": "7.1.3",
"@angular/router": "7.1.3", "@angular/router": "7.1.3",
"colormap": "2.3.0", "colormap": "2.3.0",
"core-js": "2.6.0", "core-js": "2.6.0",
"hammerjs": "2.0.8", "hammerjs": "2.0.8",
"openvidu-browser": "^2.6.0", "openvidu-browser": "2.7.0",
"openvidu-node-client": "2.5.0", "openvidu-node-client": "2.5.0",
"rxjs": "6.3.3", "rxjs": "6.3.3",
"zone.js": "0.8.26" "zone.js": "0.8.26"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "0.11.3", "@angular-devkit/build-angular": "0.11.3",
"@angular/cli": "7.1.3", "@angular/cli": "7.1.3",
"@angular/compiler-cli": "7.1.3", "@angular/compiler-cli": "7.1.3",
"@angular/language-service": "7.1.3", "@angular/language-service": "7.1.3",
"@types/jasmine": "3.3.1", "@types/jasmine": "3.3.1",
"@types/jasminewd2": "2.0.6", "@types/jasminewd2": "2.0.6",
"@types/node": "10.12.14", "@types/node": "10.12.14",
"codelyzer": "4.5.0", "codelyzer": "4.5.0",
"ts-node": "7.0.1", "ts-node": "7.0.1",
"tslint": "5.11.0", "tslint": "5.11.0",
"typescript": "3.1.6" "typescript": "3.1.6"
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"name": "openvidu-testapp", "name": "openvidu-testapp",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "ng build", "build": "ng build",
"e2e": "ng e2e", "e2e": "ng e2e",
"lint": "ng lint", "lint": "ng lint",
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve",
"test": "ng test" "test": "ng test"
}, },
"version": "2.6.0" "version": "2.7.0"
} }