2018-10-23 18:09:48 +02:00
var OPENVIDU _SERVER _URL ;
var OPENVIDU _SERVER _SECRET ;
var SESSION _ID ;
2018-10-23 18:11:23 +02:00
var USER _ID ;
2018-10-23 18:09:48 +02:00
var OV ;
var session ;
var rtcPeerConnectionStats = { } ;
window . onload = ( ) => {
var url = new URL ( window . location . href ) ;
OPENVIDU _SERVER _URL = url . searchParams . get ( "publicurl" ) ;
OPENVIDU _SERVER _SECRET = url . searchParams . get ( "secret" ) ;
SESSION _ID = url . searchParams . get ( "sessionId" ) ;
USER _ID = url . searchParams . get ( "userId" ) ;
if ( ! OPENVIDU _SERVER _URL || ! OPENVIDU _SERVER _SECRET || ! SESSION _ID || ! USER _ID ) {
initFormValues ( ) ;
document . getElementById ( 'join-form' ) . style . display = 'block' ;
} else {
joinSession ( ) ;
}
} ;
function joinSession ( ) {
OV = new OpenVidu ( ) ;
session = OV . initSession ( ) ;
session . on ( "streamCreated" , event => {
var subscriber = session . subscribe ( event . stream , insertVideoContainer ( event ) ) ;
subscriber . on ( 'videoPlaying' , e => {
var userId = event . stream . connection . data ;
gatherStats ( event . stream . getRTCPeerConnection ( ) , userId ) ;
rtcPeerConnectionStats [ userId ] = {
interval : window . setInterval (
( ) => {
gatherStats ( event . stream . getRTCPeerConnection ( ) , userId ) ;
} , 1000 )
}
} ) ;
} ) ;
session . on ( "streamDestroyed" , event => {
var userId = event . stream . connection . data ;
window . clearInterval ( rtcPeerConnectionStats [ userId ] . interval ) ;
delete rtcPeerConnectionStats [ userId ] ;
document . getElementById ( 'video-' + userId ) . outerHTML = "" ;
} ) ;
getToken ( ) . then ( token => {
session . connect ( token , USER _ID )
. then ( ( ) => {
var publisher = OV . initPublisher ( 'local' , { resolution : "540x320" , frameRate : 30 } ) ;
session . publish ( publisher ) ;
} )
. catch ( error => {
console . log ( "There was an error connecting to the session:" , error . code , error . message ) ;
} ) ;
} ) ;
}
function leaveSession ( ) {
session . disconnect ( ) ;
}
window . onbeforeunload = ( ) => {
if ( session ) leaveSession ( ) ;
} ;
function insertVideoContainer ( event ) {
var commonTagStyle = "background-color: #0088aa; color: white; font-weight: bold; padding: 2px 5px; border-radius: 3px; font-family: 'Arial'" ;
var videoContainer = document . createElement ( 'div' ) ;
videoContainer . id = 'video-' + event . stream . connection . data ;
videoContainer . setAttribute ( "style" , "display: inline-block; margin: 5px 5px 0 0" ) ;
var infoContainer = document . createElement ( 'div' ) ;
infoContainer . setAttribute ( "style" , "text-align: center; margin-bottom: 3px" ) ;
var userId = document . createElement ( 'div' ) ;
userId . setAttribute ( "style" , "float: left; " + commonTagStyle ) ;
userId . innerText = event . stream . connection . data ;
var resolution = document . createElement ( 'div' ) ;
resolution . id = 'resolution-' + event . stream . connection . data ;
resolution . setAttribute ( "style" , "display: inline-block; " + commonTagStyle ) ;
resolution . innerText = event . stream . videoDimensions . width + 'x' + event . stream . videoDimensions . height ;
var bitrate = document . createElement ( 'div' ) ;
bitrate . id = 'bitrate-' + event . stream . connection . data ;
bitrate . setAttribute ( "style" , "float: right; " + commonTagStyle ) ;
infoContainer . appendChild ( userId ) ;
infoContainer . appendChild ( resolution ) ;
infoContainer . appendChild ( bitrate ) ;
videoContainer . appendChild ( infoContainer ) ;
document . body . appendChild ( videoContainer ) ;
return videoContainer ;
}
function initFormValues ( ) {
document . getElementById ( "form-publicurl" ) . value = OPENVIDU _SERVER _URL ;
document . getElementById ( "form-secret" ) . value = OPENVIDU _SERVER _SECRET ;
document . getElementById ( "form-sessionId" ) . value = SESSION _ID ;
document . getElementById ( "form-userId" ) . value = USER _ID ;
}
function joinWithForm ( ) {
OPENVIDU _SERVER _URL = document . getElementById ( "form-publicurl" ) . value ;
OPENVIDU _SERVER _SECRET = document . getElementById ( "form-secret" ) . value ;
SESSION _ID = document . getElementById ( "form-sessionId" ) . value ;
USER _ID = document . getElementById ( "form-userId" ) . value ;
document . getElementById ( 'join-form' ) . style . display = 'none' ;
joinSession ( ) ;
return false ;
}
function getToken ( ) {
return createSession ( ) . then ( sessionId => createToken ( sessionId ) ) ;
}
function createSession ( ) { // See https://openvidu.io/docs/reference-docs/REST-API/#post-apisessions
return new Promise ( ( resolve , reject ) => {
var request = new XMLHttpRequest ( ) ;
request . open ( "POST" , OPENVIDU _SERVER _URL + "api/sessions" , true ) ;
request . setRequestHeader ( 'Content-Type' , 'application/json' ) ;
request . setRequestHeader ( 'Authorization' , "Basic " + btoa ( "OPENVIDUAPP:" + OPENVIDU _SERVER _SECRET ) ) ;
request . onreadystatechange = ( ) => {
if ( request . readyState === 4 ) {
if ( request . status === 200 || request . status === 409 ) {
resolve ( SESSION _ID ) ;
} else {
console . warn ( 'No connection to OpenVidu Server. This may be a certificate error at ' + OPENVIDU _SERVER _URL ) ;
if ( window . confirm ( 'No connection to OpenVidu Server. This may be a certificate error at \"' + OPENVIDU _SERVER _URL + '\"\n\nClick OK to navigate and accept it. ' +
'If no certificate warning is shown, then check that your OpenVidu Server is up and running at "' + OPENVIDU _SERVER _URL + '"' ) ) {
location . assign ( OPENVIDU _SERVER _URL + '/accept-certificate' ) ;
}
}
} ;
}
request . send ( JSON . stringify ( { customSessionId : SESSION _ID } ) ) ;
} ) ;
}
function createToken ( ) { // See https://openvidu.io/docs/reference-docs/REST-API/#post-apitokens
return new Promise ( ( resolve , reject ) => {
var request = new XMLHttpRequest ( ) ;
request . open ( "POST" , OPENVIDU _SERVER _URL + "api/tokens" , true ) ;
request . setRequestHeader ( 'Content-Type' , 'application/json' ) ;
request . setRequestHeader ( 'Authorization' , "Basic " + btoa ( "OPENVIDUAPP:" + OPENVIDU _SERVER _SECRET ) ) ;
request . onreadystatechange = ( ) => {
if ( request . readyState === 4 ) {
if ( request . status == 200 ) {
resolve ( JSON . parse ( request . response ) . token ) ;
} else {
reject ( new Error ( request . responseText ) )
}
} ;
}
request . send ( JSON . stringify ( { session : SESSION _ID } ) ) ;
} ) ;
}
function gatherStats ( rtcPeerConnection , userId , errorCallback ) {
return rtcPeerConnection . getStats ( response => {
const fullReport = [ ] ;
response . result ( ) . forEach ( report => {
const stat = {
id : report . id ,
timestamp : report . timestamp ,
type : report . type
} ;
report . names ( ) . forEach ( ( name ) => {
stat [ name ] = report . stat ( name ) ;
} ) ;
fullReport . push ( stat ) ;
} ) ;
if ( ! rtcPeerConnectionStats [ userId ] . rtt ) {
var activeCandidateStats = fullReport . find ( report => report . type === 'googCandidatePair' && report . googActiveConnection === 'true' ) ;
if ( ! ! activeCandidateStats ) {
rtcPeerConnectionStats [ userId ] = {
rtt : activeCandidateStats . googRtt ,
transport : activeCandidateStats . googTransportType ,
candidateType : activeCandidateStats . googRemoteCandidateType ,
localAddress : activeCandidateStats . googLocalAddress ,
remoteAddress : activeCandidateStats . googRemoteAddress ,
interval : rtcPeerConnectionStats [ userId ] . interval
}
}
}
var videoStats = fullReport . find ( report => report . type === 'ssrc' && report . mediaType === 'video' ) ;
if ( ! ! videoStats ) {
rtcPeerConnectionStats [ userId ] . bitRate = ( videoStats . bytesReceived - rtcPeerConnectionStats [ userId ] . bytesReceived ) * 8 / 1000 ;
rtcPeerConnectionStats [ userId ] . jitter = videoStats . googJitterBufferMs ;
rtcPeerConnectionStats [ userId ] . bytesReceived = videoStats . bytesReceived ;
rtcPeerConnectionStats [ userId ] . delay = videoStats . googCurrentDelayMs ;
rtcPeerConnectionStats [ userId ] . packetsLost = videoStats . packetsLost ;
document . querySelector ( '#bitrate-' + userId ) . innerText = Math . floor ( rtcPeerConnectionStats [ userId ] . bitRate ) + ' kbps' ;
}
console . log ( rtcPeerConnectionStats ) ;
} , null , errorCallback ) ;
}