Merge pull request #154 from OpenVidu/ios-ionic

Ios ionic
pull/173/head
Pablo Fuente Pérez 2018-11-30 18:42:58 +01:00 committed by GitHub
commit d15638ed59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 242 additions and 1169 deletions

View File

@ -105,6 +105,7 @@ var OpenVidu = /** @class */ (function () {
* Returns new session
*/
OpenVidu.prototype.initSession = function () {
console.warn("OEeeeeee");
this.session = new Session_1.Session(this);
return this.session;
};

File diff suppressed because one or more lines are too long

View File

@ -274,7 +274,9 @@ var Publisher = /** @class */ (function (_super) {
if (!_this.stream.isSendScreen()) {
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
// Orientation must be checked for mobile devices (width and height are reversed)
var _a = mediaStream.getVideoTracks()[0].getSettings(), width = _a.width, height = _a.height;
//const { width, height } = mediaStream.getVideoTracks()[0].getSettings();
var width = 700;
var height = 480;
if (platform.name.toLowerCase().indexOf('mobile') !== -1 && (window.innerHeight > window.innerWidth)) {
// Mobile portrait mode
_this.stream.videoDimensions = {

File diff suppressed because one or more lines are too long

View File

@ -46,7 +46,9 @@ export declare class Stream implements EventDispatcher {
*/
audioActive: boolean;
/**
* Unique identifier of the stream
* Unique identifier of the stream. If the stream belongs to a...
* - Subscriber object: property `streamId` is always defined
* - Publisher object: property `streamId` is only defined after successful execution of [[Session.publish]]
*/
streamId: string;
/**

View File

@ -550,14 +550,17 @@ var Stream = /** @class */ (function () {
});
};
Stream.prototype.remotePeerSuccessfullyEstablished = function () {
this.mediaStream = new MediaStream();
var receiver;
for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) {
receiver = _a[_i];
/*this.mediaStream = new MediaStream();
let receiver: RTCRtpReceiver;
for (receiver of this.webRtcPeer.pc.getReceivers()) {
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);
if (!!this.mediaStream) {
this.ee.emitEvent('mediastream-updated');

File diff suppressed because one or more lines are too long

View File

@ -125,4 +125,5 @@ export declare class StreamManager implements EventDispatcher {
emitEvent(type: string, eventArray: any[]): void;
private pushNewStreamManagerVideo;
private mirrorVideo;
private removeMirrorVideo;
}

View File

@ -279,7 +279,11 @@ var StreamManager = /** @class */ (function () {
}
if (!this.remote && !this.stream.displayMyRemote()) {
video.muted = true;
if (this.stream.outboundStreamOpts.publisherProperties.mirror) {
if (video.style.transform === 'rotateY(180deg)' && !this.stream.outboundStreamOpts.publisherProperties.mirror) {
// If the video was already rotated and now is set to not mirror
this.removeMirrorVideo(video);
}
else if (this.stream.outboundStreamOpts.publisherProperties.mirror) {
this.mirrorVideo(video);
}
}
@ -338,6 +342,12 @@ var StreamManager = /** @class */ (function () {
StreamManager.prototype.updateMediaStream = function (mediaStream) {
this.videos.forEach(function (streamManagerVideo) {
streamManagerVideo.video.srcObject = mediaStream;
console.warn("document.getElementID");
var videoDiv = document.getElementById('remoteVideo');
if (videoDiv) {
streamManagerVideo.video.setAttribute('playsinline', 'true');
videoDiv.appendChild(streamManagerVideo.video);
}
});
};
/**
@ -357,6 +367,10 @@ var StreamManager = /** @class */ (function () {
video.style.transform = 'rotateY(180deg)';
video.style.webkitTransform = 'rotateY(180deg)';
};
StreamManager.prototype.removeMirrorVideo = function (video) {
video.style.transform = 'unset';
video.style.webkitTransform = 'unset';
};
return StreamManager;
}());
exports.StreamManager = StreamManager;

File diff suppressed because one or more lines are too long

View File

@ -1,507 +0,0 @@
var freeice = require('freeice');
var inherits = require('inherits');
var UAParser = require('ua-parser-js');
var uuid = require('uuid');
var hark = require('hark');
var EventEmitter = require('events').EventEmitter;
var recursive = require('merge').recursive.bind(undefined, true);
var sdpTranslator = require('sdp-translator');
var logger = window.Logger || console;
var MEDIA_CONSTRAINTS = {
audio: true,
video: {
width: 640,
framerate: 15
}
};
var ua = (window && window.navigator) ? window.navigator.userAgent : '';
var parser = new UAParser(ua);
var browser = parser.getBrowser();
var usePlanB = false;
if (browser.name === 'Chrome' || browser.name === 'Chromium') {
logger.debug(browser.name + ": using SDP PlanB");
usePlanB = true;
}
function noop(error) {
if (error)
logger.error(error);
}
function trackStop(track) {
track.stop && track.stop();
}
function streamStop(stream) {
stream.getTracks().forEach(trackStop);
}
var dumpSDP = function (description) {
if (typeof description === 'undefined' || description === null) {
return '';
}
return 'type: ' + description.type + '\r\n' + description.sdp;
};
function bufferizeCandidates(pc, onerror) {
var candidatesQueue = [];
pc.addEventListener('signalingstatechange', function () {
if (this.signalingState === 'stable') {
while (candidatesQueue.length) {
var entry = candidatesQueue.shift();
pc.addIceCandidate(entry.candidate, entry.callback, entry.callback);
}
}
});
return function (candidate, callback) {
callback = callback || onerror;
switch (pc.signalingState) {
case 'closed':
callback(new Error('PeerConnection object is closed'));
break;
case 'stable':
if (pc.remoteDescription) {
pc.addIceCandidate(candidate, callback, callback);
}
break;
default:
candidatesQueue.push({
candidate: candidate,
callback: callback
});
}
};
}
function removeFIDFromOffer(sdp) {
var n = sdp.indexOf("a=ssrc-group:FID");
if (n > 0) {
return sdp.slice(0, n);
}
else {
return sdp;
}
}
function getSimulcastInfo(videoStream) {
var videoTracks = videoStream.getVideoTracks();
if (!videoTracks.length) {
logger.warn('No video tracks available in the video stream');
return '';
}
var lines = [
'a=x-google-flag:conference',
'a=ssrc-group:SIM 1 2 3',
'a=ssrc:1 cname:localVideo',
'a=ssrc:1 msid:' + videoStream.id + ' ' + videoTracks[0].id,
'a=ssrc:1 mslabel:' + videoStream.id,
'a=ssrc:1 label:' + videoTracks[0].id,
'a=ssrc:2 cname:localVideo',
'a=ssrc:2 msid:' + videoStream.id + ' ' + videoTracks[0].id,
'a=ssrc:2 mslabel:' + videoStream.id,
'a=ssrc:2 label:' + videoTracks[0].id,
'a=ssrc:3 cname:localVideo',
'a=ssrc:3 msid:' + videoStream.id + ' ' + videoTracks[0].id,
'a=ssrc:3 mslabel:' + videoStream.id,
'a=ssrc:3 label:' + videoTracks[0].id
];
lines.push('');
return lines.join('\n');
}
function WebRtcPeer(mode, options, callback) {
if (!(this instanceof WebRtcPeer)) {
return new WebRtcPeer(mode, options, callback);
}
WebRtcPeer.super_.call(this);
if (options instanceof Function) {
callback = options;
options = undefined;
}
options = options || {};
callback = (callback || noop).bind(this);
var self = this;
var localVideo = options.localVideo;
var remoteVideo = options.remoteVideo;
var videoStream = options.videoStream;
var audioStream = options.audioStream;
var mediaConstraints = options.mediaConstraints;
var connectionConstraints = options.connectionConstraints;
var pc = options.peerConnection;
var sendSource = options.sendSource || 'webcam';
var guid = uuid.v4();
var configuration = recursive({
iceServers: (!!options.iceServers && options.iceServers.length > 0) ? options.iceServers : freeice()
}, options.configuration);
var onicecandidate = options.onicecandidate;
if (onicecandidate)
this.on('icecandidate', onicecandidate);
var oncandidategatheringdone = options.oncandidategatheringdone;
if (oncandidategatheringdone) {
this.on('candidategatheringdone', oncandidategatheringdone);
}
var simulcast = options.simulcast;
var multistream = options.multistream;
var interop = new sdpTranslator.Interop();
var candidatesQueueOut = [];
var candidategatheringdone = false;
Object.defineProperties(this, {
'peerConnection': {
get: function () {
return pc;
}
},
'id': {
value: options.id || guid,
writable: false
},
'remoteVideo': {
get: function () {
return remoteVideo;
}
},
'localVideo': {
get: function () {
return localVideo;
}
},
'currentFrame': {
get: function () {
if (!remoteVideo)
return;
if (remoteVideo.readyState < remoteVideo.HAVE_CURRENT_DATA)
throw new Error('No video stream data available');
var canvas = document.createElement('canvas');
canvas.width = remoteVideo.videoWidth;
canvas.height = remoteVideo.videoHeight;
canvas.getContext('2d').drawImage(remoteVideo, 0, 0);
return canvas;
}
}
});
if (!pc) {
pc = new RTCPeerConnection(configuration);
}
pc.addEventListener('icecandidate', function (event) {
var candidate = event.candidate;
if (EventEmitter.listenerCount(self, 'icecandidate') ||
EventEmitter.listenerCount(self, 'candidategatheringdone')) {
if (candidate) {
var cand;
if (multistream && usePlanB) {
cand = interop.candidateToUnifiedPlan(candidate);
}
else {
cand = candidate;
}
self.emit('icecandidate', cand);
candidategatheringdone = false;
}
else if (!candidategatheringdone) {
self.emit('candidategatheringdone');
candidategatheringdone = true;
}
}
else if (!candidategatheringdone) {
candidatesQueueOut.push(candidate);
if (!candidate)
candidategatheringdone = true;
}
});
pc.onaddstream = options.onaddstream;
pc.onnegotiationneeded = options.onnegotiationneeded;
this.on('newListener', function (event, listener) {
if (event === 'icecandidate' || event === 'candidategatheringdone') {
while (candidatesQueueOut.length) {
var candidate = candidatesQueueOut.shift();
if (!candidate === (event === 'candidategatheringdone')) {
listener(candidate);
}
}
}
});
var addIceCandidate = bufferizeCandidates(pc);
this.addIceCandidate = function (iceCandidate, callback) {
var candidate;
if (multistream && usePlanB) {
candidate = interop.candidateToPlanB(iceCandidate);
}
else {
candidate = new RTCIceCandidate(iceCandidate);
}
logger.debug('Remote ICE candidate received', iceCandidate);
callback = (callback || noop).bind(this);
addIceCandidate(candidate, callback);
};
this.generateOffer = function (callback) {
callback = callback.bind(this);
var offerAudio = true;
var offerVideo = true;
if (mediaConstraints) {
offerAudio = (typeof mediaConstraints.audio === 'boolean') ?
mediaConstraints.audio : true;
offerVideo = (typeof mediaConstraints.video === 'boolean') ?
mediaConstraints.video : true;
}
var browserDependantConstraints = {
offerToReceiveAudio: (mode !== 'sendonly' && offerAudio),
offerToReceiveVideo: (mode !== 'sendonly' && offerVideo)
};
var constraints = browserDependantConstraints;
logger.debug('constraints: ' + JSON.stringify(constraints));
pc.createOffer(constraints).then(function (offer) {
logger.debug('Created SDP offer');
offer = mangleSdpToAddSimulcast(offer);
return pc.setLocalDescription(offer);
}).then(function () {
var localDescription = pc.localDescription;
logger.debug('Local description set', localDescription.sdp);
if (multistream && usePlanB) {
localDescription = interop.toUnifiedPlan(localDescription);
logger.debug('offer::origPlanB->UnifiedPlan', dumpSDP(localDescription));
}
callback(null, localDescription.sdp, self.processAnswer.bind(self));
}).catch(callback);
};
this.getLocalSessionDescriptor = function () {
return pc.localDescription;
};
this.getRemoteSessionDescriptor = function () {
return pc.remoteDescription;
};
function setRemoteVideo() {
if (remoteVideo) {
remoteVideo.pause();
var stream = pc.getRemoteStreams()[0];
remoteVideo.srcObject = stream;
logger.debug('Remote stream:', stream);
remoteVideo.load();
}
}
this.showLocalVideo = function () {
localVideo.srcObject = videoStream;
localVideo.muted = true;
};
this.processAnswer = function (sdpAnswer, callback) {
callback = (callback || noop).bind(this);
var answer = new RTCSessionDescription({
type: 'answer',
sdp: sdpAnswer
});
if (multistream && usePlanB) {
var planBAnswer = interop.toPlanB(answer);
logger.debug('asnwer::planB', dumpSDP(planBAnswer));
answer = planBAnswer;
}
logger.debug('SDP answer received, setting remote description');
if (pc.signalingState === 'closed') {
return callback('PeerConnection is closed');
}
pc.setRemoteDescription(answer, function () {
setRemoteVideo();
callback();
}, callback);
};
this.processOffer = function (sdpOffer, callback) {
callback = callback.bind(this);
var offer = new RTCSessionDescription({
type: 'offer',
sdp: sdpOffer
});
if (multistream && usePlanB) {
var planBOffer = interop.toPlanB(offer);
logger.debug('offer::planB', dumpSDP(planBOffer));
offer = planBOffer;
}
logger.debug('SDP offer received, setting remote description');
if (pc.signalingState === 'closed') {
return callback('PeerConnection is closed');
}
pc.setRemoteDescription(offer).then(function () {
return setRemoteVideo();
}).then(function () {
return pc.createAnswer();
}).then(function (answer) {
answer = mangleSdpToAddSimulcast(answer);
logger.debug('Created SDP answer');
return pc.setLocalDescription(answer);
}).then(function () {
var localDescription = pc.localDescription;
if (multistream && usePlanB) {
localDescription = interop.toUnifiedPlan(localDescription);
logger.debug('answer::origPlanB->UnifiedPlan', dumpSDP(localDescription));
}
logger.debug('Local description set', localDescription.sdp);
callback(null, localDescription.sdp);
}).catch(callback);
};
function mangleSdpToAddSimulcast(answer) {
if (simulcast) {
if (browser.name === 'Chrome' || browser.name === 'Chromium') {
logger.debug('Adding multicast info');
answer = new RTCSessionDescription({
'type': answer.type,
'sdp': removeFIDFromOffer(answer.sdp) + getSimulcastInfo(videoStream)
});
}
else {
logger.warn('Simulcast is only available in Chrome browser.');
}
}
return answer;
}
function start() {
if (pc.signalingState === 'closed') {
callback('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 (videoStream && localVideo) {
self.showLocalVideo();
}
if (videoStream) {
pc.addStream(videoStream);
}
if (audioStream) {
pc.addStream(audioStream);
}
var browser = parser.getBrowser();
if (mode === 'sendonly' &&
(browser.name === 'Chrome' || browser.name === 'Chromium') &&
browser.major === 39) {
mode = 'sendrecv';
}
callback();
}
if (mode !== 'recvonly' && !videoStream && !audioStream) {
function getMedia(constraints) {
if (constraints === undefined) {
constraints = MEDIA_CONSTRAINTS;
}
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
videoStream = stream;
start();
}).catch(callback);
}
if (sendSource === 'webcam') {
getMedia(mediaConstraints);
}
else {
getScreenConstraints(sendSource, function (error, constraints_) {
if (error)
return callback(error);
constraints = [mediaConstraints];
constraints.unshift(constraints_);
getMedia(recursive.apply(undefined, constraints));
}, guid);
}
}
else {
setTimeout(start, 0);
}
this.on('_dispose', function () {
if (localVideo) {
localVideo.pause();
localVideo.srcObject = null;
localVideo.load();
localVideo.muted = false;
}
if (remoteVideo) {
remoteVideo.pause();
remoteVideo.srcObject = null;
remoteVideo.load();
}
self.removeAllListeners();
if (window.cancelChooseDesktopMedia !== undefined) {
window.cancelChooseDesktopMedia(guid);
}
});
}
inherits(WebRtcPeer, EventEmitter);
function createEnableDescriptor(type) {
var method = 'get' + type + 'Tracks';
return {
enumerable: true,
get: function () {
if (!this.peerConnection)
return;
var streams = this.peerConnection.getLocalStreams();
if (!streams.length)
return;
for (var i = 0, stream; stream = streams[i]; i++) {
var tracks = stream[method]();
for (var j = 0, track; track = tracks[j]; j++)
if (!track.enabled)
return false;
}
return true;
},
set: function (value) {
function trackSetEnable(track) {
track.enabled = value;
}
this.peerConnection.getLocalStreams().forEach(function (stream) {
stream[method]().forEach(trackSetEnable);
});
}
};
}
Object.defineProperties(WebRtcPeer.prototype, {
'enabled': {
enumerable: true,
get: function () {
return this.audioEnabled && this.videoEnabled;
},
set: function (value) {
this.audioEnabled = this.videoEnabled = value;
}
},
'audioEnabled': createEnableDescriptor('Audio'),
'videoEnabled': createEnableDescriptor('Video')
});
WebRtcPeer.prototype.getLocalStream = function (index) {
if (this.peerConnection) {
return this.peerConnection.getLocalStreams()[index || 0];
}
};
WebRtcPeer.prototype.getRemoteStream = function (index) {
if (this.peerConnection) {
return this.peerConnection.getRemoteStreams()[index || 0];
}
};
WebRtcPeer.prototype.dispose = function () {
logger.debug('Disposing WebRtcPeer');
var pc = this.peerConnection;
try {
if (pc) {
if (pc.signalingState === 'closed')
return;
pc.getLocalStreams().forEach(streamStop);
pc.close();
}
}
catch (err) {
logger.warn('Exception disposing webrtc peer ' + err);
}
this.emit('_dispose');
};
function WebRtcPeerRecvonly(options, callback) {
if (!(this instanceof WebRtcPeerRecvonly)) {
return new WebRtcPeerRecvonly(options, callback);
}
WebRtcPeerRecvonly.super_.call(this, 'recvonly', options, callback);
}
inherits(WebRtcPeerRecvonly, WebRtcPeer);
function WebRtcPeerSendonly(options, callback) {
if (!(this instanceof WebRtcPeerSendonly)) {
return new WebRtcPeerSendonly(options, callback);
}
WebRtcPeerSendonly.super_.call(this, 'sendonly', options, callback);
}
inherits(WebRtcPeerSendonly, WebRtcPeer);
function WebRtcPeerSendrecv(options, callback) {
if (!(this instanceof WebRtcPeerSendrecv)) {
return new WebRtcPeerSendrecv(options, callback);
}
WebRtcPeerSendrecv.super_.call(this, 'sendrecv', options, callback);
}
inherits(WebRtcPeerSendrecv, WebRtcPeer);
function harkUtils(stream, options) {
return hark(stream, options);
}
exports.bufferizeCandidates = bufferizeCandidates;
exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly;
exports.WebRtcPeerSendonly = WebRtcPeerSendonly;
exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;
exports.hark = harkUtils;
//# sourceMappingURL=WebRtcPeer.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,3 +0,0 @@
var WebRtcPeer = require('./WebRtcPeer');
exports.WebRtcPeer = WebRtcPeer;
//# sourceMappingURL=index.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/OpenViduInternal/KurentoUtils/kurento-utils-js/index.js"],"names":[],"mappings":"AA2BA,IAAI,UAAU,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAEzC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC"}

View File

@ -80,7 +80,10 @@ var WebRtcPeer = /** @class */ (function () {
if (!!_this.configuration.mediaStream) {
for (var _i = 0, _a = _this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) {
var track = _a[_i];
_this.pc.addTrack(track, _this.configuration.mediaStream);
//this.pc.addTrack(track, this.configuration.mediaStream);
console.warn("ADDSTREAM");
var pc2 = _this.pc;
pc2.addStream(_this.configuration.mediaStream);
}
resolve();
}
@ -99,20 +102,19 @@ var WebRtcPeer = /** @class */ (function () {
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
// Stop senders
for (var _i = 0, _a = this.pc.getSenders(); _i < _a.length; _i++) {
var pc1 = this.pc;
for (var _i = 0, _a = pc1.getLocalStreams(); _i < _a.length; _i++) {
var sender = _a[_i];
if (!videoSourceIsMediaStreamTrack) {
if (!!sender.track) {
sender.track.stop();
}
sender.stop();
}
this.pc.removeTrack(sender);
pc1.removeStream(sender);
}
// Stop receivers
for (var _b = 0, _c = this.pc.getReceivers(); _b < _c.length; _b++) {
for (var _b = 0, _c = pc1.getRemoteStreams(); _b < _c.length; _b++) {
var receiver = _c[_b];
if (!!receiver.track) {
receiver.track.stop();
receiver.stop();
}
}
this.pc.close();

File diff suppressed because one or more lines are too long

View File

@ -61,9 +61,9 @@
"dev": true
},
"@types/node": {
"version": "10.12.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.7.tgz",
"integrity": "sha512-Zh5Z4kACfbeE8aAOYh9mqotRxaZMro8MbBQtR8vEXOMiZo2rGEh2LayJijKdlu48YnS6y2EFU/oo2NCe5P6jGw=="
"version": "10.12.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.10.tgz",
"integrity": "sha512-8xZEYckCbUVgK8Eg7lf5Iy4COKJ5uXlnIOnePN0WUwSQggy9tolM+tDJf7wMOnT/JT/W9xDYIaYggt3mRV2O5w=="
},
"@types/platform": {
"version": "1.3.1",
@ -783,7 +783,6 @@
"anymatch": "^2.0.0",
"async-each": "^1.0.0",
"braces": "^2.3.0",
"fsevents": "^1.2.2",
"glob-parent": "^3.1.0",
"inherits": "^2.0.1",
"is-binary-path": "^1.0.0",
@ -1608,535 +1607,6 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
"integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
"dev": true,
"optional": true,
"requires": {
"nan": "^2.9.2",
"node-pre-gyp": "^0.10.0"
},
"dependencies": {
"abbrev": {
"version": "1.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
},
"aproba": {
"version": "1.2.0",
"bundled": true,
"dev": true,
"optional": true
},
"are-we-there-yet": {
"version": "1.1.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
}
},
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"chownr": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"debug": {
"version": "2.6.9",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ms": "2.0.0"
}
},
"deep-extend": {
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true
},
"delegates": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"detect-libc": {
"version": "1.0.3",
"bundled": true,
"dev": true,
"optional": true
},
"fs-minipass": {
"version": "1.2.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.2.1"
}
},
"fs.realpath": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"gauge": {
"version": "2.7.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.0",
"object-assign": "^4.1.0",
"signal-exit": "^3.0.0",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wide-align": "^1.1.0"
}
},
"glob": {
"version": "7.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"has-unicode": {
"version": "2.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"iconv-lite": {
"version": "0.4.21",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safer-buffer": "^2.1.0"
}
},
"ignore-walk": {
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimatch": "^3.0.4"
}
},
"inflight": {
"version": "1.0.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
},
"ini": {
"version": "1.3.5",
"bundled": true,
"dev": true,
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"isarray": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"minimatch": {
"version": "3.0.4",
"bundled": true,
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
}
},
"minizlib": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minipass": "^2.2.1"
}
},
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"dev": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"needle": {
"version": "2.2.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"debug": "^2.1.2",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
}
},
"node-pre-gyp": {
"version": "0.10.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"detect-libc": "^1.0.2",
"mkdirp": "^0.5.1",
"needle": "^2.2.0",
"nopt": "^4.0.1",
"npm-packlist": "^1.1.6",
"npmlog": "^4.0.2",
"rc": "^1.1.7",
"rimraf": "^2.6.1",
"semver": "^5.3.0",
"tar": "^4"
}
},
"nopt": {
"version": "4.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"abbrev": "1",
"osenv": "^0.1.4"
}
},
"npm-bundled": {
"version": "1.0.3",
"bundled": true,
"dev": true,
"optional": true
},
"npm-packlist": {
"version": "1.1.10",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1"
}
},
"npmlog": {
"version": "4.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
"gauge": "~2.7.3",
"set-blocking": "~2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
},
"object-assign": {
"version": "4.1.1",
"bundled": true,
"dev": true,
"optional": true
},
"once": {
"version": "1.4.0",
"bundled": true,
"dev": true,
"requires": {
"wrappy": "1"
}
},
"os-homedir": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"osenv": {
"version": "0.1.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"os-homedir": "^1.0.0",
"os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"process-nextick-args": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"rc": {
"version": "1.2.7",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"deep-extend": "^0.5.1",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"bundled": true,
"dev": true,
"optional": true
}
}
},
"readable-stream": {
"version": "2.3.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"rimraf": {
"version": "2.6.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"glob": "^7.0.5"
}
},
"safe-buffer": {
"version": "5.1.1",
"bundled": true,
"dev": true
},
"safer-buffer": {
"version": "2.1.2",
"bundled": true,
"dev": true,
"optional": true
},
"sax": {
"version": "1.2.4",
"bundled": true,
"dev": true,
"optional": true
},
"semver": {
"version": "5.5.0",
"bundled": true,
"dev": true,
"optional": true
},
"set-blocking": {
"version": "2.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"string-width": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"string_decoder": {
"version": "1.1.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "~5.1.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
"bundled": true,
"dev": true,
"optional": true
},
"tar": {
"version": "4.4.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"chownr": "^1.0.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.2.4",
"minizlib": "^1.1.0",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.1",
"yallist": "^3.0.2"
}
},
"util-deprecate": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
"wide-align": {
"version": "1.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"string-width": "^1.0.2"
}
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
},
"yallist": {
"version": "3.0.2",
"bundled": true,
"dev": true
}
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -3559,13 +3029,6 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"nan": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
"integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==",
"dev": true,
"optional": true
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@ -4797,15 +4260,15 @@
}
},
"tsify": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/tsify/-/tsify-4.0.0.tgz",
"integrity": "sha512-A33g5azPh2KDo/gbcSHpSo2m8l5FYC3SdjD5qNpBT+LP758HIGXT6cLko+aJhyFDRU5nCT/zQvfIq/5GQNRsoA==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/tsify/-/tsify-4.0.1.tgz",
"integrity": "sha512-ClznEI+pmwY5wmD0J7HCSVERwkD+l71ch3Dqyod2JuQLEsFaiNDI+vPjaGadsuVFVvmzgoI7HghrBtWsSmCDHQ==",
"dev": true,
"requires": {
"convert-source-map": "^1.1.0",
"fs.realpath": "^1.0.0",
"object-assign": "^4.1.0",
"semver": "^5.1.0",
"semver": "^5.6.0",
"through2": "^2.0.0",
"tsconfig": "^5.0.3"
}
@ -4904,6 +4367,14 @@
"shelljs": "^0.8.2",
"typedoc-default-themes": "^0.5.0",
"typescript": "3.1.x"
},
"dependencies": {
"typescript": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz",
"integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==",
"dev": true
}
}
},
"typedoc-default-themes": {
@ -4913,9 +4384,9 @@
"dev": true
},
"typescript": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz",
"integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.1.tgz",
"integrity": "sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg==",
"dev": true
},
"uglify-js": {
@ -5139,9 +4610,9 @@
"dev": true
},
"webrtc-adapter": {
"version": "6.4.5",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-6.4.5.tgz",
"integrity": "sha512-eZkkraBtI3ny/PJ3kxeyrFzE/zCDc8O6HDq945/14qeEF0mg1htx3egNeb4vpWCL4pKVeJZWbXldr3NifLPaPw==",
"version": "6.4.8",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-6.4.8.tgz",
"integrity": "sha512-YM8yl545c/JhYcjGHgaCoA7jRK/KZuMwEDFeP2AcP0Auv5awEd+gZE0hXy9z7Ed3p9HvAXp8jdbe+4ESb1zxAw==",
"requires": {
"rtcpeerconnection-shim": "^1.2.14",
"sdp": "^2.9.0"

View File

@ -1,13 +1,13 @@
{
"author": "OpenVidu",
"dependencies": {
"@types/node": "10.12.7",
"@types/node": "10.12.10",
"@types/platform": "1.3.1",
"freeice": "2.2.2",
"hark": "1.2.3",
"platform": "1.3.5",
"uuid": "3.3.2",
"webrtc-adapter": "6.4.5",
"webrtc-adapter": "6.4.8",
"wolfy87-eventemitter": "5.2.5"
},
"description": "OpenVidu Browser",
@ -22,10 +22,10 @@
"grunt-contrib-watch": "1.1.0",
"grunt-string-replace": "1.3.1",
"grunt-ts": "6.0.0-beta.21",
"tsify": "4.0.0",
"tsify": "4.0.1",
"tslint": "5.11.0",
"typedoc": "0.13.0",
"typescript": "3.1.6",
"typescript": "3.2.1",
"uglify-js": "3.4.9"
},
"license": "Apache-2.0",

View File

@ -32,6 +32,7 @@ import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturi
import RpcBuilder = require('../OpenViduInternal/KurentoUtils/kurento-jsonrpc');
import platform = require('platform');
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua!!.indexOf('Safari') === -1;
/**
* Entrypoint of OpenVidu Browser library.
@ -78,8 +79,8 @@ export class OpenVidu {
console.info("'OpenVidu' initialized");
if (platform.os!!.family === 'iOS' || platform.os!!.family === 'Android') {
// Listen to orientationchange only on mobile browsers
(<any>window).onorientationchange = () => {
// Listen to orientationchange only on mobile devices
(<any>window).addEventListener('orientationchange', () => {
this.publishers.forEach(publisher => {
if (!!publisher.stream && !!publisher.stream.hasVideo && !!publisher.stream.streamManager.videos[0]) {
@ -87,22 +88,37 @@ export class OpenVidu {
const oldWidth = publisher.stream.videoDimensions.width;
const oldHeight = publisher.stream.videoDimensions.height;
// 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
let firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings();
let newWidth = (platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth;
let newHeight = (platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight;
const getNewVideoDimensions = (): Promise<{newWidth: number, newHeight: number}> => {
return new Promise((resolve, reject) => {
let newVideoDimensions: { newWidth: number, newHeight: number };
if (platform['isIonicIos']) {
// iOS Ionic. Limitation: must get new dimensions from an existing video element already inserted into DOM
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
let firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings();
const newWidth = <number>((platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth);
const newHeight = <number>((platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight);
resolve({newWidth, newHeight});
}
});
};
const repeatUntilChange = setInterval(() => {
firefoxSettings = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings();
newWidth = (platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.width : publisher.videoReference.videoWidth;
newHeight = (platform.name!!.toLowerCase().indexOf('firefox') !== -1) ? firefoxSettings.height : publisher.videoReference.videoHeight;
sendStreamPropertyChangedEvent(oldWidth, oldHeight, newWidth, newHeight);
}, 100);
getNewVideoDimensions().then(newDimensions => {
sendStreamPropertyChangedEvent(oldWidth, oldHeight, newDimensions.newWidth, newDimensions.newHeight);
});
}, 75);
const sendStreamPropertyChangedEvent = (oldWidth, oldHeight, newWidth, newHeight) => {
attempts++;
if (attempts > 4) {
if (attempts > 10) {
clearTimeout(repeatUntilChange);
}
if (newWidth !== oldWidth || newHeight !== oldHeight) {
@ -131,7 +147,7 @@ export class OpenVidu {
};
}
});
};
});
}
}
@ -309,7 +325,7 @@ export class OpenVidu {
const family = platform.os!!.family;
// Reject mobile devices
if (family === 'iOS' || family === 'Android' || family === 'Windows Phone') {
if (family === 'iOS' || family === 'Android') {
return 0;
}

View File

@ -28,9 +28,6 @@ import { VideoElementEvent } from '../OpenViduInternal/Events/VideoElementEvent'
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
import platform = require('platform');
/**
* Packs local media streams. Participants can publish it to a session. Initialized with [[OpenVidu.initPublisher]] method
*/
@ -313,24 +310,58 @@ export class Publisher extends StreamManager {
if (this.stream.isSendVideo()) {
if (!this.stream.isSendScreen()) {
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
// Orientation must be checked for mobile devices (width and height are reversed)
const { width, height } = mediaStream.getVideoTracks()[0].getSettings();
if (platform.name!!.toLowerCase().indexOf('mobile') !== -1 && (window.innerHeight > window.innerWidth)) {
// Mobile portrait mode
this.stream.videoDimensions = {
width: height || 0,
height: width || 0
if (platform['isIonicIos']) {
// iOS Ionic. Limitation: cannot set videoDimensions directly, as the videoReference is not loaded
// if not added to DOM. Must add it to DOM and wait for videoWidth and videoHeight properties to be defined
this.videoReference.style.display = 'none';
document.body.appendChild(this.videoReference);
const videoDimensionsSet = () => {
this.stream.videoDimensions = {
width: this.videoReference.videoWidth,
height: this.videoReference.videoHeight
};
this.stream.isLocalStreamReadyToPublish = true;
this.stream.ee.emitEvent('stream-ready-to-publish', []);
document.body.removeChild(this.videoReference);
}
let interval;
this.videoReference.onloadedmetadata = () => {
if (this.videoReference.videoWidth === 0) {
interval = setInterval(() => {
if (this.videoReference.videoWidth !== 0) {
videoDimensionsSet();
clearInterval(interval);
}
}, 10);
} else {
videoDimensionsSet();
}
};
} else {
this.stream.videoDimensions = {
width: width || 0,
height: height || 0
};
// Rest of platforms
// With no screen share, video dimension can be set directly from MediaStream (getSettings)
// Orientation must be checked for mobile devices (width and height are reversed)
const { width, height } = mediaStream.getVideoTracks()[0].getSettings();
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 {
// With screen share, video dimension must be got from a video element (onloadedmetadata event)
this.videoReference.onloadedmetadata = () => {

View File

@ -40,7 +40,6 @@ import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPro
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
import platform = require('platform');
import EventEmitter = require('wolfy87-eventemitter');

View File

@ -703,15 +703,19 @@ export class Stream implements EventDispatcher {
}
private remotePeerSuccessfullyEstablished(): void {
this.mediaStream = new MediaStream();
let receiver: RTCRtpReceiver;
for (receiver of this.webRtcPeer.pc.getReceivers()) {
if (!!receiver.track) {
this.mediaStream.addTrack(receiver.track);
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
const pc1: any = this.webRtcPeer.pc;
this.mediaStream = pc1.getRemoteStreams()[0];
} else {
this.mediaStream = new MediaStream();
let receiver: RTCRtpReceiver;
for (receiver of this.webRtcPeer.pc.getReceivers()) {
if (!!receiver.track) {
this.mediaStream.addTrack(receiver.track);
}
}
}
console.debug('Peer remote stream', this.mediaStream);
if (!!this.mediaStream) {

View File

@ -412,6 +412,14 @@ export class StreamManager implements EventDispatcher {
updateMediaStream(mediaStream: MediaStream) {
this.videos.forEach(streamManagerVideo => {
streamManagerVideo.video.srcObject = mediaStream;
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must reinsert the video in the DOM for
// the media stream to be updated
const vParent = streamManagerVideo.video.parentElement;
const newVideo = streamManagerVideo.video;
vParent!!.replaceChild(newVideo, streamManagerVideo.video);
streamManagerVideo.video = newVideo;
}
});
}
@ -431,8 +439,10 @@ export class StreamManager implements EventDispatcher {
}
private mirrorVideo(video): void {
video.style.transform = 'rotateY(180deg)';
video.style.webkitTransform = 'rotateY(180deg)';
if (!platform['isIonicIos']) {
video.style.transform = 'rotateY(180deg)';
video.style.webkitTransform = 'rotateY(180deg)';
}
}
private removeMirrorVideo(video): void {

View File

@ -17,8 +17,6 @@
import freeice = require('freeice');
import uuid = require('uuid');
import platform = require('platform');
export interface WebRtcPeerConfiguration {
mediaConstraints: {
@ -87,8 +85,14 @@ export class WebRtcPeer {
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) {
for (const track of this.configuration.mediaStream.getTracks()) {
this.pc.addTrack(track, this.configuration.mediaStream);
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
const pc2: any = this.pc;
pc2.addStream(this.configuration.mediaStream);
} else {
for (const track of this.configuration.mediaStream.getTracks()) {
this.pc.addTrack(track, this.configuration.mediaStream);
}
}
resolve();
}
@ -108,19 +112,37 @@ export class WebRtcPeer {
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
// Stop senders
for (const sender of this.pc.getSenders()) {
if (!videoSourceIsMediaStreamTrack) {
if (!!sender.track) {
sender.track.stop();
if (platform['isIonicIos']) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
// Stop senders deprecated
const pc1: any = this.pc;
for (const sender of pc1.getLocalStreams()) {
if (!videoSourceIsMediaStreamTrack) {
(<MediaStream>sender).stop();
}
pc1.removeStream(sender);
}
// Stop receivers deprecated
for (const receiver of pc1.getRemoteStreams()) {
if (!!receiver.track) {
(<MediaStream>receiver).stop();
}
}
this.pc.removeTrack(sender);
}
// Stop receivers
for (const receiver of this.pc.getReceivers()) {
if (!!receiver.track) {
receiver.track.stop();
} else {
// Stop senders
for (const sender of this.pc.getSenders()) {
if (!videoSourceIsMediaStreamTrack) {
if (!!sender.track) {
sender.track.stop();
}
}
this.pc.removeTrack(sender);
}
// Stop receivers
for (const receiver of this.pc.getReceivers()) {
if (!!receiver.track) {
receiver.track.stop();
}
}
}
@ -154,8 +176,8 @@ export class WebRtcPeer {
console.debug('RTCPeerConnection constraints: ' + JSON.stringify(constraints));
if (platform.name === 'Safari') {
// Safari, at least on iOS just seems to support unified plan, whereas in other browsers is not yet ready and considered experimental
if (platform.name === 'Safari' && platform.ua!!.indexOf('Safari') !== -1) {
// Safari (excluding Ionic), at least on iOS just seems to support unified plan, whereas in other browsers is not yet ready and considered experimental
if (offerAudio) {
this.pc.addTransceiver('audio', {
direction: this.configuration.mode,

View File

@ -18,7 +18,6 @@
// tslint:disable:no-string-literal
import { Stream } from '../../OpenVidu/Stream';
import platform = require('platform');
export class WebRtcStats {

View File

@ -61,9 +61,9 @@
"dev": true
},
"@types/node": {
"version": "10.12.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.6.tgz",
"integrity": "sha512-+ZWB5Ec1iki99xQFzBlivlKxSZQ+fuUKBott8StBOnLN4dWbRHlgdg1XknpW6g0tweniN5DcOqA64CJyOUPSAw==",
"version": "10.12.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.10.tgz",
"integrity": "sha512-8xZEYckCbUVgK8Eg7lf5Iy4COKJ5uXlnIOnePN0WUwSQggy9tolM+tDJf7wMOnT/JT/W9xDYIaYggt3mRV2O5w==",
"dev": true
},
"@types/shelljs": {
@ -478,9 +478,9 @@
}
},
"caniuse-db": {
"version": "1.0.30000907",
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000907.tgz",
"integrity": "sha512-OKtlTmEPR9GgCxnKMlvdHTT2QD6n4eIovcVqEnjoR8iB9l6rk4abKnjsDSyTD36an/ebgigl8T2CSdwSf4JoGw==",
"version": "1.0.30000912",
"resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000912.tgz",
"integrity": "sha512-uiepPdHcJ06Na9t15L5l+pp3NWQU4IETbmleghD6tqCqbIYqhHSu7nVfbK2gqPjfy+9jl/wHF1UQlyTszh9tJQ==",
"dev": true
},
"chalk": {
@ -1075,9 +1075,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.5.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz",
"integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==",
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
@ -2666,7 +2666,7 @@
},
"lru-cache": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
"resolved": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
"integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
"dev": true
},
@ -3197,7 +3197,7 @@
},
"pretty-bytes": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
"resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
"integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=",
"dev": true,
"requires": {
@ -3217,9 +3217,9 @@
"dev": true
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.6.0.tgz",
"integrity": "sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA==",
"dev": true
},
"raw-body": {
@ -3270,7 +3270,7 @@
"dependencies": {
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@ -3586,7 +3586,7 @@
},
"source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"requires": {
@ -3706,7 +3706,7 @@
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
@ -3937,6 +3937,14 @@
"shelljs": "^0.8.2",
"typedoc-default-themes": "^0.5.0",
"typescript": "3.1.x"
},
"dependencies": {
"typescript": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz",
"integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==",
"dev": true
}
}
},
"typedoc-default-themes": {
@ -3946,9 +3954,9 @@
"dev": true
},
"typescript": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz",
"integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==",
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.1.tgz",
"integrity": "sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg==",
"dev": true
},
"uglify-js": {

View File

@ -6,7 +6,7 @@
},
"description": "OpenVidu Node Client",
"devDependencies": {
"@types/node": "10.12.6",
"@types/node": "10.12.10",
"grunt": "1.0.3",
"grunt-autoprefixer": "3.0.4",
"grunt-cli": "1.3.2",
@ -19,7 +19,7 @@
"ts-node": "7.0.1",
"tslint": "5.11.0",
"typedoc": "0.13.0",
"typescript": "3.1.6"
"typescript": "3.2.1"
},
"license": "Apache-2.0",
"main": "lib/index.js",