2018-04-26 15:33:47 +02:00
"use strict" ;
/ *
2018-05-06 02:20:25 +02:00
* ( C ) Copyright 2017 - 2018 OpenVidu ( https : //openvidu.io/)
2018-04-26 15:33:47 +02:00
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*
* /
exports . _ _esModule = true ;
2018-10-01 11:17:05 +02:00
var Filter _1 = require ( "./Filter" ) ;
2018-06-27 16:29:31 +02:00
var WebRtcPeer _1 = require ( "../OpenViduInternal/WebRtcPeer/WebRtcPeer" ) ;
2018-04-26 15:33:47 +02:00
var WebRtcStats _1 = require ( "../OpenViduInternal/WebRtcStats/WebRtcStats" ) ;
var PublisherSpeakingEvent _1 = require ( "../OpenViduInternal/Events/PublisherSpeakingEvent" ) ;
2018-12-14 14:01:16 +01:00
var StreamManagerEvent _1 = require ( "../OpenViduInternal/Events/StreamManagerEvent" ) ;
2018-10-01 11:17:05 +02:00
var StreamPropertyChangedEvent _1 = require ( "../OpenViduInternal/Events/StreamPropertyChangedEvent" ) ;
2018-12-14 14:01:16 +01:00
var OpenViduError _1 = require ( "../OpenViduInternal/Enums/OpenViduError" ) ;
2018-04-26 15:33:47 +02:00
var EventEmitter = require ( "wolfy87-eventemitter" ) ;
2018-06-27 16:29:31 +02:00
var hark = require ( "hark" ) ;
2018-12-14 14:01:16 +01:00
var platform = require ( "platform" ) ;
platform [ 'isIonicIos' ] = ( platform . product === 'iPhone' || platform . product === 'iPad' ) && platform . ua . indexOf ( 'Safari' ) === - 1 ;
2018-04-26 15:33:47 +02:00
/ * *
2018-06-01 14:39:38 +02:00
* 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
* to one of them ( sending and receiving it , respectively )
2018-04-26 15:33:47 +02:00
* /
var Stream = /** @class */ ( function ( ) {
/ * *
* @ hidden
* /
function Stream ( session , options ) {
var _this = this ;
/ * *
* @ hidden
* /
2018-06-01 14:39:38 +02:00
this . ee = new EventEmitter ( ) ;
this . isSubscribeToRemote = false ;
2018-04-26 15:33:47 +02:00
/ * *
* @ hidden
* /
2018-06-01 14:39:38 +02:00
this . isLocalStreamReadyToPublish = false ;
2018-04-26 15:33:47 +02:00
/ * *
* @ hidden
* /
2018-06-01 14:39:38 +02:00
this . isLocalStreamPublished = false ;
2018-07-11 11:47:53 +02:00
/ * *
* @ hidden
* /
this . publishedOnce = false ;
2018-12-14 14:01:16 +01:00
/ * *
* @ hidden
* /
this . publisherStartSpeakingEventEnabled = false ;
/ * *
* @ hidden
* /
this . publisherStopSpeakingEventEnabled = false ;
/ * *
* @ hidden
* /
this . volumeChangeEventEnabled = false ;
2018-04-26 15:33:47 +02:00
this . session = session ;
if ( options . hasOwnProperty ( 'id' ) ) {
// InboundStreamOptions: stream belongs to a Subscriber
this . inboundStreamOpts = options ;
this . streamId = this . inboundStreamOpts . id ;
2018-07-11 11:47:53 +02:00
this . hasAudio = this . inboundStreamOpts . hasAudio ;
this . hasVideo = this . inboundStreamOpts . hasVideo ;
if ( this . hasAudio ) {
this . audioActive = this . inboundStreamOpts . audioActive ;
}
if ( this . hasVideo ) {
this . videoActive = this . inboundStreamOpts . videoActive ;
this . typeOfVideo = ( ! this . inboundStreamOpts . typeOfVideo ) ? undefined : this . inboundStreamOpts . typeOfVideo ;
this . frameRate = ( this . inboundStreamOpts . frameRate === - 1 ) ? undefined : this . inboundStreamOpts . frameRate ;
this . videoDimensions = this . inboundStreamOpts . videoDimensions ;
}
2018-10-01 11:17:05 +02:00
if ( ! ! this . inboundStreamOpts . filter && ( Object . keys ( this . inboundStreamOpts . filter ) . length > 0 ) ) {
if ( ! ! this . inboundStreamOpts . filter . lastExecMethod && Object . keys ( this . inboundStreamOpts . filter . lastExecMethod ) . length === 0 ) {
delete this . inboundStreamOpts . filter . lastExecMethod ;
}
this . filter = this . inboundStreamOpts . filter ;
}
2018-04-26 15:33:47 +02:00
}
else {
// OutboundStreamOptions: stream belongs to a Publisher
this . outboundStreamOpts = options ;
2018-07-11 11:47:53 +02:00
this . hasAudio = this . isSendAudio ( ) ;
this . hasVideo = this . isSendVideo ( ) ;
if ( this . hasAudio ) {
this . audioActive = ! ! this . outboundStreamOpts . publisherProperties . publishAudio ;
}
if ( this . hasVideo ) {
this . videoActive = ! ! this . outboundStreamOpts . publisherProperties . publishVideo ;
this . frameRate = this . outboundStreamOpts . publisherProperties . frameRate ;
if ( this . outboundStreamOpts . publisherProperties . videoSource instanceof MediaStreamTrack ) {
this . typeOfVideo = 'CUSTOM' ;
2018-04-26 15:33:47 +02:00
}
else {
2018-07-11 11:47:53 +02:00
this . typeOfVideo = this . isSendScreen ( ) ? 'SCREEN' : 'CAMERA' ;
2018-04-26 15:33:47 +02:00
}
}
2018-10-01 11:17:05 +02:00
if ( ! ! this . outboundStreamOpts . publisherProperties . filter ) {
this . filter = this . outboundStreamOpts . publisherProperties . filter ;
}
2018-04-26 15:33:47 +02:00
}
2018-06-01 14:39:38 +02:00
this . ee . on ( 'mediastream-updated' , function ( ) {
_this . streamManager . updateMediaStream ( _this . mediaStream ) ;
2018-04-26 15:33:47 +02:00
console . debug ( 'Video srcObject [' + _this . mediaStream + '] updated in stream [' + _this . streamId + ']' ) ;
} ) ;
}
2018-10-01 11:17:05 +02:00
/ * *
* See [ [ EventDispatcher . on ] ]
* /
Stream . prototype . on = function ( type , handler ) {
var _this = this ;
this . ee . on ( type , function ( event ) {
if ( event ) {
console . info ( "Event '" + type + "' triggered by stream '" + _this . streamId + "'" , event ) ;
}
else {
console . info ( "Event '" + type + "' triggered by stream '" + _this . streamId + "'" ) ;
}
handler ( event ) ;
} ) ;
return this ;
} ;
/ * *
* See [ [ EventDispatcher . once ] ]
* /
Stream . prototype . once = function ( type , handler ) {
var _this = this ;
this . ee . once ( type , function ( event ) {
if ( event ) {
console . info ( "Event '" + type + "' triggered once by stream '" + _this . streamId + "'" , event ) ;
}
else {
console . info ( "Event '" + type + "' triggered once by stream '" + _this . streamId + "'" ) ;
}
handler ( event ) ;
} ) ;
return this ;
} ;
/ * *
* See [ [ EventDispatcher . off ] ]
* /
Stream . prototype . off = function ( type , handler ) {
if ( ! handler ) {
this . ee . removeAllListeners ( type ) ;
}
else {
this . ee . off ( type , handler ) ;
}
return this ;
} ;
/ * *
* Applies an audio / video filter to the stream .
*
* @ param type Type of filter applied . See [ [ Filter . type ] ]
* @ param options Parameters used to initialize the filter . See [ [ Filter . options ] ]
*
* @ returns A Promise ( to which you can optionally subscribe to ) that is resolved to the applied filter if success and rejected with an Error object if not
* /
Stream . prototype . applyFilter = function ( type , options ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
console . info ( 'Applying filter to stream ' + _this . streamId ) ;
options = ! ! options ? options : { } ;
if ( typeof options !== 'string' ) {
options = JSON . stringify ( options ) ;
}
_this . session . openvidu . sendRequest ( 'applyFilter' , { streamId : _this . streamId , type : type , options : options } , function ( error , response ) {
if ( error ) {
console . error ( 'Error applying filter for Stream ' + _this . streamId , error ) ;
if ( error . code === 401 ) {
reject ( new OpenViduError _1 . OpenViduError ( OpenViduError _1 . OpenViduErrorName . OPENVIDU _PERMISSION _DENIED , "You don't have permissions to apply a filter" ) ) ;
}
else {
reject ( error ) ;
}
}
else {
console . info ( 'Filter successfully applied on Stream ' + _this . streamId ) ;
var oldValue = _this . filter ;
_this . filter = new Filter _1 . Filter ( type , options ) ;
_this . filter . stream = _this ;
_this . session . emitEvent ( 'streamPropertyChanged' , [ new StreamPropertyChangedEvent _1 . StreamPropertyChangedEvent ( _this . session , _this , 'filter' , _this . filter , oldValue , 'applyFilter' ) ] ) ;
_this . streamManager . emitEvent ( 'streamPropertyChanged' , [ new StreamPropertyChangedEvent _1 . StreamPropertyChangedEvent ( _this . streamManager , _this , 'filter' , _this . filter , oldValue , 'applyFilter' ) ] ) ;
resolve ( _this . filter ) ;
}
} ) ;
} ) ;
} ;
/ * *
* Removes an audio / video filter previously applied .
*
* @ returns A Promise ( to which you can optionally subscribe to ) that is resolved if the previously applied filter has been successfully removed and rejected with an Error object in other case
* /
Stream . prototype . removeFilter = function ( ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
console . info ( 'Removing filter of stream ' + _this . streamId ) ;
_this . session . openvidu . sendRequest ( 'removeFilter' , { streamId : _this . streamId } , function ( error , response ) {
if ( error ) {
console . error ( 'Error removing filter for Stream ' + _this . streamId , error ) ;
if ( error . code === 401 ) {
reject ( new OpenViduError _1 . OpenViduError ( OpenViduError _1 . OpenViduErrorName . OPENVIDU _PERMISSION _DENIED , "You don't have permissions to remove a filter" ) ) ;
}
else {
reject ( error ) ;
}
}
else {
console . info ( 'Filter successfully removed from Stream ' + _this . streamId ) ;
var oldValue = _this . filter ;
delete _this . filter ;
_this . session . emitEvent ( 'streamPropertyChanged' , [ new StreamPropertyChangedEvent _1 . StreamPropertyChangedEvent ( _this . session , _this , 'filter' , _this . filter , oldValue , 'applyFilter' ) ] ) ;
_this . streamManager . emitEvent ( 'streamPropertyChanged' , [ new StreamPropertyChangedEvent _1 . StreamPropertyChangedEvent ( _this . streamManager , _this , 'filter' , _this . filter , oldValue , 'applyFilter' ) ] ) ;
resolve ( ) ;
}
} ) ;
} ) ;
} ;
2018-04-26 15:33:47 +02:00
/* Hidden methods */
/ * *
* @ hidden
* /
Stream . prototype . getMediaStream = function ( ) {
return this . mediaStream ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . setMediaStream = function ( mediaStream ) {
this . mediaStream = mediaStream ;
2018-06-01 14:39:38 +02:00
} ;
/ * *
* @ hidden
* /
Stream . prototype . updateMediaStreamInVideos = function ( ) {
2018-04-26 15:33:47 +02:00
this . ee . emitEvent ( 'mediastream-updated' ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . getWebRtcPeer = function ( ) {
return this . webRtcPeer ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . getRTCPeerConnection = function ( ) {
2018-06-27 16:29:31 +02:00
return this . webRtcPeer . pc ;
2018-04-26 15:33:47 +02:00
} ;
/ * *
* @ hidden
* /
2018-06-01 14:39:38 +02:00
Stream . prototype . subscribeToMyRemote = function ( value ) {
this . isSubscribeToRemote = value ;
2018-04-26 15:33:47 +02:00
} ;
/ * *
* @ hidden
* /
Stream . prototype . setOutboundStreamOptions = function ( outboundStreamOpts ) {
this . outboundStreamOpts = outboundStreamOpts ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . subscribe = function ( ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
_this . initWebRtcPeerReceive ( )
. then ( function ( ) {
resolve ( ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( error ) ;
} ) ;
} ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . publish = function ( ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
2018-06-01 14:39:38 +02:00
if ( _this . isLocalStreamReadyToPublish ) {
2018-04-26 15:33:47 +02:00
_this . initWebRtcPeerSend ( )
. then ( function ( ) {
resolve ( ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( error ) ;
} ) ;
}
else {
2018-06-01 14:39:38 +02:00
_this . ee . once ( 'stream-ready-to-publish' , function ( ) {
2018-04-26 15:33:47 +02:00
_this . publish ( )
. then ( function ( ) {
resolve ( ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( error ) ;
} ) ;
} ) ;
}
} ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . disposeWebRtcPeer = function ( ) {
if ( this . webRtcPeer ) {
2018-10-01 11:17:05 +02:00
var isSenderAndCustomTrack = ! ! this . outboundStreamOpts &&
this . outboundStreamOpts . publisherProperties . videoSource instanceof MediaStreamTrack ;
this . webRtcPeer . dispose ( isSenderAndCustomTrack ) ;
2018-04-26 15:33:47 +02:00
}
if ( this . speechEvent ) {
this . speechEvent . stop ( ) ;
2018-12-14 14:01:16 +01:00
delete this . speechEvent ;
2018-04-26 15:33:47 +02:00
}
this . stopWebRtcStats ( ) ;
console . info ( ( ! ! this . outboundStreamOpts ? 'Outbound ' : 'Inbound ' ) + "WebRTCPeer from 'Stream' with id [" + this . streamId + '] is now closed' ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . disposeMediaStream = function ( ) {
if ( this . mediaStream ) {
this . mediaStream . getAudioTracks ( ) . forEach ( function ( track ) {
track . stop ( ) ;
} ) ;
this . mediaStream . getVideoTracks ( ) . forEach ( function ( track ) {
track . stop ( ) ;
} ) ;
2018-06-01 14:39:38 +02:00
delete this . mediaStream ;
2018-04-26 15:33:47 +02:00
}
console . info ( ( ! ! this . outboundStreamOpts ? 'Local ' : 'Remote ' ) + "MediaStream from 'Stream' with id [" + this . streamId + '] is now disposed' ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . displayMyRemote = function ( ) {
return this . isSubscribeToRemote ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . isSendAudio = function ( ) {
return ( ! ! this . outboundStreamOpts &&
this . outboundStreamOpts . publisherProperties . audioSource !== null &&
this . outboundStreamOpts . publisherProperties . audioSource !== false ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . isSendVideo = function ( ) {
return ( ! ! this . outboundStreamOpts &&
this . outboundStreamOpts . publisherProperties . videoSource !== null &&
this . outboundStreamOpts . publisherProperties . videoSource !== false ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . isSendScreen = function ( ) {
return ( ! ! this . outboundStreamOpts &&
this . outboundStreamOpts . publisherProperties . videoSource === 'screen' ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . setSpeechEventIfNotExists = function ( ) {
if ( ! this . speechEvent ) {
var harkOptions = this . session . openvidu . advancedConfiguration . publisherSpeakingEventsOptions || { } ;
harkOptions . interval = ( typeof harkOptions . interval === 'number' ) ? harkOptions . interval : 50 ;
harkOptions . threshold = ( typeof harkOptions . threshold === 'number' ) ? harkOptions . threshold : - 50 ;
2018-06-27 16:29:31 +02:00
this . speechEvent = hark ( this . mediaStream , harkOptions ) ;
2018-04-26 15:33:47 +02:00
}
} ;
/ * *
* @ hidden
* /
Stream . prototype . enableSpeakingEvents = function ( ) {
var _this = this ;
this . setSpeechEventIfNotExists ( ) ;
2018-12-14 14:01:16 +01:00
if ( ! this . publisherStartSpeakingEventEnabled ) {
this . publisherStartSpeakingEventEnabled = true ;
this . speechEvent . on ( 'speaking' , function ( ) {
_this . session . emitEvent ( 'publisherStartSpeaking' , [ new PublisherSpeakingEvent _1 . PublisherSpeakingEvent ( _this . session , 'publisherStartSpeaking' , _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 ) ] ) ;
} ) ;
}
2018-04-26 15:33:47 +02:00
} ;
/ * *
* @ hidden
* /
Stream . prototype . enableOnceSpeakingEvents = function ( ) {
var _this = this ;
this . setSpeechEventIfNotExists ( ) ;
2018-12-14 14:01:16 +01:00
if ( ! this . publisherStartSpeakingEventEnabled ) {
this . publisherStartSpeakingEventEnabled = true ;
this . speechEvent . once ( 'speaking' , function ( ) {
_this . session . emitEvent ( 'publisherStartSpeaking' , [ new PublisherSpeakingEvent _1 . PublisherSpeakingEvent ( _this . session , 'publisherStartSpeaking' , _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 ( ) ;
} ) ;
}
2018-04-26 15:33:47 +02:00
} ;
/ * *
* @ hidden
* /
Stream . prototype . disableSpeakingEvents = function ( ) {
2018-12-14 14:01:16 +01:00
if ( ! ! this . speechEvent ) {
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 ;
2018-04-26 15:33:47 +02:00
} ;
2018-06-27 16:29:31 +02:00
/ * *
* @ hidden
* /
Stream . prototype . isLocal = function ( ) {
// inbound options undefined and outbound options defined
return ( ! this . inboundStreamOpts && ! ! this . outboundStreamOpts ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . getSelectedIceCandidate = function ( ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
_this . webRtcStats . getSelectedIceCandidateInfo ( )
. then ( function ( report ) { return resolve ( report ) ; } ) [ "catch" ] ( function ( error ) { return reject ( error ) ; } ) ;
} ) ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . getRemoteIceCandidateList = function ( ) {
return this . webRtcPeer . remoteCandidatesQueue ;
} ;
/ * *
* @ hidden
* /
Stream . prototype . getLocalIceCandidateList = function ( ) {
return this . webRtcPeer . localCandidatesQueue ;
} ;
2018-04-26 15:33:47 +02:00
/* Private methods */
Stream . prototype . initWebRtcPeerSend = function ( ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
var userMediaConstraints = {
audio : _this . isSendAudio ( ) ,
video : _this . isSendVideo ( )
} ;
var options = {
2018-06-27 16:29:31 +02:00
mediaStream : _this . mediaStream ,
2018-04-26 15:33:47 +02:00
mediaConstraints : userMediaConstraints ,
onicecandidate : _this . connection . sendIceCandidate . bind ( _this . connection ) ,
2018-06-27 16:29:31 +02:00
iceServers : _this . getIceServersConf ( ) ,
simulcast : false
2018-04-26 15:33:47 +02:00
} ;
2018-06-27 16:29:31 +02:00
var successCallback = function ( sdpOfferParam ) {
2018-04-26 15:33:47 +02:00
console . debug ( 'Sending SDP offer to publish as '
+ _this . streamId , sdpOfferParam ) ;
2018-07-11 11:47:53 +02:00
var typeOfVideo = '' ;
if ( _this . isSendVideo ( ) ) {
typeOfVideo = _this . outboundStreamOpts . publisherProperties . videoSource instanceof MediaStreamTrack ? 'CUSTOM' : ( _this . isSendScreen ( ) ? 'SCREEN' : 'CAMERA' ) ;
}
2018-04-26 15:33:47 +02:00
_this . session . openvidu . sendRequest ( 'publishVideo' , {
sdpOffer : sdpOfferParam ,
doLoopback : _this . displayMyRemote ( ) || false ,
2018-07-11 11:47:53 +02:00
hasAudio : _this . isSendAudio ( ) ,
hasVideo : _this . isSendVideo ( ) ,
audioActive : _this . audioActive ,
videoActive : _this . videoActive ,
typeOfVideo : typeOfVideo ,
frameRate : ! ! _this . frameRate ? _this . frameRate : - 1 ,
2018-10-01 11:17:05 +02:00
videoDimensions : JSON . stringify ( _this . videoDimensions ) ,
filter : _this . outboundStreamOpts . publisherProperties . filter
2018-04-26 15:33:47 +02:00
} , function ( error , response ) {
if ( error ) {
2018-07-11 11:47:53 +02:00
if ( error . code === 401 ) {
reject ( new OpenViduError _1 . OpenViduError ( OpenViduError _1 . OpenViduErrorName . OPENVIDU _PERMISSION _DENIED , "You don't have permissions to publish" ) ) ;
}
else {
reject ( 'Error on publishVideo: ' + JSON . stringify ( error ) ) ;
}
2018-04-26 15:33:47 +02:00
}
else {
2018-12-14 14:01:16 +01:00
_this . webRtcPeer . processAnswer ( response . sdpAnswer , false )
2018-04-26 15:33:47 +02:00
. then ( function ( ) {
2018-06-27 16:29:31 +02:00
_this . streamId = response . id ;
2018-06-01 14:39:38 +02:00
_this . isLocalStreamPublished = true ;
2018-07-11 11:47:53 +02:00
_this . publishedOnce = true ;
2018-06-01 14:39:38 +02:00
if ( _this . displayMyRemote ( ) ) {
2018-07-11 11:47:53 +02:00
_this . remotePeerSuccessfullyEstablished ( ) ;
2018-06-01 14:39:38 +02:00
}
2018-04-26 15:33:47 +02:00
_this . ee . emitEvent ( 'stream-created-by-publisher' ) ;
2018-06-27 16:29:31 +02:00
_this . initWebRtcStats ( ) ;
2018-04-26 15:33:47 +02:00
resolve ( ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( error ) ;
} ) ;
console . info ( "'Publisher' successfully published to session" ) ;
}
} ) ;
} ;
if ( _this . displayMyRemote ( ) ) {
2018-06-27 16:29:31 +02:00
_this . webRtcPeer = new WebRtcPeer _1 . WebRtcPeerSendrecv ( options ) ;
2018-04-26 15:33:47 +02:00
}
else {
2018-06-27 16:29:31 +02:00
_this . webRtcPeer = new WebRtcPeer _1 . WebRtcPeerSendonly ( options ) ;
2018-04-26 15:33:47 +02:00
}
2018-06-27 16:29:31 +02:00
_this . webRtcPeer . generateOffer ( ) . then ( function ( offer ) {
successCallback ( offer ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( new Error ( '(publish) SDP offer error: ' + JSON . stringify ( error ) ) ) ;
} ) ;
2018-04-26 15:33:47 +02:00
} ) ;
} ;
Stream . prototype . initWebRtcPeerReceive = function ( ) {
var _this = this ;
return new Promise ( function ( resolve , reject ) {
var offerConstraints = {
2018-07-11 11:47:53 +02:00
audio : _this . inboundStreamOpts . hasAudio ,
video : _this . inboundStreamOpts . hasVideo
2018-04-26 15:33:47 +02:00
} ;
console . debug ( "'Session.subscribe(Stream)' called. Constraints of generate SDP offer" , offerConstraints ) ;
var options = {
onicecandidate : _this . connection . sendIceCandidate . bind ( _this . connection ) ,
2018-06-27 16:29:31 +02:00
mediaConstraints : offerConstraints ,
iceServers : _this . getIceServersConf ( ) ,
simulcast : false
2018-04-26 15:33:47 +02:00
} ;
2018-06-27 16:29:31 +02:00
var successCallback = function ( sdpOfferParam ) {
2018-04-26 15:33:47 +02:00
console . debug ( 'Sending SDP offer to subscribe to '
+ _this . streamId , sdpOfferParam ) ;
_this . session . openvidu . sendRequest ( 'receiveVideoFrom' , {
sender : _this . streamId ,
sdpOffer : sdpOfferParam
} , function ( error , response ) {
if ( error ) {
reject ( new Error ( 'Error on recvVideoFrom: ' + JSON . stringify ( error ) ) ) ;
}
else {
2018-12-14 14:01:16 +01:00
// 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 ( ) {
2018-07-11 11:47:53 +02:00
_this . remotePeerSuccessfullyEstablished ( ) ;
2018-06-27 16:29:31 +02:00
_this . initWebRtcStats ( ) ;
2018-04-26 15:33:47 +02:00
resolve ( ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( error ) ;
} ) ;
}
} ) ;
} ;
2018-06-27 16:29:31 +02:00
_this . webRtcPeer = new WebRtcPeer _1 . WebRtcPeerRecvonly ( options ) ;
_this . webRtcPeer . generateOffer ( )
. then ( function ( offer ) {
successCallback ( offer ) ;
} ) [ "catch" ] ( function ( error ) {
reject ( new Error ( '(subscribe) SDP offer error: ' + JSON . stringify ( error ) ) ) ;
2018-04-26 15:33:47 +02:00
} ) ;
} ) ;
} ;
2018-07-11 11:47:53 +02:00
Stream . prototype . remotePeerSuccessfullyEstablished = function ( ) {
2018-12-14 14:01:16 +01:00
if ( platform [ 'isIonicIos' ] ) {
// iOS Ionic. LIMITATION: must use deprecated WebRTC API
var pc1 = this . webRtcPeer . pc ;
this . mediaStream = pc1 . getRemoteStreams ( ) [ 0 ] ;
}
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 ) ;
}
2018-10-01 11:17:05 +02:00
}
2018-12-14 14:01:16 +01:00
}
2018-06-27 16:29:31 +02:00
console . debug ( 'Peer remote stream' , this . mediaStream ) ;
if ( ! ! this . mediaStream ) {
this . ee . emitEvent ( 'mediastream-updated' ) ;
if ( ! this . displayMyRemote ( ) && ! ! this . mediaStream . getAudioTracks ( ) [ 0 ] && this . session . speakingEventsEnabled ) {
this . enableSpeakingEvents ( ) ;
}
}
2018-04-26 15:33:47 +02:00
} ;
Stream . prototype . initWebRtcStats = function ( ) {
this . webRtcStats = new WebRtcStats _1 . WebRtcStats ( this ) ;
this . webRtcStats . initWebRtcStats ( ) ;
} ;
Stream . prototype . stopWebRtcStats = function ( ) {
if ( ! ! this . webRtcStats && this . webRtcStats . isEnabled ( ) ) {
this . webRtcStats . stopWebRtcStats ( ) ;
}
} ;
2018-06-27 16:29:31 +02:00
Stream . prototype . getIceServersConf = function ( ) {
var returnValue ;
if ( ! ! this . session . openvidu . advancedConfiguration . iceServers ) {
returnValue = this . session . openvidu . advancedConfiguration . iceServers === 'freeice' ?
undefined :
this . session . openvidu . advancedConfiguration . iceServers ;
}
else if ( this . session . openvidu . iceServers ) {
returnValue = this . session . openvidu . iceServers ;
}
else {
returnValue = undefined ;
}
return returnValue ;
2018-04-26 15:33:47 +02:00
} ;
return Stream ;
} ( ) ) ;
exports . Stream = Stream ;
//# sourceMappingURL=Stream.js.map