Merge branch 'staging-1.9'
This commit is contained in:
commit
6ef4df96da
|
@ -297,6 +297,7 @@ library_include_HEADERS = \
|
|||
src/include/switch_curl.h \
|
||||
src/include/switch_json.h \
|
||||
src/include/switch_utf8.h \
|
||||
src/include/switch_msrp.h \
|
||||
src/include/switch_vpx.h \
|
||||
libs/libteletone/src/libteletone_detect.h \
|
||||
libs/libteletone/src/libteletone_generate.h \
|
||||
|
@ -378,6 +379,7 @@ libfreeswitch_la_SOURCES = \
|
|||
src/switch_curl.c \
|
||||
src/switch_hashtable.c\
|
||||
src/switch_utf8.c \
|
||||
src/switch_msrp.c \
|
||||
src/switch_vpx.c \
|
||||
libs/libtpl-1.5/src/tpl.c \
|
||||
libs/libteletone/src/libteletone_detect.c \
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<configuration name="msrp.conf" description="MSRP">
|
||||
<settings>
|
||||
<param name="listen-ip" value="$${local_ip_v4}"/>
|
||||
<param name="listen-port" value="2855"/>
|
||||
<param name="listen-ssl-port" value="2856"/>
|
||||
<!-- <param name="message-buffer-size" value="50"/> -->
|
||||
<!-- <param name="debug" value="true"/> -->
|
||||
</settings>
|
||||
</configuration>
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
# Must change all of the below together
|
||||
# For a release, set revision for that tagged release as well and uncomment
|
||||
AC_INIT([freeswitch], [1.7.0], bugs@freeswitch.org)
|
||||
AC_INIT([freeswitch], [1.9.0], bugs@freeswitch.org)
|
||||
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
||||
AC_SUBST(SWITCH_VERSION_MINOR, [7])
|
||||
AC_SUBST(SWITCH_VERSION_MINOR, [9])
|
||||
AC_SUBST(SWITCH_VERSION_MICRO, [0])
|
||||
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
||||
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
JSFILES=src/jquery.FSRTC.js src/jquery.jsonrpcclient.js src/jquery.verto.js
|
||||
JSFILES=src/jquery.FSRTC.js src/jquery.jsonrpcclient.js src/jquery.verto.js src/vendor/adapter-latest.js
|
||||
|
||||
all: jsmin verto-min.js
|
||||
|
||||
|
|
|
@ -100,22 +100,10 @@
|
|||
candidateList: []
|
||||
};
|
||||
|
||||
|
||||
if (moz) {
|
||||
this.constraints = {
|
||||
offerToReceiveAudio: this.options.useSpeak === "none" ? false : true,
|
||||
offerToReceiveVideo: this.options.useVideo ? true : false,
|
||||
};
|
||||
} else {
|
||||
this.constraints = {
|
||||
optional: [{
|
||||
'DtlsSrtpKeyAgreement': 'true'
|
||||
}],mandatory: {
|
||||
OfferToReceiveAudio: this.options.useSpeak === "none" ? false : true,
|
||||
OfferToReceiveVideo: this.options.useVideo ? true : false,
|
||||
}
|
||||
};
|
||||
}
|
||||
this.constraints = {
|
||||
offerToReceiveAudio: this.options.useSpeak === "none" ? false : true,
|
||||
offerToReceiveVideo: this.options.useVideo ? true : false,
|
||||
};
|
||||
|
||||
if (self.options.useVideo) {
|
||||
self.options.useVideo.style.display = 'none';
|
||||
|
@ -133,19 +121,11 @@
|
|||
if (obj) {
|
||||
self.options.useVideo = obj;
|
||||
self.options.localVideo = local;
|
||||
if (moz) {
|
||||
self.constraints.offerToReceiveVideo = true;
|
||||
} else {
|
||||
self.constraints.mandatory.OfferToReceiveVideo = true;
|
||||
}
|
||||
self.constraints.offerToReceiveVideo = true;
|
||||
} else {
|
||||
self.options.useVideo = null;
|
||||
self.options.localVideo = null;
|
||||
if (moz) {
|
||||
self.constraints.offerToReceiveVideo = false;
|
||||
} else {
|
||||
self.constraints.mandatory.OfferToReceiveVideo = false;
|
||||
}
|
||||
self.constraints.offerToReceiveVideo = false;
|
||||
}
|
||||
|
||||
if (self.options.useVideo) {
|
||||
|
@ -193,18 +173,9 @@
|
|||
};
|
||||
|
||||
function setCompat() {
|
||||
$.FSRTC.moz = !!navigator.mozGetUserMedia;
|
||||
//navigator.getUserMedia || (navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia);
|
||||
if (!navigator.getUserMedia) {
|
||||
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia;
|
||||
}
|
||||
}
|
||||
|
||||
function checkCompat() {
|
||||
if (!navigator.getUserMedia) {
|
||||
alert('This application cannot function in this browser.');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -258,6 +229,21 @@
|
|||
doCallback(self, "onICESDP", msg);
|
||||
}
|
||||
|
||||
FSRTCattachMediaStream = function(element, stream) {
|
||||
if (element && element.id && attachMediaStream) {
|
||||
attachMediaStream(element, stream);
|
||||
} else {
|
||||
if (typeof element.srcObject !== 'undefined') {
|
||||
element.srcObject = stream;
|
||||
} else if (typeof element.src !== 'undefined') {
|
||||
element.src = URL.createObjectURL(stream);
|
||||
} else {
|
||||
console.error('Error attaching stream to element.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onRemoteStream(self, stream) {
|
||||
if (self.options.useVideo) {
|
||||
self.options.useVideo.style.display = 'block';
|
||||
|
@ -266,16 +252,8 @@
|
|||
var element = self.options.useAudio;
|
||||
console.log("REMOTE STREAM", stream, element);
|
||||
|
||||
if (typeof element.srcObject !== 'undefined') {
|
||||
element.srcObject = stream;
|
||||
} else if (typeof element.mozSrcObject !== 'undefined') {
|
||||
element.mozSrcObject = stream;
|
||||
} else if (typeof element.src !== 'undefined') {
|
||||
element.src = URL.createObjectURL(stream);
|
||||
} else {
|
||||
console.error('Error attaching stream to element.');
|
||||
}
|
||||
|
||||
FSRTCattachMediaStream(element, stream);
|
||||
|
||||
self.options.useAudio.play();
|
||||
self.remoteStream = stream;
|
||||
}
|
||||
|
@ -306,11 +284,7 @@
|
|||
|
||||
if (self.options.useVideo) {
|
||||
self.options.useVideo.style.display = 'none';
|
||||
if (moz) {
|
||||
self.options.useVideo['mozSrcObject'] = null;
|
||||
} else {
|
||||
self.options.useVideo['src'] = '';
|
||||
}
|
||||
self.options.useVideo['src'] = '';
|
||||
}
|
||||
|
||||
if (self.localStream) {
|
||||
|
@ -331,11 +305,7 @@
|
|||
|
||||
if (self.options.localVideo) {
|
||||
self.options.localVideo.style.display = 'none';
|
||||
if (moz) {
|
||||
self.options.localVideo['mozSrcObject'] = null;
|
||||
} else {
|
||||
self.options.localVideo['src'] = '';
|
||||
}
|
||||
self.options.localVideo['src'] = '';
|
||||
}
|
||||
|
||||
if (self.options.localVideoStream) {
|
||||
|
@ -426,7 +396,7 @@
|
|||
function onSuccess(stream) {
|
||||
self.localStream = stream;
|
||||
|
||||
self.peer = RTCPeerConnection({
|
||||
self.peer = FSRTCPeerConnection({
|
||||
type: self.type,
|
||||
attachStream: self.localStream,
|
||||
onICE: function(candidate) {
|
||||
|
@ -469,8 +439,8 @@
|
|||
constraints: {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: self.options.videoParams,
|
||||
optional: []
|
||||
//mandatory: self.options.videoParams,
|
||||
//optional: []
|
||||
},
|
||||
},
|
||||
localVideo: self.options.localVideo,
|
||||
|
@ -501,31 +471,29 @@
|
|||
console.log("Microphone Disabled");
|
||||
audio = false;
|
||||
} else if (obj.options.videoParams && obj.options.screenShare) {//obj.options.videoParams.chromeMediaSource == 'desktop') {
|
||||
|
||||
//obj.options.videoParams = {
|
||||
// chromeMediaSource: 'screen',
|
||||
// maxWidth:screen.width,
|
||||
// maxHeight:screen.height
|
||||
// chromeMediaSourceId = sourceId;
|
||||
// };
|
||||
|
||||
console.error("SCREEN SHARE");
|
||||
console.error("SCREEN SHARE", obj.options.videoParams);
|
||||
audio = false;
|
||||
} else {
|
||||
audio = {
|
||||
mandatory: {},
|
||||
optional: []
|
||||
//mandatory: {},
|
||||
//optional: []
|
||||
advanced: []
|
||||
};
|
||||
|
||||
if (obj.options.useMic !== "any") {
|
||||
audio.optional = [{sourceId: obj.options.useMic}]
|
||||
//audio.optional = [{sourceId: obj.options.useMic}]
|
||||
audio.deviceId = {exact: obj.options.useMic};
|
||||
}
|
||||
|
||||
//FIXME
|
||||
if (obj.options.audioParams) {
|
||||
for (var key in obj.options.audioParams) {
|
||||
var con = {};
|
||||
con[key] = obj.options.audioParams[key];
|
||||
audio.optional.push(con);
|
||||
//con[key] = obj.options.audioParams[key];
|
||||
if (obj.options.audioParams[key]) {
|
||||
con.exact = key;
|
||||
audio.advanced.push(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,10 +504,8 @@
|
|||
getUserMedia({
|
||||
constraints: {
|
||||
audio: false,
|
||||
video: {
|
||||
mandatory: obj.options.videoParams,
|
||||
optional: []
|
||||
},
|
||||
video: obj.options.videoParams
|
||||
|
||||
},
|
||||
localVideo: obj.options.localVideo,
|
||||
onsuccess: function(e) {self.options.localVideoStream = e; console.log("local video ready");},
|
||||
|
@ -549,33 +515,57 @@
|
|||
|
||||
var video = {};
|
||||
var bestFrameRate = obj.options.videoParams.vertoBestFrameRate;
|
||||
var minFrameRate = obj.options.videoParams.minFrameRate || 15;
|
||||
delete obj.options.videoParams.vertoBestFrameRate;
|
||||
|
||||
video = {
|
||||
mandatory: obj.options.videoParams,
|
||||
optional: []
|
||||
}
|
||||
|
||||
var useVideo = obj.options.useVideo;
|
||||
|
||||
if (useVideo && obj.options.useCamera && obj.options.useCamera !== "none") {
|
||||
if (!video.optional) {
|
||||
video.optional = [];
|
||||
}
|
||||
|
||||
if (obj.options.useCamera !== "any") {
|
||||
video.optional.push({sourceId: obj.options.useCamera});
|
||||
}
|
||||
if (obj.options.screenShare) {
|
||||
// fix for chrome to work for now, will need to change once we figure out how to do this in a non-mandatory style constraint.
|
||||
var opt = [];
|
||||
opt.push({sourceId: obj.options.useCamera});
|
||||
|
||||
if (bestFrameRate) {
|
||||
video.optional.push({minFrameRate: bestFrameRate});
|
||||
video.optional.push({maxFrameRate: bestFrameRate});
|
||||
opt.push({minFrameRate: bestFrameRate});
|
||||
opt.push({maxFrameRate: bestFrameRate});
|
||||
}
|
||||
|
||||
video = {
|
||||
mandatory: obj.options.videoParams,
|
||||
optional: opt
|
||||
};
|
||||
} else {
|
||||
console.log("Camera Disabled");
|
||||
video = false;
|
||||
useVideo = false;
|
||||
|
||||
video = {
|
||||
//mandatory: obj.options.videoParams,
|
||||
width: {min: obj.options.videoParams.minWidth, max: obj.options.videoParams.maxWidth},
|
||||
height: {min: obj.options.videoParams.minHeight, max: obj.options.videoParams.maxHeight}
|
||||
};
|
||||
|
||||
|
||||
|
||||
var useVideo = obj.options.useVideo;
|
||||
|
||||
if (useVideo && obj.options.useCamera && obj.options.useCamera !== "none") {
|
||||
//if (!video.optional) {
|
||||
//video.optional = [];
|
||||
//}
|
||||
|
||||
|
||||
if (obj.options.useCamera !== "any") {
|
||||
//video.optional.push({sourceId: obj.options.useCamera});
|
||||
video.deviceId = obj.options.useCamera;
|
||||
}
|
||||
|
||||
if (bestFrameRate) {
|
||||
//video.optional.push({minFrameRate: bestFrameRate});
|
||||
//video.optional.push({maxFrameRate: bestFrameRate});
|
||||
video.frameRate = {ideal: bestFrameRate, min: minFrameRate, max: 30};
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log("Camera Disabled");
|
||||
video = false;
|
||||
useVideo = false;
|
||||
}
|
||||
}
|
||||
|
||||
return {audio: audio, video: video, useVideo: useVideo};
|
||||
|
@ -597,14 +587,10 @@
|
|||
self.localStream = stream;
|
||||
|
||||
if (screen) {
|
||||
if (moz) {
|
||||
self.constraints.OfferToReceiveVideo = false;
|
||||
} else {
|
||||
self.constraints.mandatory.OfferToReceiveVideo = false;
|
||||
}
|
||||
self.constraints.offerToReceiveVideo = false;
|
||||
}
|
||||
|
||||
self.peer = RTCPeerConnection({
|
||||
self.peer = FSRTCPeerConnection({
|
||||
type: self.type,
|
||||
attachStream: self.localStream,
|
||||
onICE: function(candidate) {
|
||||
|
@ -671,57 +657,23 @@
|
|||
// 2013, @muazkh - github.com/muaz-khan
|
||||
// MIT License - https://www.webrtc-experiment.com/licence/
|
||||
// Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RTCPeerConnection
|
||||
window.moz = !!navigator.mozGetUserMedia;
|
||||
|
||||
function RTCPeerConnection(options) {
|
||||
|
||||
function FSRTCPeerConnection(options) {
|
||||
var gathering = false, done = false;
|
||||
|
||||
var w = window,
|
||||
PeerConnection = w.mozRTCPeerConnection || w.webkitRTCPeerConnection,
|
||||
SessionDescription = w.mozRTCSessionDescription || w.RTCSessionDescription,
|
||||
IceCandidate = w.mozRTCIceCandidate || w.RTCIceCandidate;
|
||||
|
||||
var STUN = {
|
||||
url: !moz ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121'
|
||||
};
|
||||
|
||||
var iceServers = null;
|
||||
var config = {};
|
||||
var default_ice = {
|
||||
urls: ['stun:stun.l.google.com:19302']
|
||||
};
|
||||
|
||||
if (options.iceServers) {
|
||||
var tmp = options.iceServers;
|
||||
|
||||
if (typeof(tmp) === "boolean") {
|
||||
tmp = null;
|
||||
}
|
||||
|
||||
if (tmp && !(typeof(tmp) == "object" && tmp.constructor === Array)) {
|
||||
console.warn("iceServers must be an array, reverting to default ice servers");
|
||||
tmp = null;
|
||||
}
|
||||
|
||||
iceServers = {
|
||||
iceServers: tmp || [STUN]
|
||||
};
|
||||
|
||||
if (!moz && !tmp) {
|
||||
iceServers.iceServers = [STUN];
|
||||
}
|
||||
if (typeof(options.iceServers) === "boolean") {
|
||||
config.iceServers = [default_ice];
|
||||
} else {
|
||||
config.iceServers = options.iceServers;
|
||||
}
|
||||
}
|
||||
|
||||
var optional = {
|
||||
optional: []
|
||||
};
|
||||
|
||||
if (!moz) {
|
||||
optional.optional = [{
|
||||
DtlsSrtpKeyAgreement: true
|
||||
},
|
||||
{
|
||||
RtpDataChannels: options.onChannelMessage ? true : false
|
||||
}];
|
||||
}
|
||||
|
||||
var peer = new PeerConnection(iceServers, optional);
|
||||
var peer = new window.RTCPeerConnection(config);
|
||||
|
||||
openOffererChannel();
|
||||
var x = 0;
|
||||
|
@ -736,34 +688,10 @@
|
|||
}
|
||||
|
||||
if (options.type == "offer") {
|
||||
if ((!moz || (!options.sentICESDP && peer.localDescription.sdp.match(/a=candidate/)) && !x && options.onICESDP)) {
|
||||
options.onICESDP(peer.localDescription);
|
||||
//x = 1;
|
||||
/*
|
||||
x = 1;
|
||||
peer.createOffer(function(sessionDescription) {
|
||||
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||
peer.setLocalDescription(sessionDescription);
|
||||
if (options.onICESDP) {
|
||||
options.onICESDP(sessionDescription);
|
||||
}
|
||||
}, onSdpError, constraints);
|
||||
*/
|
||||
}
|
||||
options.onICESDP(peer.localDescription);
|
||||
} else {
|
||||
if (!x && options.onICESDP) {
|
||||
options.onICESDP(peer.localDescription);
|
||||
//x = 1;
|
||||
/*
|
||||
x = 1;
|
||||
peer.createAnswer(function(sessionDescription) {
|
||||
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||
peer.setLocalDescription(sessionDescription);
|
||||
if (options.onICESDP) {
|
||||
options.onICESDP(sessionDescription);
|
||||
}
|
||||
}, onSdpError, constraints);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -821,10 +749,10 @@
|
|||
//console.debug('on:add:stream', remoteMediaStream);
|
||||
};
|
||||
|
||||
var constraints = options.constraints || {
|
||||
offerToReceiveAudio: true,
|
||||
offerToReceiveVideo: true
|
||||
};
|
||||
//var constraints = options.constraints || {
|
||||
// offerToReceiveAudio: true,
|
||||
//offerToReceiveVideo: true
|
||||
//};
|
||||
|
||||
// onOfferSDP(RTCSessionDescription)
|
||||
function createOffer() {
|
||||
|
@ -834,13 +762,8 @@
|
|||
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||
peer.setLocalDescription(sessionDescription);
|
||||
options.onOfferSDP(sessionDescription);
|
||||
/* old mozilla behaviour the SDP was already great right away */
|
||||
if (moz && options.onICESDP && sessionDescription.sdp.match(/a=candidate/)) {
|
||||
options.onICESDP(sessionDescription);
|
||||
options.sentICESDP = 1;
|
||||
}
|
||||
},
|
||||
onSdpError, constraints);
|
||||
onSdpError, options.constraints);
|
||||
}
|
||||
|
||||
// onAnswerSDP(RTCSessionDescription)
|
||||
|
@ -848,7 +771,7 @@
|
|||
if (options.type != "answer") return;
|
||||
|
||||
//options.offerSDP.sdp = addStereo(options.offerSDP.sdp);
|
||||
peer.setRemoteDescription(new SessionDescription(options.offerSDP), onSdpSuccess, onSdpError);
|
||||
peer.setRemoteDescription(new window.RTCSessionDescription(options.offerSDP), onSdpSuccess, onSdpError);
|
||||
peer.createAnswer(function(sessionDescription) {
|
||||
sessionDescription.sdp = serializeSdp(sessionDescription.sdp);
|
||||
peer.setLocalDescription(sessionDescription);
|
||||
|
@ -856,11 +779,11 @@
|
|||
options.onAnswerSDP(sessionDescription);
|
||||
}
|
||||
},
|
||||
onSdpError, constraints);
|
||||
onSdpError);
|
||||
}
|
||||
|
||||
// if Mozilla Firefox & DataChannel; offer/answer will be created later
|
||||
if ((options.onChannelMessage && !moz) || !options.onChannelMessage) {
|
||||
|
||||
if ((options.onChannelMessage) || !options.onChannelMessage) {
|
||||
createOffer();
|
||||
createAnswer();
|
||||
}
|
||||
|
@ -899,9 +822,6 @@
|
|||
}
|
||||
|
||||
function serializeSdp(sdp) {
|
||||
//if (!moz) sdp = setBandwidth(sdp);
|
||||
//sdp = getInteropSDP(sdp);
|
||||
//console.debug(sdp);
|
||||
return sdp;
|
||||
}
|
||||
|
||||
|
@ -909,29 +829,18 @@
|
|||
var channel;
|
||||
|
||||
function openOffererChannel() {
|
||||
if (!options.onChannelMessage || (moz && !options.onOfferSDP)) return;
|
||||
if (!options.onChannelMessage) return;
|
||||
|
||||
_openOffererChannel();
|
||||
|
||||
if (!moz) return;
|
||||
navigator.mozGetUserMedia({
|
||||
audio: true,
|
||||
fake: true
|
||||
},
|
||||
function(stream) {
|
||||
peer.addStream(stream);
|
||||
createOffer();
|
||||
},
|
||||
useless);
|
||||
return;
|
||||
}
|
||||
|
||||
function _openOffererChannel() {
|
||||
channel = peer.createDataChannel(options.channel || 'RTCDataChannel', moz ? {} : {
|
||||
channel = peer.createDataChannel(options.channel || 'RTCDataChannel', {
|
||||
reliable: false
|
||||
});
|
||||
|
||||
if (moz) channel.binaryType = 'blob';
|
||||
|
||||
setChannelEvents();
|
||||
}
|
||||
|
||||
|
@ -955,8 +864,6 @@
|
|||
};
|
||||
}
|
||||
|
||||
if (options.onAnswerSDP && moz && options.onChannelMessage) openAnswererChannel();
|
||||
|
||||
function openAnswererChannel() {
|
||||
peer.ondatachannel = function(event) {
|
||||
channel = event.channel;
|
||||
|
@ -964,16 +871,7 @@
|
|||
setChannelEvents();
|
||||
};
|
||||
|
||||
if (!moz) return;
|
||||
navigator.mozGetUserMedia({
|
||||
audio: true,
|
||||
fake: true
|
||||
},
|
||||
function(stream) {
|
||||
peer.addStream(stream);
|
||||
createAnswer();
|
||||
},
|
||||
useless);
|
||||
return;
|
||||
}
|
||||
|
||||
// fake:true is also available on chrome under a flag!
|
||||
|
@ -993,10 +891,10 @@
|
|||
return {
|
||||
addAnswerSDP: function(sdp, cbSuccess, cbError) {
|
||||
|
||||
peer.setRemoteDescription(new SessionDescription(sdp), cbSuccess ? cbSuccess : onSdpSuccess, cbError ? cbError : onSdpError);
|
||||
peer.setRemoteDescription(new window.RTCSessionDescription(sdp), cbSuccess ? cbSuccess : onSdpSuccess, cbError ? cbError : onSdpError);
|
||||
},
|
||||
addICE: function(candidate) {
|
||||
peer.addIceCandidate(new IceCandidate({
|
||||
peer.addIceCandidate(new window.RTCIceCandidate({
|
||||
sdpMLineIndex: candidate.sdpMLineIndex,
|
||||
candidate: candidate.candidate
|
||||
}));
|
||||
|
@ -1026,14 +924,14 @@
|
|||
|
||||
// getUserMedia
|
||||
var video_constraints = {
|
||||
mandatory: {},
|
||||
optional: []
|
||||
//mandatory: {},
|
||||
//optional: []
|
||||
};
|
||||
|
||||
function getUserMedia(options) {
|
||||
var n = navigator,
|
||||
media;
|
||||
n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia;
|
||||
n.getMedia = n.getUserMedia;
|
||||
n.getMedia(options.constraints || {
|
||||
audio: true,
|
||||
video: video_constraints
|
||||
|
@ -1044,15 +942,8 @@
|
|||
});
|
||||
|
||||
function streaming(stream) {
|
||||
//var video = options.video;
|
||||
//var localVideo = options.localVideo;
|
||||
//if (video) {
|
||||
// video[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream);
|
||||
//video.play();
|
||||
//}
|
||||
|
||||
if (options.localVideo) {
|
||||
options.localVideo[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream);
|
||||
options.localVideo['src'] = window.URL.createObjectURL(stream);
|
||||
options.localVideo.style.display = 'block';
|
||||
}
|
||||
|
||||
|
@ -1108,23 +999,26 @@
|
|||
}
|
||||
|
||||
var video = {
|
||||
mandatory: {},
|
||||
optional: []
|
||||
//mandatory: {},
|
||||
//optional: []
|
||||
}
|
||||
|
||||
//FIXME
|
||||
if (cam) {
|
||||
video.optional = [{sourceId: cam}];
|
||||
//video.optional = [{sourceId: cam}];
|
||||
video.deviceId = {exact: cam};
|
||||
}
|
||||
|
||||
w = resList[resI][0];
|
||||
h = resList[resI][1];
|
||||
resI++;
|
||||
|
||||
video.mandatory = {
|
||||
"minWidth": w,
|
||||
"minHeight": h,
|
||||
"maxWidth": w,
|
||||
"maxHeight": h
|
||||
video = {
|
||||
width: w,
|
||||
height: h
|
||||
//"minWidth": w,
|
||||
//"minHeight": h,
|
||||
//"maxWidth": w,
|
||||
//"maxHeight": h
|
||||
};
|
||||
|
||||
getUserMedia({
|
||||
|
|
|
@ -2062,12 +2062,18 @@
|
|||
obj.dialogParams = {};
|
||||
|
||||
for (var i in dialog.params) {
|
||||
if (i == "sdp" && method != "verto.invite" && method != "verto.attach") {
|
||||
if (i == "sdp" && method != "verto.invite" && method != "verto.attach") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((obj.noDialogParams && i != "callID")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
obj.dialogParams[i] = dialog.params[i];
|
||||
obj.dialogParams[i] = dialog.params[i];
|
||||
}
|
||||
|
||||
delete obj.noDialogParams;
|
||||
|
||||
dialog.verto.rpcClient.call(method, obj,
|
||||
|
||||
|
@ -2371,6 +2377,26 @@
|
|||
}
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.rtt = function(obj) {
|
||||
var dialog = this;
|
||||
var pobj = {};
|
||||
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pobj.code = obj.code;
|
||||
pobj.chars = obj.chars;
|
||||
|
||||
|
||||
if (pobj.chars || pobj.code) {
|
||||
dialog.sendMethod("verto.info", {
|
||||
txt: obj,
|
||||
noDialogParams: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.transfer = function(dest, params) {
|
||||
var dialog = this;
|
||||
if (dest) {
|
||||
|
@ -2517,7 +2543,8 @@
|
|||
$.verto.dialog.prototype.handleInfo = function(params) {
|
||||
var dialog = this;
|
||||
|
||||
dialog.sendMessage($.verto.enum.message.info, params.msg);
|
||||
dialog.sendMessage($.verto.enum.message.info, params);
|
||||
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.handleDisplay = function(params) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -108,6 +108,7 @@
|
|||
<script type="text/javascript" src="../js/src/jquery.jsonrpcclient.js"></script>
|
||||
<script type="text/javascript" src="../js/src/jquery.FSRTC.js"></script>
|
||||
<script type="text/javascript" src="../js/src/jquery.verto.js"></script>
|
||||
<script type="text/javascript" src="../js/src/vendor/adapter-latest.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/3rd-party/getScreenId.js"></script>
|
||||
<script type="text/javascript" src="js/3rd-party/md5.min.js"></script>
|
||||
|
|
|
@ -150,5 +150,6 @@
|
|||
"CHAT_GAIN_PLUS": "Gain +",
|
||||
"LANGUAGE": "Language:",
|
||||
"BROWSER_LANGUAGE": "Browser Language",
|
||||
"FACTORY_RESET_SETTINGS": "Factory Reset Settings"
|
||||
"FACTORY_RESET_SETTINGS": "Factory Reset Settings",
|
||||
"AUTOGAIN_CONTROL": "Auto Gain Control"
|
||||
}
|
||||
|
|
|
@ -148,5 +148,6 @@
|
|||
"CHAT_VOL_PLUS": "Vol +",
|
||||
"CHAT_GAIN_MINUS": "Ganho -",
|
||||
"CHAT_GAIN_PLUS": "Ganho +",
|
||||
"FACTORY_RESET_SETTINGS": "Redefinir configurações"
|
||||
"FACTORY_RESET_SETTINGS": "Redefinir configurações",
|
||||
"AUTOGAIN_CONTROL": "Controle de Ganho Automático (AGC)"
|
||||
}
|
||||
|
|
|
@ -188,7 +188,8 @@
|
|||
<div class="chat-message-input">
|
||||
<form ng-submit="send()" >
|
||||
<div class="chat-message-input-group">
|
||||
<textarea ng-model="message" ng-keydown="($event.keyCode == 13 && $event.shiftKey !== true) && send($event)" required="required" class="form-control input-sm" placeholder="{{ 'CHAT_TYPE_MESSAGE' | translate }}"></textarea>
|
||||
<textarea ng-model="message" ng-keydown="($event.keyCode == 13 && $event.shiftKey !== true) && send($event)" required="required" class="form-control input-sm" placeholder="{{ 'CHAT_TYPE_MESSAGE' | translate }}"
|
||||
ng-focus="disableOnKeydownDtmf()" ng-blur="enableOnKeydownDtmf()"></textarea>
|
||||
<button class="btn btn-success btn-sm" type="submit">
|
||||
{{ 'CHAT_SEND_MESSAGE' | translate }}
|
||||
<span class="mdi-navigation-arrow-forward chat-message-input-group-icon-button"></span>
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
<div class="panel panel-default shadow-z-2" ng-class="{'shadow-z-2': !call_history}">
|
||||
<form name="form">
|
||||
<div class="input-group dialpad-display">
|
||||
<input name="dialpadnumber" type="text" class="form-control text-center" placeholder="" ng-model="dialpadNumber" />
|
||||
<input name="dtmfHistory" type="text" class="form-control text-center" placeholder="" ng-model="dtmfHistory.value" />
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="dialpad-numbers">
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(1)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(1)">
|
||||
<h2 class="dialpad-number">1</h2>
|
||||
<span class="dialpad-alpha">./@</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(2)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(2)">
|
||||
<h2 class="dialpad-number">2</h2>
|
||||
<span class="dialpad-alpha">ABC</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(3)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(3)">
|
||||
<h2 class="dialpad-number">3</h2>
|
||||
<span class="dialpad-alpha">DEF</span>
|
||||
</a>
|
||||
|
@ -27,19 +27,19 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(4)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(4)">
|
||||
<h2 class="dialpad-number">4</h2>
|
||||
<span class="dialpad-alpha">GHI</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(5)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(5)">
|
||||
<h2 class="dialpad-number">5</h2>
|
||||
<span class="dialpad-alpha">JKL</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(6)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(6)">
|
||||
<h2 class="dialpad-number">6</h2>
|
||||
<span class="dialpad-alpha">MNO</span>
|
||||
</a>
|
||||
|
@ -47,19 +47,19 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(7)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(7)">
|
||||
<h2 class="dialpad-number">7</h2>
|
||||
<span class="dialpad-alpha">PQRS</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(8)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(8)">
|
||||
<h2 class="dialpad-number">8</h2>
|
||||
<span class="dialpad-alpha">TUV</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(9)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(9)">
|
||||
<h2 class="dialpad-number">9</h2>
|
||||
<span class="dialpad-alpha">WXYZ</span>
|
||||
</a>
|
||||
|
@ -67,19 +67,19 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf('*')">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget('*')">
|
||||
<h2 class="dialpad-number dialpad-star">*</h2>
|
||||
<span class="dialpad-alpha"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf(0)">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget(0)">
|
||||
<h2 class="dialpad-number">0</h2>
|
||||
<span class="dialpad-alpha">+</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-4 col-xs-4">
|
||||
<a class="btn btn-block" href="" ng-click="dtmf('#')">
|
||||
<a class="btn btn-block" href="" ng-click="dtmfWidget('#')">
|
||||
<h2 class="dialpad-number dialpad-pound">#</h2>
|
||||
<span class="dialpad-alpha"></span>
|
||||
</a>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="panel-body">
|
||||
<div class="preview-wrapper">
|
||||
<video id="videopreview" muted autoplay style="width: 100%;"></video>
|
||||
<div id="mic-meter">
|
||||
<div id="mic-meter" ng-if="audioContext">
|
||||
<div class="volumes">
|
||||
<div class="volume-segment"></div>
|
||||
<div class="volume-segment"></div>
|
||||
|
|
|
@ -107,6 +107,12 @@
|
|||
<span ng-bind="'HIGHPASS_FILTER' | translate"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="googAutoGainControl" value="mydata.googAutoGainControl" ng-model="mydata.googAutoGainControl">
|
||||
<span ng-bind="'AUTOGAIN_CONTROL' | translate"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -99,6 +99,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 col-xs-6 text-right">
|
||||
<button ng-if="!verto.data.conf" tooltips="" tooltip-title="Hold" tooltip-side="bottom" tooltip-lazy="false" class="btn btn-material-900" ng-click="hold()">
|
||||
<i class="big-icon" ng-class="{'mdi-av-pause':!storage.data.onHold, 'mdi-av-play-arrow': storage.data.onHold}"></i>
|
||||
</button>
|
||||
<button class="btn btn-danger" ng-click="hangup()" translate>
|
||||
<i class="mdi-communication-call-end"></i>
|
||||
{{ watcher ? 'BUTTON_CLOSE' : 'BUTTON_END_CALL' }}
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
'status': 'success',
|
||||
'message': $translate.instant('BROWSER_COMPATIBILITY')
|
||||
};
|
||||
navigator.getUserMedia = navigator.getUserMedia ||
|
||||
navigator.webkitGetUserMedia ||
|
||||
navigator.mozGetUserMedia;
|
||||
|
||||
if (!navigator.getUserMedia) {
|
||||
if (!navigator.mediaDevices.getUserMedia) {
|
||||
result['status'] = 'error';
|
||||
result['message'] = $translate.instant('BROWSER_WITHOUT_WEBRTC');
|
||||
reject(result);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
mutedMic: false,
|
||||
preview: true,
|
||||
selectedVideo: null,
|
||||
selectedVideoName: null,
|
||||
selectedAudio: null,
|
||||
selectedShare: null,
|
||||
selectedSpeaker: null,
|
||||
|
@ -37,6 +38,7 @@
|
|||
googNoiseSuppression: true,
|
||||
googHighpassFilter: true,
|
||||
googEchoCancellation: true,
|
||||
googAutoGainControl: true,
|
||||
autoBand: true,
|
||||
testSpeedJoin: true,
|
||||
bestFrameRate: "15",
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('DialPadController', ['$rootScope', '$scope',
|
||||
'$http', '$location', 'toastr', 'verto', 'storage', 'CallHistory', 'eventQueue',
|
||||
function($rootScope, $scope, $http, $location, toastr, verto, storage, CallHistory, eventQueue) {
|
||||
'$http', '$location', 'toastr', 'verto', 'storage', 'CallHistory', 'eventQueue', '$timeout',
|
||||
function($rootScope, $scope, $http, $location, toastr, verto, storage, CallHistory, eventQueue, $timeout) {
|
||||
console.debug('Executing DialPadController.');
|
||||
|
||||
eventQueue.process();
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
angular
|
||||
.module('vertoControllers')
|
||||
.controller('MainController',
|
||||
function($scope, $rootScope, $location, $modal, $timeout, $q, verto, storage, CallHistory, toastr, Fullscreen, prompt, eventQueue, $translate) {
|
||||
function($scope, $rootScope, $location, $modal, $timeout, $q, verto, storage, CallHistory, toastr, Fullscreen, prompt, eventQueue, $translate, $window) {
|
||||
|
||||
console.debug('Executing MainController.');
|
||||
$rootScope.dtmfHistory = { value: '' };
|
||||
$rootScope.onKeydownDtmfEnabled = true;
|
||||
|
||||
if (storage.data.language && storage.data.language !== 'browser') {
|
||||
$translate.use(storage.data.language);
|
||||
|
@ -239,7 +241,8 @@
|
|||
* @param {String} number - New touched number.
|
||||
*/
|
||||
$rootScope.dtmf = function(number) {
|
||||
$rootScope.dialpadNumber = $scope.dialpadNumber + number;
|
||||
console.log('dtmf', number);
|
||||
$rootScope.dialpadNumber = $rootScope.dialpadNumber + number;
|
||||
if (verto.data.call) {
|
||||
verto.dtmf(number);
|
||||
}
|
||||
|
@ -555,6 +558,38 @@
|
|||
}
|
||||
}
|
||||
|
||||
$rootScope.dtmfWidget = function(number) {
|
||||
$rootScope.dtmfHistory.value = $rootScope.dtmfHistory.value + number;
|
||||
if (verto.data.call) {
|
||||
verto.dtmf(number);
|
||||
}
|
||||
}
|
||||
|
||||
$rootScope.disableOnKeydownDtmf = function() {
|
||||
$rootScope.onKeydownDtmfEnabled = false;
|
||||
};
|
||||
|
||||
$rootScope.enableOnKeydownDtmf = function() {
|
||||
$rootScope.onKeydownDtmfEnabled = true;
|
||||
};
|
||||
|
||||
$rootScope.$on("$routeChangeStart", function(event, next, current) {
|
||||
if (next.$$route.originalPath === '/incall') {
|
||||
$rootScope.dtmfHistory.value = '';
|
||||
angular.element($window).bind('keydown', onKeydownDtmfHistory);
|
||||
} else {
|
||||
angular.element($window).unbind('keydown', onKeydownDtmfHistory);
|
||||
}
|
||||
});
|
||||
|
||||
function onKeydownDtmfHistory(event) {
|
||||
var caracter = event.key;
|
||||
if ($rootScope.onKeydownDtmfEnabled && caracter.match(/^(\*|\#|[0-9a-dA-D])$/g)) {
|
||||
$rootScope.dtmfWidget(caracter);
|
||||
$scope.$applyAsync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
$scope.storage = storage;
|
||||
console.debug('Executing PreviewController.');
|
||||
var localVideo = document.getElementById('videopreview');
|
||||
var volumes = document.querySelector('#mic-meter .volumes').children;
|
||||
var volumes = document.querySelector('#mic-meter .volumes');
|
||||
if (volumes) {
|
||||
volumes = volumes.children;
|
||||
}
|
||||
|
||||
$scope.localVideo = function() {
|
||||
var constraints = {
|
||||
|
@ -31,10 +34,13 @@
|
|||
|
||||
});
|
||||
};
|
||||
var audioContext = null;
|
||||
if (typeof AudioContext !== "undefined") {
|
||||
audioContext = new AudioContext();
|
||||
}
|
||||
|
||||
var audioContext = new AudioContext();
|
||||
var mediaStreamSource = null;
|
||||
var meter;
|
||||
var meter = null;
|
||||
var streamObj = {};
|
||||
|
||||
function stopMedia(stream) {
|
||||
|
@ -55,13 +61,12 @@
|
|||
}
|
||||
|
||||
streamObj = stream;
|
||||
localVideo.src = window.URL.createObjectURL(stream);
|
||||
|
||||
mediaStreamSource = audioContext.createMediaStreamSource(stream);
|
||||
meter = createAudioMeter(audioContext);
|
||||
mediaStreamSource.connect(meter);
|
||||
|
||||
renderMic();
|
||||
FSRTCattachMediaStream(localVideo, stream);
|
||||
if (audioContext) {
|
||||
mediaStreamSource = audioContext.createMediaStreamSource(stream);
|
||||
meter = createAudioMeter(audioContext);
|
||||
mediaStreamSource.connect(meter);
|
||||
};
|
||||
}
|
||||
|
||||
function renderMic() {
|
||||
|
@ -109,8 +114,10 @@
|
|||
|
||||
$scope.endPreview = function() {
|
||||
localVideo.src = null;
|
||||
meter.shutdown();
|
||||
meter.onaudioprocess = null;
|
||||
if (audioContext) {
|
||||
meter.shutdown();
|
||||
meter.onaudioprocess = null;
|
||||
};
|
||||
stopMedia(streamObj);
|
||||
$location.path('/dialpad');
|
||||
storage.data.preview = false;
|
||||
|
|
|
@ -33,6 +33,15 @@
|
|||
});
|
||||
|
||||
$scope.ok = function() {
|
||||
console.log('Camera Selected is', $scope.mydata.selectedVideo, $scope.verto.data.videoDevices);
|
||||
|
||||
angular.forEach(verto.data.videoDevices, function(video) {
|
||||
console.log('checking video ', video);
|
||||
if (video.id == $scope.mydata.selectedVideo) {
|
||||
$scope.mydata.selectedVideoName = video.label;
|
||||
console.log('Setting selectedVideoName to ', video.label);
|
||||
}
|
||||
})
|
||||
if ($scope.mydata.selectedSpeaker != storage.data.selectedSpeaker) {
|
||||
$rootScope.$emit('changedSpeaker', $scope.mydata.selectedSpeaker);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
$rootScope.$on('progress.complete', function(ev, current_progress) {
|
||||
$scope.message = 'Complete';
|
||||
if(verto.data.connected) {
|
||||
if (storage.data.preview) {
|
||||
if (0 && storage.data.preview) {
|
||||
$location.path('/preview');
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -13,17 +13,35 @@
|
|||
.module('vertoDirectives')
|
||||
.directive('videoTag',
|
||||
function() {
|
||||
|
||||
function link(scope, element, attrs) {
|
||||
// Moving the video tag to the new place inside the incall page.
|
||||
console.log('Moving the video to element.');
|
||||
jQuery('video').removeClass('hide').appendTo(element);
|
||||
jQuery('video').css('display', 'block');
|
||||
var videoElem = jQuery('#webcam');
|
||||
|
||||
var newParent = document.getElementsByClassName('video-tag-wrapper');
|
||||
newParent[0].appendChild(document.getElementById('webcam'));
|
||||
|
||||
$("#webcam").resize(function() {
|
||||
updateVideoSize();
|
||||
});
|
||||
|
||||
$(window).resize(function() {
|
||||
updateVideoSize();
|
||||
});
|
||||
|
||||
updateVideoSize();
|
||||
|
||||
videoElem.removeClass('hide');
|
||||
videoElem.css('display', 'block');
|
||||
|
||||
scope.callActive("", {useVideo: true});
|
||||
|
||||
element.on('$destroy', function() {
|
||||
// Move the video back to the body.
|
||||
console.log('Moving the video back to body.');
|
||||
jQuery('video').addClass('hide').appendTo(jQuery('body'));
|
||||
videoElem.addClass('hide').appendTo(jQuery('body'));
|
||||
$(window).unbind('resize');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,35 @@ var framerate = [{
|
|||
label: '30 FPS'
|
||||
}, ];
|
||||
|
||||
var updateReq;
|
||||
|
||||
var updateVideoSize = function(ms) {
|
||||
if (!ms) ms = 500;
|
||||
|
||||
clearTimeout(updateReq);
|
||||
updateReq = setTimeout(function () {
|
||||
var videoElem = jQuery('#webcam');
|
||||
videoElem.width("");
|
||||
videoElem.height("");
|
||||
|
||||
var w = videoElem.width();
|
||||
var h = videoElem.height();
|
||||
var new_w, new_h;
|
||||
var aspect = 1920 / 1080;
|
||||
var videoContainer = jQuery('div.video-wrapper');
|
||||
if (w > h) {
|
||||
new_w = videoContainer.width();
|
||||
new_h = Math.round(videoContainer.width() / aspect);
|
||||
} else {
|
||||
new_h = videoContainer.height();
|
||||
new_w = Math.round(videoContainer.height() / aspect);
|
||||
}
|
||||
videoElem.width(new_w);
|
||||
videoElem.height(new_h);
|
||||
console.log('Setting video size to ' + new_w + '/' + new_h);
|
||||
}, ms);
|
||||
}
|
||||
|
||||
var vertoService = angular.module('vertoService', ['ngCookies']);
|
||||
|
||||
vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'storage',
|
||||
|
@ -317,7 +346,13 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
|
||||
// Verify if selected devices are valid
|
||||
var videoFlag = data.videoDevices.some(function(device) {
|
||||
return device.id == storage.data.selectedVideo;
|
||||
console.log('Evaluating device ', device);
|
||||
if (device.label == storage.data.selectedVideoName) {
|
||||
console.log('Matched video selection by name: ', device.label);
|
||||
storage.data.selectedVideo = device.id;
|
||||
return true;
|
||||
}
|
||||
return device.id == storage.data.selectedVideo && storage.data.selectedVideo !== "none";
|
||||
});
|
||||
|
||||
var shareFlag = data.shareDevices.some(function(device) {
|
||||
|
@ -332,7 +367,10 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
return device.id == storage.data.selectedSpeaker;
|
||||
});
|
||||
|
||||
if (!videoFlag) storage.data.selectedVideo = data.videoDevices[0].id;
|
||||
console.log('Storage Video: ', storage.data.selectedVideo);
|
||||
console.log('Video Flag: ', videoFlag)
|
||||
|
||||
if (!videoFlag) storage.data.selectedVideo = data.videoDevices[data.videoDevices.length - 1].id;
|
||||
if (!shareFlag) storage.data.selectedShare = data.shareDevices[0].id;
|
||||
if (!audioFlag) storage.data.selectedAudio = data.audioDevices[0].id;
|
||||
if (!speakerFlag && data.speakerDevices.length > 0) storage.data.selectedSpeaker = data.speakerDevices[0].id;
|
||||
|
@ -484,7 +522,6 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
|
||||
data.liveArray.onChange = function(obj, args) {
|
||||
// console.log('liveArray.onChange', obj, args);
|
||||
|
||||
switch (args.action) {
|
||||
case 'bootObj':
|
||||
$rootScope.$emit('members.boot', args.data);
|
||||
|
@ -560,6 +597,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
console.log("conference-liveArray-join");
|
||||
stopConference();
|
||||
startConference(v, dialog, params.pvtData);
|
||||
updateVideoSize();
|
||||
}
|
||||
break;
|
||||
case "conference-liveArray-part":
|
||||
|
@ -616,6 +654,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
console.debug('Talking to:', d.cidString());
|
||||
data.callState = 'active';
|
||||
callActive(d.lastState.name, d.params);
|
||||
updateVideoSize();
|
||||
break;
|
||||
case "hangup":
|
||||
console.debug('Call ended with cause: ' + d.cause);
|
||||
|
@ -672,9 +711,11 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
ringFile: "sounds/bell_ring2.wav",
|
||||
// TODO: Add options for this.
|
||||
audioParams: {
|
||||
googEchoCancellation: storage.data.googEchoCancellation || true,
|
||||
googNoiseSuppression: storage.data.googNoiseSuppression || true,
|
||||
googHighpassFilter: storage.data.googHighpassFilter || true
|
||||
googEchoCancellation: storage.data.googEchoCancellation === undefined ? true : storage.data.googEchoCancellation,
|
||||
googNoiseSuppression: storage.data.googNoiseSuppression === undefined ? true : storage.data.googNoiseSuppression,
|
||||
googHighpassFilter: storage.data.googHighpassFilter === undefined ? true : storage.data.googHighpassFilter,
|
||||
googAutoGainControl: storage.data.googAutoGainControl === undefined ? true : storage.data.googAutoGainControl,
|
||||
googAutoGainControl2: storage.data.googAutoGainControl === undefined ? true : storage.data.googAutoGainControl
|
||||
},
|
||||
sessid: sessid,
|
||||
iceServers: storage.data.useSTUN
|
||||
|
@ -783,9 +824,63 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
},
|
||||
|
||||
screenshare: function(destination, callback) {
|
||||
console.log('share screen video');
|
||||
|
||||
var that = this;
|
||||
|
||||
var that = this;
|
||||
|
||||
if (storage.data.selectedShare !== "screen") {
|
||||
|
||||
console.log('share screen from device ' + storage.data.selectedShare);
|
||||
|
||||
var call = data.instance.newCall({
|
||||
destination_number: destination + "-screen",
|
||||
caller_id_name: data.name + " (Screen)",
|
||||
caller_id_number: data.login + " (screen)",
|
||||
outgoingBandwidth: storage.data.outgoingBandwidth,
|
||||
incomingBandwidth: storage.data.incomingBandwidth,
|
||||
useCamera: storage.data.selectedShare,
|
||||
useVideo: true,
|
||||
screenShare: true,
|
||||
dedEnc: storage.data.useDedenc,
|
||||
mirrorInput: storage.data.mirrorInput,
|
||||
userVariables: {
|
||||
email : storage.data.email,
|
||||
avatar: "http://gravatar.com/avatar/" + md5(storage.data.email) + ".png?s=600"
|
||||
}
|
||||
});
|
||||
|
||||
// Override onStream callback in $.FSRTC instance
|
||||
call.rtc.options.callbacks.onStream = function(rtc, stream) {
|
||||
if(stream) {
|
||||
var StreamTrack = stream.getVideoTracks()[0];
|
||||
StreamTrack.addEventListener('ended', stopSharing);
|
||||
// (stream.getVideoTracks()[0]).onended = stopSharing;
|
||||
}
|
||||
|
||||
console.log("screenshare started");
|
||||
|
||||
function stopSharing() {
|
||||
if(that.data.shareCall) {
|
||||
that.screenshareHangup();
|
||||
console.log("screenshare ended");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
data.shareCall = call;
|
||||
|
||||
console.log('shareCall', data);
|
||||
|
||||
data.mutedMic = false;
|
||||
data.mutedVideo = false;
|
||||
|
||||
that.refreshDevices();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
console.log('share screen from plugin');
|
||||
|
||||
getScreenId(function(error, sourceId, screen_constraints) {
|
||||
|
||||
|
@ -801,7 +896,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
|||
outgoingBandwidth: storage.data.outgoingBandwidth,
|
||||
incomingBandwidth: storage.data.incomingBandwidth,
|
||||
videoParams: screen_constraints.video.mandatory,
|
||||
useVideo: storage.data.useVideo,
|
||||
useVideo: true,
|
||||
screenShare: true,
|
||||
dedEnc: storage.data.useDedenc,
|
||||
mirrorInput: storage.data.mirrorInput,
|
||||
|
|
|
@ -244,6 +244,14 @@ div#preload { display: none; }
|
|||
|
||||
|
||||
<video id="webcam" autoplay="autoplay" style="width:100%;height:100%;object-fit:inherit;"></video>
|
||||
<br><br>
|
||||
<table><tr><td>
|
||||
<div style="width:500px;max-height:300px;overflow-y:scroll;display:block;unicode-bidi:embed;font-family:tahoma;white-space:pre;size:14pt;text-align:left" id="rtt_in"></div>
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
<textarea style="width:500px;height:200px" id="rtt"></textarea>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!--<video id="local_webcam" autoplay="autoplay" style="width:100%;height:100%;object-fit:inherit;"></video>-->
|
||||
|
||||
</div><!-- rows -->
|
||||
|
|
|
@ -6,15 +6,13 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\
|
|||
function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i<elements.length;i++){if(index===3){newLine[index++]=payload;}
|
||||
if(elements[i]!==payload)newLine[index++]=elements[i];}
|
||||
return newLine.join(' ');}
|
||||
$.FSRTC=function(options){this.options=$.extend({useVideo:null,useStereo:false,userData:null,localVideo:null,screenShare:false,useCamera:"any",iceServers:false,videoParams:{},audioParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}},},options);this.audioEnabled=true;this.videoEnabled=true;this.mediaData={SDP:null,profile:{},candidateList:[]};if(moz){this.constraints={offerToReceiveAudio:this.options.useSpeak==="none"?false:true,offerToReceiveVideo:this.options.useVideo?true:false,};}else{this.constraints={optional:[{'DtlsSrtpKeyAgreement':'true'}],mandatory:{OfferToReceiveAudio:this.options.useSpeak==="none"?false:true,OfferToReceiveVideo:this.options.useVideo?true:false,}};}
|
||||
if(self.options.useVideo){self.options.useVideo.style.display='none';}
|
||||
setCompat();checkCompat();};$.FSRTC.validRes=[];$.FSRTC.prototype.useVideo=function(obj,local){var self=this;if(obj){self.options.useVideo=obj;self.options.localVideo=local;if(moz){self.constraints.offerToReceiveVideo=true;}else{self.constraints.mandatory.OfferToReceiveVideo=true;}}else{self.options.useVideo=null;self.options.localVideo=null;if(moz){self.constraints.offerToReceiveVideo=false;}else{self.constraints.mandatory.OfferToReceiveVideo=false;}}
|
||||
$.FSRTC=function(options){this.options=$.extend({useVideo:null,useStereo:false,userData:null,localVideo:null,screenShare:false,useCamera:"any",iceServers:false,videoParams:{},audioParams:{},callbacks:{onICEComplete:function(){},onICE:function(){},onOfferSDP:function(){}},},options);this.audioEnabled=true;this.videoEnabled=true;this.mediaData={SDP:null,profile:{},candidateList:[]};this.constraints={offerToReceiveAudio:this.options.useSpeak==="none"?false:true,offerToReceiveVideo:this.options.useVideo?true:false,};if(self.options.useVideo){self.options.useVideo.style.display='none';}
|
||||
setCompat();checkCompat();};$.FSRTC.validRes=[];$.FSRTC.prototype.useVideo=function(obj,local){var self=this;if(obj){self.options.useVideo=obj;self.options.localVideo=local;self.constraints.offerToReceiveVideo=true;}else{self.options.useVideo=null;self.options.localVideo=null;self.constraints.offerToReceiveVideo=false;}
|
||||
if(self.options.useVideo){self.options.useVideo.style.display='none';}};$.FSRTC.prototype.useStereo=function(on){var self=this;self.options.useStereo=on;};$.FSRTC.prototype.stereoHack=function(sdp){var self=this;if(!self.options.useStereo){return sdp;}
|
||||
var sdpLines=sdp.split('\r\n');var opusIndex=findLine(sdpLines,'a=rtpmap','opus/48000'),opusPayload;if(!opusIndex){return sdp;}else{opusPayload=getCodecPayloadType(sdpLines[opusIndex]);}
|
||||
var fmtpLineIndex=findLine(sdpLines,'a=fmtp:'+opusPayload.toString());if(fmtpLineIndex===null){sdpLines[opusIndex]=sdpLines[opusIndex]+'\r\na=fmtp:'+opusPayload.toString()+" stereo=1; sprop-stereo=1"}else{sdpLines[fmtpLineIndex]=sdpLines[fmtpLineIndex].concat('; stereo=1; sprop-stereo=1');}
|
||||
sdp=sdpLines.join('\r\n');return sdp;};function setCompat(){$.FSRTC.moz=!!navigator.mozGetUserMedia;if(!navigator.getUserMedia){navigator.getUserMedia=navigator.mozGetUserMedia||navigator.webkitGetUserMedia||navigator.msGetUserMedia;}}
|
||||
function checkCompat(){if(!navigator.getUserMedia){alert('This application cannot function in this browser.');return false;}
|
||||
return true;}
|
||||
sdp=sdpLines.join('\r\n');return sdp;};function setCompat(){}
|
||||
function checkCompat(){return true;}
|
||||
function onStreamError(self,e){console.log('There has been a problem retrieving the streams - did you allow access? Check Device Resolution',e);doCallback(self,"onError",e);}
|
||||
function onStreamSuccess(self,stream){console.log("Stream Success");doCallback(self,"onStream",stream);}
|
||||
function onICE(self,candidate){self.mediaData.candidate=candidate;self.mediaData.candidateList.push(self.mediaData.candidate);doCallback(self,"onICE");}
|
||||
|
@ -24,15 +22,15 @@ function onChannelError(self,e){console.error("Channel Error",e);doCallback(self
|
|||
function onICESDP(self,sdp){self.mediaData.SDP=self.stereoHack(sdp.sdp);console.log("ICE SDP");doCallback(self,"onICESDP");}
|
||||
function onAnswerSDP(self,sdp){self.answer.SDP=self.stereoHack(sdp.sdp);console.log("ICE ANSWER SDP");doCallback(self,"onAnswerSDP",self.answer.SDP);}
|
||||
function onMessage(self,msg){console.log("Message");doCallback(self,"onICESDP",msg);}
|
||||
FSRTCattachMediaStream=function(element,stream){if(element&&element.id&&attachMediaStream){attachMediaStream(element,stream);}else{if(typeof element.srcObject!=='undefined'){element.srcObject=stream;}else if(typeof element.src!=='undefined'){element.src=URL.createObjectURL(stream);}else{console.error('Error attaching stream to element.');}}}
|
||||
function onRemoteStream(self,stream){if(self.options.useVideo){self.options.useVideo.style.display='block';}
|
||||
var element=self.options.useAudio;console.log("REMOTE STREAM",stream,element);if(typeof element.srcObject!=='undefined'){element.srcObject=stream;}else if(typeof element.mozSrcObject!=='undefined'){element.mozSrcObject=stream;}else if(typeof element.src!=='undefined'){element.src=URL.createObjectURL(stream);}else{console.error('Error attaching stream to element.');}
|
||||
self.options.useAudio.play();self.remoteStream=stream;}
|
||||
var element=self.options.useAudio;console.log("REMOTE STREAM",stream,element);FSRTCattachMediaStream(element,stream);self.options.useAudio.play();self.remoteStream=stream;}
|
||||
function onOfferSDP(self,sdp){self.mediaData.SDP=self.stereoHack(sdp.sdp);console.log("Offer SDP");doCallback(self,"onOfferSDP");}
|
||||
$.FSRTC.prototype.answer=function(sdp,onSuccess,onError){this.peer.addAnswerSDP({type:"answer",sdp:sdp},onSuccess,onError);};$.FSRTC.prototype.stopPeer=function(){if(self.peer){console.log("stopping peer");self.peer.stop();}}
|
||||
$.FSRTC.prototype.stop=function(){var self=this;if(self.options.useVideo){self.options.useVideo.style.display='none';if(moz){self.options.useVideo['mozSrcObject']=null;}else{self.options.useVideo['src']='';}}
|
||||
$.FSRTC.prototype.stop=function(){var self=this;if(self.options.useVideo){self.options.useVideo.style.display='none';self.options.useVideo['src']='';}
|
||||
if(self.localStream){if(typeof self.localStream.stop=='function'){self.localStream.stop();}else{if(self.localStream.active){var tracks=self.localStream.getTracks();console.error(tracks);tracks.forEach(function(track,index){console.log(track);track.stop();})}}
|
||||
self.localStream=null;}
|
||||
if(self.options.localVideo){self.options.localVideo.style.display='none';if(moz){self.options.localVideo['mozSrcObject']=null;}else{self.options.localVideo['src']='';}}
|
||||
if(self.options.localVideo){self.options.localVideo.style.display='none';self.options.localVideo['src']='';}
|
||||
if(self.options.localVideoStream){if(typeof self.options.localVideoStream.stop=='function'){self.options.localVideoStream.stop();}else{if(self.options.localVideoStream.active){var tracks=self.options.localVideoStream.getTracks();console.error(tracks);tracks.forEach(function(track,index){console.log(track);track.stop();})}}}
|
||||
if(self.peer){console.log("stopping peer");self.peer.stop();}};$.FSRTC.prototype.getMute=function(){var self=this;return self.audioEnabled;}
|
||||
$.FSRTC.prototype.setMute=function(what){var self=this;var audioTracks=self.localStream.getAudioTracks();for(var i=0,len=audioTracks.length;i<len;i++){switch(what){case"on":audioTracks[i].enabled=true;break;case"off":audioTracks[i].enabled=false;break;case"toggle":audioTracks[i].enabled=!audioTracks[i].enabled;default:break;}
|
||||
|
@ -42,48 +40,44 @@ $.FSRTC.prototype.getVideoMute=function(){var self=this;return self.videoEnabled
|
|||
$.FSRTC.prototype.setVideoMute=function(what){var self=this;var videoTracks=self.localStream.getVideoTracks();for(var i=0,len=videoTracks.length;i<len;i++){switch(what){case"on":videoTracks[i].enabled=true;break;case"off":videoTracks[i].enabled=false;break;case"toggle":videoTracks[i].enabled=!videoTracks[i].enabled;default:break;}
|
||||
self.videoEnabled=videoTracks[i].enabled;}
|
||||
return!self.videoEnabled;}
|
||||
$.FSRTC.prototype.createAnswer=function(params){var self=this;self.type="answer";self.remoteSDP=params.sdp;console.debug("inbound sdp: ",params.sdp);function onSuccess(stream){self.localStream=stream;self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:function(stream){return onRemoteStream(self,stream);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,offerSDP:{type:"offer",sdp:self.remoteSDP}});onStreamSuccess(self);}
|
||||
$.FSRTC.prototype.createAnswer=function(params){var self=this;self.type="answer";self.remoteSDP=params.sdp;console.debug("inbound sdp: ",params.sdp);function onSuccess(stream){self.localStream=stream;self.peer=FSRTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:function(stream){return onRemoteStream(self,stream);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,offerSDP:{type:"offer",sdp:self.remoteSDP}});onStreamSuccess(self);}
|
||||
function onError(e){onStreamError(self,e);}
|
||||
var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(self.options.useVideo&&self.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:self.options.videoParams,optional:[]},},localVideo:self.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
|
||||
getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});};function getMediaParams(obj){var audio;if(obj.options.useMic&&obj.options.useMic==="none"){console.log("Microphone Disabled");audio=false;}else if(obj.options.videoParams&&obj.options.screenShare){console.error("SCREEN SHARE");audio=false;}else{audio={mandatory:{},optional:[]};if(obj.options.useMic!=="any"){audio.optional=[{sourceId:obj.options.useMic}]}
|
||||
if(obj.options.audioParams){for(var key in obj.options.audioParams){var con={};con[key]=obj.options.audioParams[key];audio.optional.push(con);}}}
|
||||
if(obj.options.useVideo&&obj.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:obj.options.videoParams,optional:[]},},localVideo:obj.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
|
||||
var video={};var bestFrameRate=obj.options.videoParams.vertoBestFrameRate;delete obj.options.videoParams.vertoBestFrameRate;video={mandatory:obj.options.videoParams,optional:[]}
|
||||
var useVideo=obj.options.useVideo;if(useVideo&&obj.options.useCamera&&obj.options.useCamera!=="none"){if(!video.optional){video.optional=[];}
|
||||
if(obj.options.useCamera!=="any"){video.optional.push({sourceId:obj.options.useCamera});}
|
||||
if(bestFrameRate){video.optional.push({minFrameRate:bestFrameRate});video.optional.push({maxFrameRate:bestFrameRate});}}else{console.log("Camera Disabled");video=false;useVideo=false;}
|
||||
var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(self.options.useVideo&&self.options.localVideo){getUserMedia({constraints:{audio:false,video:{},},localVideo:self.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
|
||||
getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});};function getMediaParams(obj){var audio;if(obj.options.useMic&&obj.options.useMic==="none"){console.log("Microphone Disabled");audio=false;}else if(obj.options.videoParams&&obj.options.screenShare){console.error("SCREEN SHARE",obj.options.videoParams);audio=false;}else{audio={advanced:[]};if(obj.options.useMic!=="any"){audio.deviceId={exact:obj.options.useMic};}
|
||||
if(obj.options.audioParams){for(var key in obj.options.audioParams){var con={};if(obj.options.audioParams[key]){con.exact=key;audio.advanced.push(con);}}}}
|
||||
if(obj.options.useVideo&&obj.options.localVideo){getUserMedia({constraints:{audio:false,video:obj.options.videoParams},localVideo:obj.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});}
|
||||
var video={};var bestFrameRate=obj.options.videoParams.vertoBestFrameRate;var minFrameRate=obj.options.videoParams.minFrameRate||15;delete obj.options.videoParams.vertoBestFrameRate;if(obj.options.screenShare){var opt=[];opt.push({sourceId:obj.options.useCamera});if(bestFrameRate){opt.push({minFrameRate:bestFrameRate});opt.push({maxFrameRate:bestFrameRate});}
|
||||
video={mandatory:obj.options.videoParams,optional:opt};}else{video={width:{min:obj.options.videoParams.minWidth,max:obj.options.videoParams.maxWidth},height:{min:obj.options.videoParams.minHeight,max:obj.options.videoParams.maxHeight}};var useVideo=obj.options.useVideo;if(useVideo&&obj.options.useCamera&&obj.options.useCamera!=="none"){if(obj.options.useCamera!=="any"){video.deviceId=obj.options.useCamera;}
|
||||
if(bestFrameRate){video.frameRate={ideal:bestFrameRate,min:minFrameRate,max:30};}}else{console.log("Camera Disabled");video=false;useVideo=false;}}
|
||||
return{audio:audio,video:video,useVideo:useVideo};}
|
||||
$.FSRTC.prototype.call=function(profile){checkCompat();var self=this;var screen=false;self.type="offer";if(self.options.videoParams&&self.options.screenShare){screen=true;}
|
||||
function onSuccess(stream){self.localStream=stream;if(screen){if(moz){self.constraints.OfferToReceiveVideo=false;}else{self.constraints.mandatory.OfferToReceiveVideo=false;}}
|
||||
self.peer=RTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:screen?function(stream){}:function(stream){return onRemoteStream(self,stream);},onOfferSDP:function(sdp){return onOfferSDP(self,sdp);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,});onStreamSuccess(self,stream);}
|
||||
function onSuccess(stream){self.localStream=stream;if(screen){self.constraints.offerToReceiveVideo=false;}
|
||||
self.peer=FSRTCPeerConnection({type:self.type,attachStream:self.localStream,onICE:function(candidate){return onICE(self,candidate);},onICEComplete:function(){return onICEComplete(self);},onRemoteStream:screen?function(stream){}:function(stream){return onRemoteStream(self,stream);},onOfferSDP:function(sdp){return onOfferSDP(self,sdp);},onICESDP:function(sdp){return onICESDP(self,sdp);},onChannelError:function(e){return onChannelError(self,e);},constraints:self.constraints,iceServers:self.options.iceServers,});onStreamSuccess(self,stream);}
|
||||
function onError(e){onStreamError(self,e);}
|
||||
var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(mediaParams.audio||mediaParams.video){getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});}else{onSuccess(null);}};window.moz=!!navigator.mozGetUserMedia;function RTCPeerConnection(options){var gathering=false,done=false;var w=window,PeerConnection=w.mozRTCPeerConnection||w.webkitRTCPeerConnection,SessionDescription=w.mozRTCSessionDescription||w.RTCSessionDescription,IceCandidate=w.mozRTCIceCandidate||w.RTCIceCandidate;var STUN={url:!moz?'stun:stun.l.google.com:19302':'stun:23.21.150.121'};var iceServers=null;if(options.iceServers){var tmp=options.iceServers;if(typeof(tmp)==="boolean"){tmp=null;}
|
||||
if(tmp&&!(typeof(tmp)=="object"&&tmp.constructor===Array)){console.warn("iceServers must be an array, reverting to default ice servers");tmp=null;}
|
||||
iceServers={iceServers:tmp||[STUN]};if(!moz&&!tmp){iceServers.iceServers=[STUN];}}
|
||||
var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];}
|
||||
var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;function ice_handler(){done=true;gathering=null;if(options.onICEComplete){options.onICEComplete();}
|
||||
if(options.type=="offer"){if((!moz||(!options.sentICESDP&&peer.localDescription.sdp.match(/a=candidate/))&&!x&&options.onICESDP)){options.onICESDP(peer.localDescription);}}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}
|
||||
var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(mediaParams.audio||mediaParams.video){getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});}else{onSuccess(null);}};function FSRTCPeerConnection(options){var gathering=false,done=false;var config={};var default_ice={urls:['stun:stun.l.google.com:19302']};if(options.iceServers){if(typeof(options.iceServers)==="boolean"){config.iceServers=[default_ice];}else{config.iceServers=options.iceServers;}}
|
||||
var peer=new window.RTCPeerConnection(config);openOffererChannel();var x=0;function ice_handler(){done=true;gathering=null;if(options.onICEComplete){options.onICEComplete();}
|
||||
if(options.type=="offer"){options.onICESDP(peer.localDescription);}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}
|
||||
peer.onicecandidate=function(event){if(done){return;}
|
||||
if(!gathering){gathering=setTimeout(ice_handler,1000);}
|
||||
if(event){if(event.candidate){options.onICE(event.candidate);}}else{done=true;if(gathering){clearTimeout(gathering);gathering=null;}
|
||||
ice_handler();}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i<streams.length;i++){peer.addStream(streams[i]);}}
|
||||
peer.onaddstream=function(event){var remoteMediaStream=event.stream;remoteMediaStream.onended=function(){if(options.onRemoteStreamEnded)options.onRemoteStreamEnded(remoteMediaStream);};if(options.onRemoteStream)options.onRemoteStream(remoteMediaStream);};var constraints=options.constraints||{offerToReceiveAudio:true,offerToReceiveVideo:true};function createOffer(){if(!options.onOfferSDP)return;peer.createOffer(function(sessionDescription){sessionDescription.sdp=serializeSdp(sessionDescription.sdp);peer.setLocalDescription(sessionDescription);options.onOfferSDP(sessionDescription);if(moz&&options.onICESDP&&sessionDescription.sdp.match(/a=candidate/)){options.onICESDP(sessionDescription);options.sentICESDP=1;}},onSdpError,constraints);}
|
||||
function createAnswer(){if(options.type!="answer")return;peer.setRemoteDescription(new SessionDescription(options.offerSDP),onSdpSuccess,onSdpError);peer.createAnswer(function(sessionDescription){sessionDescription.sdp=serializeSdp(sessionDescription.sdp);peer.setLocalDescription(sessionDescription);if(options.onAnswerSDP){options.onAnswerSDP(sessionDescription);}},onSdpError,constraints);}
|
||||
if((options.onChannelMessage&&!moz)||!options.onChannelMessage){createOffer();createAnswer();}
|
||||
peer.onaddstream=function(event){var remoteMediaStream=event.stream;remoteMediaStream.onended=function(){if(options.onRemoteStreamEnded)options.onRemoteStreamEnded(remoteMediaStream);};if(options.onRemoteStream)options.onRemoteStream(remoteMediaStream);};function createOffer(){if(!options.onOfferSDP)return;peer.createOffer(function(sessionDescription){sessionDescription.sdp=serializeSdp(sessionDescription.sdp);peer.setLocalDescription(sessionDescription);options.onOfferSDP(sessionDescription);},onSdpError,options.constraints);}
|
||||
function createAnswer(){if(options.type!="answer")return;peer.setRemoteDescription(new window.RTCSessionDescription(options.offerSDP),onSdpSuccess,onSdpError);peer.createAnswer(function(sessionDescription){sessionDescription.sdp=serializeSdp(sessionDescription.sdp);peer.setLocalDescription(sessionDescription);if(options.onAnswerSDP){options.onAnswerSDP(sessionDescription);}},onSdpError);}
|
||||
if((options.onChannelMessage)||!options.onChannelMessage){createOffer();createAnswer();}
|
||||
function setBandwidth(sdp){sdp=sdp.replace(/b=AS([^\r\n]+\r\n)/g,'');sdp=sdp.replace(/a=mid:data\r\n/g,'a=mid:data\r\nb=AS:1638400\r\n');return sdp;}
|
||||
function getInteropSDP(sdp){var chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''),extractedChars='';function getChars(){extractedChars+=chars[parseInt(Math.random()*40)]||'';if(extractedChars.length<40)getChars();return extractedChars;}
|
||||
if(options.onAnswerSDP)sdp=sdp.replace(/(a=crypto:0 AES_CM_128_HMAC_SHA1_32)(.*?)(\r\n)/g,'');var inline=getChars()+'\r\n'+(extractedChars='');sdp=sdp.indexOf('a=crypto')==-1?sdp.replace(/c=IN/g,'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:'+inline+'c=IN'):sdp;return sdp;}
|
||||
function serializeSdp(sdp){return sdp;}
|
||||
var channel;function openOffererChannel(){if(!options.onChannelMessage||(moz&&!options.onOfferSDP))return;_openOffererChannel();if(!moz)return;navigator.mozGetUserMedia({audio:true,fake:true},function(stream){peer.addStream(stream);createOffer();},useless);}
|
||||
function _openOffererChannel(){channel=peer.createDataChannel(options.channel||'RTCDataChannel',moz?{}:{reliable:false});if(moz)channel.binaryType='blob';setChannelEvents();}
|
||||
var channel;function openOffererChannel(){if(!options.onChannelMessage)return;_openOffererChannel();return;}
|
||||
function _openOffererChannel(){channel=peer.createDataChannel(options.channel||'RTCDataChannel',{reliable:false});setChannelEvents();}
|
||||
function setChannelEvents(){channel.onmessage=function(event){if(options.onChannelMessage)options.onChannelMessage(event);};channel.onopen=function(){if(options.onChannelOpened)options.onChannelOpened(channel);};channel.onclose=function(event){if(options.onChannelClosed)options.onChannelClosed(event);console.warn('WebRTC DataChannel closed',event);};channel.onerror=function(event){if(options.onChannelError)options.onChannelError(event);console.error('WebRTC DataChannel error',event);};}
|
||||
if(options.onAnswerSDP&&moz&&options.onChannelMessage)openAnswererChannel();function openAnswererChannel(){peer.ondatachannel=function(event){channel=event.channel;channel.binaryType='blob';setChannelEvents();};if(!moz)return;navigator.mozGetUserMedia({audio:true,fake:true},function(stream){peer.addStream(stream);createAnswer();},useless);}
|
||||
function openAnswererChannel(){peer.ondatachannel=function(event){channel=event.channel;channel.binaryType='blob';setChannelEvents();};return;}
|
||||
function useless(){log('Error in fake:true');}
|
||||
function onSdpSuccess(){}
|
||||
function onSdpError(e){if(options.onChannelError){options.onChannelError(e);}
|
||||
console.error('sdp error:',e);}
|
||||
return{addAnswerSDP:function(sdp,cbSuccess,cbError){peer.setRemoteDescription(new SessionDescription(sdp),cbSuccess?cbSuccess:onSdpSuccess,cbError?cbError:onSdpError);},addICE:function(candidate){peer.addIceCandidate(new IceCandidate({sdpMLineIndex:candidate.sdpMLineIndex,candidate:candidate.candidate}));},peer:peer,channel:channel,sendData:function(message){if(channel){channel.send(message);}},stop:function(){peer.close();if(options.attachStream){if(typeof options.attachStream.stop=='function'){options.attachStream.stop();}else{options.attachStream.active=false;}}}};}
|
||||
var video_constraints={mandatory:{},optional:[]};function getUserMedia(options){var n=navigator,media;n.getMedia=n.webkitGetUserMedia||n.mozGetUserMedia;n.getMedia(options.constraints||{audio:true,video:video_constraints},streaming,options.onerror||function(e){console.error(e);});function streaming(stream){if(options.localVideo){options.localVideo[moz?'mozSrcObject':'src']=moz?stream:window.webkitURL.createObjectURL(stream);options.localVideo.style.display='block';}
|
||||
return{addAnswerSDP:function(sdp,cbSuccess,cbError){peer.setRemoteDescription(new window.RTCSessionDescription(sdp),cbSuccess?cbSuccess:onSdpSuccess,cbError?cbError:onSdpError);},addICE:function(candidate){peer.addIceCandidate(new window.RTCIceCandidate({sdpMLineIndex:candidate.sdpMLineIndex,candidate:candidate.candidate}));},peer:peer,channel:channel,sendData:function(message){if(channel){channel.send(message);}},stop:function(){peer.close();if(options.attachStream){if(typeof options.attachStream.stop=='function'){options.attachStream.stop();}else{options.attachStream.active=false;}}}};}
|
||||
var video_constraints={};function getUserMedia(options){var n=navigator,media;n.getMedia=n.getUserMedia;n.getMedia(options.constraints||{audio:true,video:video_constraints},streaming,options.onerror||function(e){console.error(e);});function streaming(stream){if(options.localVideo){options.localVideo['src']=window.URL.createObjectURL(stream);options.localVideo.style.display='block';}
|
||||
if(options.onsuccess){options.onsuccess(stream);}
|
||||
media=stream;}
|
||||
return media;}
|
||||
|
@ -91,10 +85,10 @@ $.FSRTC.resSupported=function(w,h){for(var i in $.FSRTC.validRes){if($.FSRTC.val
|
|||
return false;}
|
||||
$.FSRTC.bestResSupported=function(){var w=0,h=0;for(var i in $.FSRTC.validRes){if($.FSRTC.validRes[i][0]>w&&$.FSRTC.validRes[i][1]>h){w=$.FSRTC.validRes[i][0];h=$.FSRTC.validRes[i][1];}}
|
||||
return[w,h];}
|
||||
var resList=[[320,180],[320,240],[640,360],[640,480],[1280,720],[1920,1080]];var resI=0;var ttl=0;var checkRes=function(cam,func){if(resI>=resList.length){var res={'validRes':$.FSRTC.validRes,'bestResSupported':$.FSRTC.bestResSupported()};localStorage.setItem("res_"+cam,$.toJSON(res));if(func)return func(res);return;}
|
||||
var video={mandatory:{},optional:[]}
|
||||
if(cam){video.optional=[{sourceId:cam}];}
|
||||
w=resList[resI][0];h=resList[resI][1];resI++;video.mandatory={"minWidth":w,"minHeight":h,"maxWidth":w,"maxHeight":h};getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info(w+"x"+h+" supported.");$.FSRTC.validRes.push([w,h]);checkRes(cam,func);},onerror:function(e){console.error(w+"x"+h+" not supported.");checkRes(cam,func);}});}
|
||||
var resList=[[160,120],[320,180],[320,240],[640,360],[640,480],[1280,720],[1920,1080]];var resI=0;var ttl=0;var checkRes=function(cam,func){if(resI>=resList.length){var res={'validRes':$.FSRTC.validRes,'bestResSupported':$.FSRTC.bestResSupported()};localStorage.setItem("res_"+cam,$.toJSON(res));if(func)return func(res);return;}
|
||||
var video={}
|
||||
if(cam){video.deviceId={exact:cam};}
|
||||
w=resList[resI][0];h=resList[resI][1];resI++;video={width:w,height:h};getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info(w+"x"+h+" supported.");$.FSRTC.validRes.push([w,h]);checkRes(cam,func);},onerror:function(e){console.error(w+"x"+h+" not supported.");checkRes(cam,func);}});}
|
||||
$.FSRTC.getValidRes=function(cam,func){var used=[];var cached=localStorage.getItem("res_"+cam);if(cached){var cache=$.parseJSON(cached);if(cache){$.FSRTC.validRes=cache.validRes;console.log("CACHED RES FOR CAM "+cam,cache);}else{console.error("INVALID CACHE");}
|
||||
return func?func(cache):null;}
|
||||
$.FSRTC.validRes=[];resI=0;checkRes(cam,func);}
|
||||
|
@ -254,9 +248,12 @@ if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="No
|
|||
if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";}
|
||||
RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;}
|
||||
RTCcallbacks.onICESDP=function(rtc){console.log("RECV "+rtc.type+" SDP",rtc.mediaData.SDP);if(dialog.state==$.verto.enum.state.requesting||dialog.state==$.verto.enum.state.answering||dialog.state==$.verto.enum.state.active){location.reload();return;}
|
||||
if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.screenShare?null:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;}
|
||||
if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){if(dialog.verto.options.permissionCallback&&typeof dialog.verto.options.permissionCallback.onGranted==='function'){dialog.verto.options.permissionCallback.onGranted();}
|
||||
console.log("stream started");};RTCcallbacks.onError=function(e){if(dialog.verto.options.permissionCallback&&typeof dialog.verto.options.permissionCallback.onDenied==='function'){dialog.verto.options.permissionCallback.onDenied();}
|
||||
console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.screenShare?null:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;}
|
||||
if((obj.noDialogParams&&i!="callID")){continue;}
|
||||
obj.dialogParams[i]=dialog.params[i];}
|
||||
dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;}
|
||||
delete obj.noDialogParams;dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;}
|
||||
return false;}
|
||||
function find_name(id){for(var i in $.verto.audioOutDevices){var source=$.verto.audioOutDevices[i];if(source.id===id){return(source.label);}}
|
||||
return id;}
|
||||
|
@ -280,7 +277,8 @@ if(success){}
|
|||
break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;}
|
||||
if(params.cause){dialog.cause=params.cause;}}
|
||||
if(dialog.state.val>=$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;}
|
||||
dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
|
||||
dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.rtt=function(obj){var dialog=this;var pobj={};if(!obj){return false;}
|
||||
pobj.code=obj.code;pobj.chars=obj.chars;if(pobj.chars||pobj.code){dialog.sendMethod("verto.info",{txt:obj,noDialogParams:true});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
|
||||
if(!msg.body){console.error("Missing Body");err++;}
|
||||
if(err){return false;}
|
||||
dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(!params){params={};}
|
||||
|
@ -289,7 +287,7 @@ dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_numbe
|
|||
if(params.useMic){dialog.useMic=params.useMic;}
|
||||
if(params.useSpeak){dialog.useSpeak=params.useSpeak;}}
|
||||
dialog.rtc.createAnswer(params);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;}
|
||||
if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;}
|
||||
if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;}
|
||||
if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;}
|
||||
dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;}
|
||||
dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1,hangup:1},requesting:{trying:1,hangup:1,active:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$.verto.unloadJobs=[];$(window).bind('beforeunload',function(){for(var f in $.verto.unloadJobs){$.verto.unloadJobs[f]();}
|
||||
|
@ -299,4 +297,218 @@ $.verto.videoDevices=vid;$.verto.audioInDevices=aud_in;console.info("Audio Devic
|
|||
navigator.mediaDevices.enumerateDevices().then(function(devices){devices.forEach(function(device){console.log(device);console.log(device.kind+": "+device.label+" id = "+device.deviceId);if(device.kind==="videoinput"){vid.push({id:device.deviceId,kind:"video",label:device.label});}else if(device.kind==="audioinput"){aud_in.push({id:device.deviceId,kind:"audio_in",label:device.label});}else if(device.kind==="audiooutput"){aud_out.push({id:device.deviceId,kind:"audio_out",label:device.label});}});$.verto.videoDevices=vid;$.verto.audioInDevices=aud_in;$.verto.audioOutDevices=aud_out;console.info("Audio IN Devices",$.verto.audioInDevices);console.info("Audio Out Devices",$.verto.audioOutDevices);console.info("Video Devices",$.verto.videoDevices);runtime(true);}).catch(function(err){console.log(" Device Enumeration ERROR: "+err.name+": "+err.message);runtime(false);});}};$.verto.refreshDevices=function(runtime){checkDevices(runtime);}
|
||||
$.verto.init=function(obj,runtime){if(!obj){obj={};}
|
||||
if(!obj.skipPermCheck&&!obj.skipDeviceCheck){$.FSRTC.checkPerms(function(status){checkDevices(runtime);},true,true);}else if(obj.skipPermCheck&&!obj.skipDeviceCheck){checkDevices(runtime);}else if(!obj.skipPermCheck&&obj.skipDeviceCheck){$.FSRTC.checkPerms(function(status){runtime(status);},true,true);}else{runtime(null);}}
|
||||
$.verto.genUUID=function(){return generateGUID();}})(jQuery);
|
||||
$.verto.genUUID=function(){return generateGUID();}})(jQuery);var AdapterJS=AdapterJS||{};if(typeof exports!=='undefined'){module.exports=AdapterJS;}
|
||||
AdapterJS.options=AdapterJS.options||{};AdapterJS.VERSION='0.13.3';AdapterJS.onwebrtcready=AdapterJS.onwebrtcready||function(isUsingPlugin){};AdapterJS._onwebrtcreadies=[];AdapterJS.webRTCReady=function(callback){if(typeof callback!=='function'){throw new Error('Callback provided is not a function');}
|
||||
if(true===AdapterJS.onwebrtcreadyDone){callback(null!==AdapterJS.WebRTCPlugin.plugin);}else{AdapterJS._onwebrtcreadies.push(callback);}};AdapterJS.WebRTCPlugin=AdapterJS.WebRTCPlugin||{};AdapterJS.WebRTCPlugin.pluginInfo={prefix:'Tem',plugName:'TemWebRTCPlugin',pluginId:'plugin0',type:'application/x-temwebrtcplugin',onload:'__TemWebRTCReady0',portalLink:'http://skylink.io/plugin/',downloadLink:null,companyName:'Temasys'};if(!!navigator.platform.match(/^Mac/i)){AdapterJS.WebRTCPlugin.pluginInfo.downloadLink='http://bit.ly/1n77hco';}
|
||||
else if(!!navigator.platform.match(/^Win/i)){AdapterJS.WebRTCPlugin.pluginInfo.downloadLink='http://bit.ly/1kkS4FN';}
|
||||
AdapterJS.WebRTCPlugin.TAGS={NONE:'none',AUDIO:'audio',VIDEO:'video'};AdapterJS.WebRTCPlugin.pageId=Math.random().toString(36).slice(2);AdapterJS.WebRTCPlugin.plugin=null;AdapterJS.WebRTCPlugin.setLogLevel=null;AdapterJS.WebRTCPlugin.defineWebRTCInterface=null;AdapterJS.WebRTCPlugin.isPluginInstalled=null;AdapterJS.WebRTCPlugin.pluginInjectionInterval=null;AdapterJS.WebRTCPlugin.injectPlugin=null;AdapterJS.WebRTCPlugin.PLUGIN_STATES={NONE:0,INITIALIZING:1,INJECTING:2,INJECTED:3,READY:4};AdapterJS.WebRTCPlugin.pluginState=AdapterJS.WebRTCPlugin.PLUGIN_STATES.NONE;AdapterJS.onwebrtcreadyDone=false;AdapterJS.WebRTCPlugin.PLUGIN_LOG_LEVELS={NONE:'NONE',ERROR:'ERROR',WARNING:'WARNING',INFO:'INFO',VERBOSE:'VERBOSE',SENSITIVE:'SENSITIVE'};AdapterJS.WebRTCPlugin.WaitForPluginReady=null;AdapterJS.WebRTCPlugin.callWhenPluginReady=null;__TemWebRTCReady0=function(){if(document.readyState==='complete'){AdapterJS.WebRTCPlugin.pluginState=AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY;AdapterJS.maybeThroughWebRTCReady();}else{var timer=setInterval(function(){if(document.readyState==='complete'){clearInterval(timer);AdapterJS.WebRTCPlugin.pluginState=AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY;AdapterJS.maybeThroughWebRTCReady();}},100);}};AdapterJS.maybeThroughWebRTCReady=function(){if(!AdapterJS.onwebrtcreadyDone){AdapterJS.onwebrtcreadyDone=true;if(AdapterJS._onwebrtcreadies.length){AdapterJS._onwebrtcreadies.forEach(function(callback){if(typeof(callback)==='function'){callback(AdapterJS.WebRTCPlugin.plugin!==null);}});}else if(typeof(AdapterJS.onwebrtcready)==='function'){AdapterJS.onwebrtcready(AdapterJS.WebRTCPlugin.plugin!==null);}}};AdapterJS.TEXT={PLUGIN:{REQUIRE_INSTALLATION:'This website requires you to install a WebRTC-enabling plugin '+'to work on this browser.',NOT_SUPPORTED:'Your browser does not support WebRTC.',BUTTON:'Install Now'},REFRESH:{REQUIRE_REFRESH:'Please refresh page',BUTTON:'Refresh Page'}};AdapterJS._iceConnectionStates={starting:'starting',checking:'checking',connected:'connected',completed:'connected',done:'completed',disconnected:'disconnected',failed:'failed',closed:'closed'};AdapterJS._iceConnectionFiredStates=[];AdapterJS.isDefined=null;AdapterJS.parseWebrtcDetectedBrowser=function(){var hasMatch=null;if((!!window.opr&&!!opr.addons)||!!window.opera||navigator.userAgent.indexOf(' OPR/')>=0){webrtcDetectedBrowser='opera';webrtcDetectedType='webkit';webrtcMinimumVersion=26;hasMatch=/OPR\/(\d+)/i.exec(navigator.userAgent)||[];webrtcDetectedVersion=parseInt(hasMatch[1],10);}else if(typeof InstallTrigger!=='undefined'){webrtcDetectedType='moz';}else if(Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor')>0){webrtcDetectedBrowser='safari';webrtcDetectedType='plugin';webrtcMinimumVersion=7;hasMatch=/version\/(\d+)/i.exec(navigator.userAgent)||[];webrtcDetectedVersion=parseInt(hasMatch[1],10);}else if(false||!!document.documentMode){webrtcDetectedBrowser='IE';webrtcDetectedType='plugin';webrtcMinimumVersion=9;hasMatch=/\brv[ :]+(\d+)/g.exec(navigator.userAgent)||[];webrtcDetectedVersion=parseInt(hasMatch[1]||'0',10);if(!webrtcDetectedVersion){hasMatch=/\bMSIE[ :]+(\d+)/g.exec(navigator.userAgent)||[];webrtcDetectedVersion=parseInt(hasMatch[1]||'0',10);}}else if(!!window.StyleMedia){webrtcDetectedType='';}else if(!!window.chrome&&!!window.chrome.webstore){webrtcDetectedType='webkit';}else if((webrtcDetectedBrowser==='chrome'||webrtcDetectedBrowser==='opera')&&!!window.CSS){webrtcDetectedBrowser='blink';}
|
||||
window.webrtcDetectedBrowser=webrtcDetectedBrowser;window.webrtcDetectedVersion=webrtcDetectedVersion;window.webrtcMinimumVersion=webrtcMinimumVersion;};AdapterJS.addEvent=function(elem,evnt,func){if(elem.addEventListener){elem.addEventListener(evnt,func,false);}else if(elem.attachEvent){elem.attachEvent('on'+evnt,func);}else{elem[evnt]=func;}};AdapterJS.renderNotificationBar=function(text,buttonText,buttonLink,openNewTab,displayRefreshBar){if(document.readyState!=='complete'){return;}
|
||||
var w=window;var i=document.createElement('iframe');i.name='adapterjs-alert';i.style.position='fixed';i.style.top='-41px';i.style.left=0;i.style.right=0;i.style.width='100%';i.style.height='40px';i.style.backgroundColor='#ffffe1';i.style.border='none';i.style.borderBottom='1px solid #888888';i.style.zIndex='9999999';if(typeof i.style.webkitTransition==='string'){i.style.webkitTransition='all .5s ease-out';}else if(typeof i.style.transition==='string'){i.style.transition='all .5s ease-out';}
|
||||
document.body.appendChild(i);var c=(i.contentWindow)?i.contentWindow:(i.contentDocument.document)?i.contentDocument.document:i.contentDocument;c.document.open();c.document.write('<span style="display: inline-block; font-family: Helvetica, Arial,'+'sans-serif; font-size: .9rem; padding: 4px; vertical-align: '+'middle; cursor: default;">'+text+'</span>');if(buttonText&&buttonLink){c.document.write('<button id="okay">'+buttonText+'</button><button id="cancel">Cancel</button>');c.document.close();AdapterJS.addEvent(c.document.getElementById('okay'),'click',function(e){if(!!displayRefreshBar){AdapterJS.renderNotificationBar(AdapterJS.TEXT.EXTENSION?AdapterJS.TEXT.EXTENSION.REQUIRE_REFRESH:AdapterJS.TEXT.REFRESH.REQUIRE_REFRESH,AdapterJS.TEXT.REFRESH.BUTTON,'javascript:location.reload()');}
|
||||
window.open(buttonLink,!!openNewTab?'_blank':'_top');e.preventDefault();try{e.cancelBubble=true;}catch(error){}
|
||||
var pluginInstallInterval=setInterval(function(){if(!isIE){navigator.plugins.refresh(false);}
|
||||
AdapterJS.WebRTCPlugin.isPluginInstalled(AdapterJS.WebRTCPlugin.pluginInfo.prefix,AdapterJS.WebRTCPlugin.pluginInfo.plugName,function(){clearInterval(pluginInstallInterval);AdapterJS.WebRTCPlugin.defineWebRTCInterface();},function(){});},500);});AdapterJS.addEvent(c.document.getElementById('cancel'),'click',function(e){w.document.body.removeChild(i);});}else{c.document.close();}
|
||||
setTimeout(function(){if(typeof i.style.webkitTransform==='string'){i.style.webkitTransform='translateY(40px)';}else if(typeof i.style.transform==='string'){i.style.transform='translateY(40px)';}else{i.style.top='0px';}},300);};webrtcDetectedType=null;checkMediaDataChannelSettings=function(peerBrowserAgent,peerBrowserVersion,callback,constraints){if(typeof callback!=='function'){return;}
|
||||
var beOfferer=true;var isLocalFirefox=webrtcDetectedBrowser==='firefox';var isLocalFirefoxInterop=webrtcDetectedType==='moz'&&webrtcDetectedVersion>30;var isPeerFirefox=peerBrowserAgent==='firefox';var isPeerFirefoxInterop=peerBrowserAgent==='firefox'&&((peerBrowserVersion)?(peerBrowserVersion>30):false);if((isLocalFirefox&&isPeerFirefox)||(isLocalFirefoxInterop)){try{delete constraints.mandatory.MozDontOfferDataChannel;}catch(error){console.error('Failed deleting MozDontOfferDataChannel');console.error(error);}}else if((isLocalFirefox&&!isPeerFirefox)){constraints.mandatory.MozDontOfferDataChannel=true;}
|
||||
if(!isLocalFirefox){for(var prop in constraints.mandatory){if(constraints.mandatory.hasOwnProperty(prop)){if(prop.indexOf('Moz')!==-1){delete constraints.mandatory[prop];}}}}
|
||||
if(isLocalFirefox&&!isPeerFirefox&&!isLocalFirefoxInterop){beOfferer=false;}
|
||||
callback(beOfferer,constraints);};checkIceConnectionState=function(peerId,iceConnectionState,callback){if(typeof callback!=='function'){console.warn('No callback specified in checkIceConnectionState. Aborted.');return;}
|
||||
peerId=(peerId)?peerId:'peer';if(!AdapterJS._iceConnectionFiredStates[peerId]||iceConnectionState===AdapterJS._iceConnectionStates.disconnected||iceConnectionState===AdapterJS._iceConnectionStates.failed||iceConnectionState===AdapterJS._iceConnectionStates.closed){AdapterJS._iceConnectionFiredStates[peerId]=[];}
|
||||
iceConnectionState=AdapterJS._iceConnectionStates[iceConnectionState];if(AdapterJS._iceConnectionFiredStates[peerId].indexOf(iceConnectionState)<0){AdapterJS._iceConnectionFiredStates[peerId].push(iceConnectionState);if(iceConnectionState===AdapterJS._iceConnectionStates.connected){setTimeout(function(){AdapterJS._iceConnectionFiredStates[peerId].push(AdapterJS._iceConnectionStates.done);callback(AdapterJS._iceConnectionStates.done);},1000);}
|
||||
callback(iceConnectionState);}
|
||||
return;};createIceServer=null;createIceServers=null;RTCPeerConnection=null;RTCSessionDescription=(typeof RTCSessionDescription==='function')?RTCSessionDescription:null;RTCIceCandidate=(typeof RTCIceCandidate==='function')?RTCIceCandidate:null;getUserMedia=null;attachMediaStream=null;reattachMediaStream=null;webrtcDetectedBrowser=null;webrtcDetectedVersion=null;webrtcMinimumVersion=null;if(navigator.mozGetUserMedia||navigator.webkitGetUserMedia||(navigator.mediaDevices&&navigator.userAgent.match(/Edge\/(\d+).(\d+)$/))){(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.adapter=f()}})(function(){var define,module,exports;return(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){'use strict';var SDPUtils={};SDPUtils.generateIdentifier=function(){return Math.random().toString(36).substr(2,10);};SDPUtils.localCName=SDPUtils.generateIdentifier();SDPUtils.splitLines=function(blob){return blob.trim().split('\n').map(function(line){return line.trim();});};SDPUtils.splitSections=function(blob){var parts=blob.split('\nm=');return parts.map(function(part,index){return(index>0?'m='+part:part).trim()+'\r\n';});};SDPUtils.matchPrefix=function(blob,prefix){return SDPUtils.splitLines(blob).filter(function(line){return line.indexOf(prefix)===0;});};SDPUtils.parseCandidate=function(line){var parts;if(line.indexOf('a=candidate:')===0){parts=line.substring(12).split(' ');}else{parts=line.substring(10).split(' ');}
|
||||
var candidate={foundation:parts[0],component:parts[1],protocol:parts[2].toLowerCase(),priority:parseInt(parts[3],10),ip:parts[4],port:parseInt(parts[5],10),type:parts[7]};for(var i=8;i<parts.length;i+=2){switch(parts[i]){case'raddr':candidate.relatedAddress=parts[i+1];break;case'rport':candidate.relatedPort=parseInt(parts[i+1],10);break;case'tcptype':candidate.tcpType=parts[i+1];break;default:break;}}
|
||||
return candidate;};SDPUtils.writeCandidate=function(candidate){var sdp=[];sdp.push(candidate.foundation);sdp.push(candidate.component);sdp.push(candidate.protocol.toUpperCase());sdp.push(candidate.priority);sdp.push(candidate.ip);sdp.push(candidate.port);var type=candidate.type;sdp.push('typ');sdp.push(type);if(type!=='host'&&candidate.relatedAddress&&candidate.relatedPort){sdp.push('raddr');sdp.push(candidate.relatedAddress);sdp.push('rport');sdp.push(candidate.relatedPort);}
|
||||
if(candidate.tcpType&&candidate.protocol.toLowerCase()==='tcp'){sdp.push('tcptype');sdp.push(candidate.tcpType);}
|
||||
return'candidate:'+sdp.join(' ');};SDPUtils.parseRtpMap=function(line){var parts=line.substr(9).split(' ');var parsed={payloadType:parseInt(parts.shift(),10)};parts=parts[0].split('/');parsed.name=parts[0];parsed.clockRate=parseInt(parts[1],10);parsed.numChannels=parts.length===3?parseInt(parts[2],10):1;return parsed;};SDPUtils.writeRtpMap=function(codec){var pt=codec.payloadType;if(codec.preferredPayloadType!==undefined){pt=codec.preferredPayloadType;}
|
||||
return'a=rtpmap:'+pt+' '+codec.name+'/'+codec.clockRate+
|
||||
(codec.numChannels!==1?'/'+codec.numChannels:'')+'\r\n';};SDPUtils.parseExtmap=function(line){var parts=line.substr(9).split(' ');return{id:parseInt(parts[0],10),uri:parts[1]};};SDPUtils.writeExtmap=function(headerExtension){return'a=extmap:'+(headerExtension.id||headerExtension.preferredId)+' '+headerExtension.uri+'\r\n';};SDPUtils.parseFmtp=function(line){var parsed={};var kv;var parts=line.substr(line.indexOf(' ')+1).split(';');for(var j=0;j<parts.length;j++){kv=parts[j].trim().split('=');parsed[kv[0].trim()]=kv[1];}
|
||||
return parsed;};SDPUtils.writeFmtp=function(codec){var line='';var pt=codec.payloadType;if(codec.preferredPayloadType!==undefined){pt=codec.preferredPayloadType;}
|
||||
if(codec.parameters&&Object.keys(codec.parameters).length){var params=[];Object.keys(codec.parameters).forEach(function(param){params.push(param+'='+codec.parameters[param]);});line+='a=fmtp:'+pt+' '+params.join(';')+'\r\n';}
|
||||
return line;};SDPUtils.parseRtcpFb=function(line){var parts=line.substr(line.indexOf(' ')+1).split(' ');return{type:parts.shift(),parameter:parts.join(' ')};};SDPUtils.writeRtcpFb=function(codec){var lines='';var pt=codec.payloadType;if(codec.preferredPayloadType!==undefined){pt=codec.preferredPayloadType;}
|
||||
if(codec.rtcpFeedback&&codec.rtcpFeedback.length){codec.rtcpFeedback.forEach(function(fb){lines+='a=rtcp-fb:'+pt+' '+fb.type+
|
||||
(fb.parameter&&fb.parameter.length?' '+fb.parameter:'')+'\r\n';});}
|
||||
return lines;};SDPUtils.parseSsrcMedia=function(line){var sp=line.indexOf(' ');var parts={ssrc:parseInt(line.substr(7,sp-7),10)};var colon=line.indexOf(':',sp);if(colon>-1){parts.attribute=line.substr(sp+1,colon-sp-1);parts.value=line.substr(colon+1);}else{parts.attribute=line.substr(sp+1);}
|
||||
return parts;};SDPUtils.getDtlsParameters=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);lines=lines.concat(SDPUtils.splitLines(sessionpart));var fpLine=lines.filter(function(line){return line.indexOf('a=fingerprint:')===0;})[0].substr(14);var dtlsParameters={role:'auto',fingerprints:[{algorithm:fpLine.split(' ')[0],value:fpLine.split(' ')[1]}]};return dtlsParameters;};SDPUtils.writeDtlsParameters=function(params,setupType){var sdp='a=setup:'+setupType+'\r\n';params.fingerprints.forEach(function(fp){sdp+='a=fingerprint:'+fp.algorithm+' '+fp.value+'\r\n';});return sdp;};SDPUtils.getIceParameters=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);lines=lines.concat(SDPUtils.splitLines(sessionpart));var iceParameters={usernameFragment:lines.filter(function(line){return line.indexOf('a=ice-ufrag:')===0;})[0].substr(12),password:lines.filter(function(line){return line.indexOf('a=ice-pwd:')===0;})[0].substr(10)};return iceParameters;};SDPUtils.writeIceParameters=function(params){return'a=ice-ufrag:'+params.usernameFragment+'\r\n'+'a=ice-pwd:'+params.password+'\r\n';};SDPUtils.parseRtpParameters=function(mediaSection){var description={codecs:[],headerExtensions:[],fecMechanisms:[],rtcp:[]};var lines=SDPUtils.splitLines(mediaSection);var mline=lines[0].split(' ');for(var i=3;i<mline.length;i++){var pt=mline[i];var rtpmapline=SDPUtils.matchPrefix(mediaSection,'a=rtpmap:'+pt+' ')[0];if(rtpmapline){var codec=SDPUtils.parseRtpMap(rtpmapline);var fmtps=SDPUtils.matchPrefix(mediaSection,'a=fmtp:'+pt+' ');codec.parameters=fmtps.length?SDPUtils.parseFmtp(fmtps[0]):{};codec.rtcpFeedback=SDPUtils.matchPrefix(mediaSection,'a=rtcp-fb:'+pt+' ').map(SDPUtils.parseRtcpFb);description.codecs.push(codec);switch(codec.name.toUpperCase()){case'RED':case'ULPFEC':description.fecMechanisms.push(codec.name.toUpperCase());break;default:break;}}}
|
||||
SDPUtils.matchPrefix(mediaSection,'a=extmap:').forEach(function(line){description.headerExtensions.push(SDPUtils.parseExtmap(line));});return description;};SDPUtils.writeRtpDescription=function(kind,caps){var sdp='';sdp+='m='+kind+' ';sdp+=caps.codecs.length>0?'9':'0';sdp+=' UDP/TLS/RTP/SAVPF ';sdp+=caps.codecs.map(function(codec){if(codec.preferredPayloadType!==undefined){return codec.preferredPayloadType;}
|
||||
return codec.payloadType;}).join(' ')+'\r\n';sdp+='c=IN IP4 0.0.0.0\r\n';sdp+='a=rtcp:9 IN IP4 0.0.0.0\r\n';caps.codecs.forEach(function(codec){sdp+=SDPUtils.writeRtpMap(codec);sdp+=SDPUtils.writeFmtp(codec);sdp+=SDPUtils.writeRtcpFb(codec);});sdp+='a=rtcp-mux\r\n';return sdp;};SDPUtils.parseRtpEncodingParameters=function(mediaSection){var encodingParameters=[];var description=SDPUtils.parseRtpParameters(mediaSection);var hasRed=description.fecMechanisms.indexOf('RED')!==-1;var hasUlpfec=description.fecMechanisms.indexOf('ULPFEC')!==-1;var ssrcs=SDPUtils.matchPrefix(mediaSection,'a=ssrc:').map(function(line){return SDPUtils.parseSsrcMedia(line);}).filter(function(parts){return parts.attribute==='cname';});var primarySsrc=ssrcs.length>0&&ssrcs[0].ssrc;var secondarySsrc;var flows=SDPUtils.matchPrefix(mediaSection,'a=ssrc-group:FID').map(function(line){var parts=line.split(' ');parts.shift();return parts.map(function(part){return parseInt(part,10);});});if(flows.length>0&&flows[0].length>1&&flows[0][0]===primarySsrc){secondarySsrc=flows[0][1];}
|
||||
description.codecs.forEach(function(codec){if(codec.name.toUpperCase()==='RTX'&&codec.parameters.apt){var encParam={ssrc:primarySsrc,codecPayloadType:parseInt(codec.parameters.apt,10),rtx:{payloadType:codec.payloadType,ssrc:secondarySsrc}};encodingParameters.push(encParam);if(hasRed){encParam=JSON.parse(JSON.stringify(encParam));encParam.fec={ssrc:secondarySsrc,mechanism:hasUlpfec?'red+ulpfec':'red'};encodingParameters.push(encParam);}}});if(encodingParameters.length===0&&primarySsrc){encodingParameters.push({ssrc:primarySsrc});}
|
||||
var bandwidth=SDPUtils.matchPrefix(mediaSection,'b=');if(bandwidth.length){if(bandwidth[0].indexOf('b=TIAS:')===0){bandwidth=parseInt(bandwidth[0].substr(7),10);}else if(bandwidth[0].indexOf('b=AS:')===0){bandwidth=parseInt(bandwidth[0].substr(5),10);}
|
||||
encodingParameters.forEach(function(params){params.maxBitrate=bandwidth;});}
|
||||
return encodingParameters;};SDPUtils.writeSessionBoilerplate=function(){return'v=0\r\n'+'o=thisisadapterortc 8169639915646943137 2 IN IP4 127.0.0.1\r\n'+'s=-\r\n'+'t=0 0\r\n';};SDPUtils.writeMediaSection=function(transceiver,caps,type,stream){var sdp=SDPUtils.writeRtpDescription(transceiver.kind,caps);sdp+=SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters());sdp+=SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(),type==='offer'?'actpass':'active');sdp+='a=mid:'+transceiver.mid+'\r\n';if(transceiver.rtpSender&&transceiver.rtpReceiver){sdp+='a=sendrecv\r\n';}else if(transceiver.rtpSender){sdp+='a=sendonly\r\n';}else if(transceiver.rtpReceiver){sdp+='a=recvonly\r\n';}else{sdp+='a=inactive\r\n';}
|
||||
if(transceiver.rtpSender){var msid='msid:'+stream.id+' '+
|
||||
transceiver.rtpSender.track.id+'\r\n';sdp+='a='+msid;sdp+='a=ssrc:'+transceiver.sendEncodingParameters[0].ssrc+' '+msid;}
|
||||
sdp+='a=ssrc:'+transceiver.sendEncodingParameters[0].ssrc+' cname:'+SDPUtils.localCName+'\r\n';return sdp;};SDPUtils.getDirection=function(mediaSection,sessionpart){var lines=SDPUtils.splitLines(mediaSection);for(var i=0;i<lines.length;i++){switch(lines[i]){case'a=sendrecv':case'a=sendonly':case'a=recvonly':case'a=inactive':return lines[i].substr(2);default:}}
|
||||
if(sessionpart){return SDPUtils.getDirection(sessionpart);}
|
||||
return'sendrecv';};module.exports=SDPUtils;},{}],2:[function(require,module,exports){'use strict';(function(){var logging=require('./utils').log;var browserDetails=require('./utils').browserDetails;module.exports.browserDetails=browserDetails;module.exports.extractVersion=require('./utils').extractVersion;module.exports.disableLog=require('./utils').disableLog;var chromeShim=require('./chrome/chrome_shim')||null;var edgeShim=require('./edge/edge_shim')||null;var firefoxShim=require('./firefox/firefox_shim')||null;var safariShim=require('./safari/safari_shim')||null;switch(browserDetails.browser){case'opera':case'chrome':if(!chromeShim||!chromeShim.shimPeerConnection){logging('Chrome shim is not included in this adapter release.');return;}
|
||||
logging('adapter.js shimming chrome.');module.exports.browserShim=chromeShim;chromeShim.shimGetUserMedia();chromeShim.shimMediaStream();chromeShim.shimSourceObject();chromeShim.shimPeerConnection();chromeShim.shimOnTrack();break;case'firefox':if(!firefoxShim||!firefoxShim.shimPeerConnection){logging('Firefox shim is not included in this adapter release.');return;}
|
||||
logging('adapter.js shimming firefox.');module.exports.browserShim=firefoxShim;firefoxShim.shimGetUserMedia();firefoxShim.shimSourceObject();firefoxShim.shimPeerConnection();firefoxShim.shimOnTrack();break;case'edge':if(!edgeShim||!edgeShim.shimPeerConnection){logging('MS edge shim is not included in this adapter release.');return;}
|
||||
logging('adapter.js shimming edge.');module.exports.browserShim=edgeShim;edgeShim.shimGetUserMedia();edgeShim.shimPeerConnection();break;case'safari':if(!safariShim){logging('Safari shim is not included in this adapter release.');return;}
|
||||
logging('adapter.js shimming safari.');module.exports.browserShim=safariShim;safariShim.shimGetUserMedia();break;default:logging('Unsupported browser!');}})();},{"./chrome/chrome_shim":3,"./edge/edge_shim":5,"./firefox/firefox_shim":7,"./safari/safari_shim":9,"./utils":10}],3:[function(require,module,exports){'use strict';var logging=require('../utils.js').log;var browserDetails=require('../utils.js').browserDetails;var chromeShim={shimMediaStream:function(){window.MediaStream=window.MediaStream||window.webkitMediaStream;},shimOnTrack:function(){if(typeof window==='object'&&window.RTCPeerConnection&&!('ontrack'in
|
||||
window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,'ontrack',{get:function(){return this._ontrack;},set:function(f){var self=this;if(this._ontrack){this.removeEventListener('track',this._ontrack);this.removeEventListener('addstream',this._ontrackpoly);}
|
||||
this.addEventListener('track',this._ontrack=f);this.addEventListener('addstream',this._ontrackpoly=function(e){e.stream.addEventListener('addtrack',function(te){var event=new Event('track');event.track=te.track;event.receiver={track:te.track};event.streams=[e.stream];self.dispatchEvent(event);});e.stream.getTracks().forEach(function(track){var event=new Event('track');event.track=track;event.receiver={track:track};event.streams=[e.stream];this.dispatchEvent(event);}.bind(this));}.bind(this));}});}},shimSourceObject:function(){if(typeof window==='object'){if(window.HTMLMediaElement&&!('srcObject'in window.HTMLMediaElement.prototype)){Object.defineProperty(window.HTMLMediaElement.prototype,'srcObject',{get:function(){return this._srcObject;},set:function(stream){var self=this;this._srcObject=stream;if(this.src){URL.revokeObjectURL(this.src);}
|
||||
if(!stream){this.src='';return;}
|
||||
this.src=URL.createObjectURL(stream);stream.addEventListener('addtrack',function(){if(self.src){URL.revokeObjectURL(self.src);}
|
||||
self.src=URL.createObjectURL(stream);});stream.addEventListener('removetrack',function(){if(self.src){URL.revokeObjectURL(self.src);}
|
||||
self.src=URL.createObjectURL(stream);});}});}}},shimPeerConnection:function(){window.RTCPeerConnection=function(pcConfig,pcConstraints){logging('PeerConnection');if(pcConfig&&pcConfig.iceTransportPolicy){pcConfig.iceTransports=pcConfig.iceTransportPolicy;}
|
||||
var pc=new webkitRTCPeerConnection(pcConfig,pcConstraints);var origGetStats=pc.getStats.bind(pc);pc.getStats=function(selector,successCallback,errorCallback){var self=this;var args=arguments;if(arguments.length>0&&typeof selector==='function'){return origGetStats(selector,successCallback);}
|
||||
var fixChromeStats_=function(response){var standardReport={};var reports=response.result();reports.forEach(function(report){var standardStats={id:report.id,timestamp:report.timestamp,type:report.type};report.names().forEach(function(name){standardStats[name]=report.stat(name);});standardReport[standardStats.id]=standardStats;});return standardReport;};var makeMapStats=function(stats,legacyStats){var map=new Map(Object.keys(stats).map(function(key){return[key,stats[key]];}));legacyStats=legacyStats||stats;Object.keys(legacyStats).forEach(function(key){map[key]=legacyStats[key];});return map;};if(arguments.length>=2){var successCallbackWrapper_=function(response){args[1](makeMapStats(fixChromeStats_(response)));};return origGetStats.apply(this,[successCallbackWrapper_,arguments[0]]);}
|
||||
return new Promise(function(resolve,reject){if(args.length===1&&typeof selector==='object'){origGetStats.apply(self,[function(response){resolve(makeMapStats(fixChromeStats_(response)));},reject]);}else{origGetStats.apply(self,[function(response){resolve(makeMapStats(fixChromeStats_(response),response.result()));},reject]);}}).then(successCallback,errorCallback);};return pc;};window.RTCPeerConnection.prototype=webkitRTCPeerConnection.prototype;if(webkitRTCPeerConnection.generateCertificate){Object.defineProperty(window.RTCPeerConnection,'generateCertificate',{get:function(){return webkitRTCPeerConnection.generateCertificate;}});}
|
||||
['createOffer','createAnswer'].forEach(function(method){var nativeMethod=webkitRTCPeerConnection.prototype[method];webkitRTCPeerConnection.prototype[method]=function(){var self=this;if(arguments.length<1||(arguments.length===1&&typeof arguments[0]==='object')){var opts=arguments.length===1?arguments[0]:undefined;return new Promise(function(resolve,reject){nativeMethod.apply(self,[resolve,reject,opts]);});}
|
||||
return nativeMethod.apply(this,arguments);};});if(browserDetails.version<51){['setLocalDescription','setRemoteDescription','addIceCandidate'].forEach(function(method){var nativeMethod=webkitRTCPeerConnection.prototype[method];webkitRTCPeerConnection.prototype[method]=function(){var args=arguments;var self=this;var promise=new Promise(function(resolve,reject){nativeMethod.apply(self,[args[0],resolve,reject]);});if(args.length<2){return promise;}
|
||||
return promise.then(function(){args[1].apply(null,[]);},function(err){if(args.length>=3){args[2].apply(null,[err]);}});};});}
|
||||
['setLocalDescription','setRemoteDescription','addIceCandidate'].forEach(function(method){var nativeMethod=webkitRTCPeerConnection.prototype[method];webkitRTCPeerConnection.prototype[method]=function(){arguments[0]=new((method==='addIceCandidate')?RTCIceCandidate:RTCSessionDescription)(arguments[0]);return nativeMethod.apply(this,arguments);};});var nativeAddIceCandidate=RTCPeerConnection.prototype.addIceCandidate;RTCPeerConnection.prototype.addIceCandidate=function(){return arguments[0]===null?Promise.resolve():nativeAddIceCandidate.apply(this,arguments);};}};module.exports={shimMediaStream:chromeShim.shimMediaStream,shimOnTrack:chromeShim.shimOnTrack,shimSourceObject:chromeShim.shimSourceObject,shimPeerConnection:chromeShim.shimPeerConnection,shimGetUserMedia:require('./getusermedia')};},{"../utils.js":10,"./getusermedia":4}],4:[function(require,module,exports){'use strict';var logging=require('../utils.js').log;module.exports=function(){var constraintsToChrome_=function(c){if(typeof c!=='object'||c.mandatory||c.optional){return c;}
|
||||
var cc={};Object.keys(c).forEach(function(key){if(key==='require'||key==='advanced'||key==='mediaSource'){return;}
|
||||
var r=(typeof c[key]==='object')?c[key]:{ideal:c[key]};if(r.exact!==undefined&&typeof r.exact==='number'){r.min=r.max=r.exact;}
|
||||
var oldname_=function(prefix,name){if(prefix){return prefix+name.charAt(0).toUpperCase()+name.slice(1);}
|
||||
return(name==='deviceId')?'sourceId':name;};if(r.ideal!==undefined){cc.optional=cc.optional||[];var oc={};if(typeof r.ideal==='number'){oc[oldname_('min',key)]=r.ideal;cc.optional.push(oc);oc={};oc[oldname_('max',key)]=r.ideal;cc.optional.push(oc);}else{oc[oldname_('',key)]=r.ideal;cc.optional.push(oc);}}
|
||||
if(r.exact!==undefined&&typeof r.exact!=='number'){cc.mandatory=cc.mandatory||{};cc.mandatory[oldname_('',key)]=r.exact;}else{['min','max'].forEach(function(mix){if(r[mix]!==undefined){cc.mandatory=cc.mandatory||{};cc.mandatory[oldname_(mix,key)]=r[mix];}});}});if(c.advanced){cc.optional=(cc.optional||[]).concat(c.advanced);}
|
||||
return cc;};var shimConstraints_=function(constraints,func){constraints=JSON.parse(JSON.stringify(constraints));if(constraints&&constraints.audio){constraints.audio=constraintsToChrome_(constraints.audio);}
|
||||
if(constraints&&typeof constraints.video==='object'){var face=constraints.video.facingMode;face=face&&((typeof face==='object')?face:{ideal:face});if((face&&(face.exact==='user'||face.exact==='environment'||face.ideal==='user'||face.ideal==='environment'))&&!(navigator.mediaDevices.getSupportedConstraints&&navigator.mediaDevices.getSupportedConstraints().facingMode)){delete constraints.video.facingMode;if(face.exact==='environment'||face.ideal==='environment'){return navigator.mediaDevices.enumerateDevices().then(function(devices){devices=devices.filter(function(d){return d.kind==='videoinput';});var back=devices.find(function(d){return d.label.toLowerCase().indexOf('back')!==-1;})||(devices.length&&devices[devices.length-1]);if(back){constraints.video.deviceId=face.exact?{exact:back.deviceId}:{ideal:back.deviceId};}
|
||||
constraints.video=constraintsToChrome_(constraints.video);logging('chrome: '+JSON.stringify(constraints));return func(constraints);});}}
|
||||
constraints.video=constraintsToChrome_(constraints.video);}
|
||||
logging('chrome: '+JSON.stringify(constraints));return func(constraints);};var shimError_=function(e){return{name:{PermissionDeniedError:'NotAllowedError',ConstraintNotSatisfiedError:'OverconstrainedError'}[e.name]||e.name,message:e.message,constraint:e.constraintName,toString:function(){return this.name+(this.message&&': ')+this.message;}};};var getUserMedia_=function(constraints,onSuccess,onError){shimConstraints_(constraints,function(c){navigator.webkitGetUserMedia(c,onSuccess,function(e){onError(shimError_(e));});});};navigator.getUserMedia=getUserMedia_;var getUserMediaPromise_=function(constraints){return new Promise(function(resolve,reject){navigator.getUserMedia(constraints,resolve,reject);});};if(!navigator.mediaDevices){navigator.mediaDevices={getUserMedia:getUserMediaPromise_,enumerateDevices:function(){return new Promise(function(resolve){var kinds={audio:'audioinput',video:'videoinput'};return MediaStreamTrack.getSources(function(devices){resolve(devices.map(function(device){return{label:device.label,kind:kinds[device.kind],deviceId:device.id,groupId:''};}));});});}};}
|
||||
if(!navigator.mediaDevices.getUserMedia){navigator.mediaDevices.getUserMedia=function(constraints){return getUserMediaPromise_(constraints);};}else{var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(cs){return shimConstraints_(cs,function(c){return origGetUserMedia(c).catch(function(e){return Promise.reject(shimError_(e));});});};}
|
||||
if(typeof navigator.mediaDevices.addEventListener==='undefined'){navigator.mediaDevices.addEventListener=function(){logging('Dummy mediaDevices.addEventListener called.');};}
|
||||
if(typeof navigator.mediaDevices.removeEventListener==='undefined'){navigator.mediaDevices.removeEventListener=function(){logging('Dummy mediaDevices.removeEventListener called.');};}};},{"../utils.js":10}],5:[function(require,module,exports){'use strict';var SDPUtils=require('sdp');var edgeShim={shimPeerConnection:function(){if(window.RTCIceGatherer){if(!window.RTCIceCandidate){window.RTCIceCandidate=function(args){return args;};}
|
||||
if(!window.RTCSessionDescription){window.RTCSessionDescription=function(args){return args;};}}
|
||||
window.RTCPeerConnection=function(config){var self=this;var _eventTarget=document.createDocumentFragment();['addEventListener','removeEventListener','dispatchEvent'].forEach(function(method){self[method]=_eventTarget[method].bind(_eventTarget);});this.onicecandidate=null;this.onaddstream=null;this.ontrack=null;this.onremovestream=null;this.onsignalingstatechange=null;this.oniceconnectionstatechange=null;this.onnegotiationneeded=null;this.ondatachannel=null;this.localStreams=[];this.remoteStreams=[];this.getLocalStreams=function(){return self.localStreams;};this.getRemoteStreams=function(){return self.remoteStreams;};this.localDescription=new RTCSessionDescription({type:'',sdp:''});this.remoteDescription=new RTCSessionDescription({type:'',sdp:''});this.signalingState='stable';this.iceConnectionState='new';this.iceGatheringState='new';this.iceOptions={gatherPolicy:'all',iceServers:[]};if(config&&config.iceTransportPolicy){switch(config.iceTransportPolicy){case'all':case'relay':this.iceOptions.gatherPolicy=config.iceTransportPolicy;break;case'none':throw new TypeError('iceTransportPolicy "none" not supported');default:break;}}
|
||||
this.usingBundle=config&&config.bundlePolicy==='max-bundle';if(config&&config.iceServers){var iceServers=JSON.parse(JSON.stringify(config.iceServers));this.iceOptions.iceServers=iceServers.filter(function(server){if(server&&server.urls){var urls=server.urls;if(typeof urls==='string'){urls=[urls];}
|
||||
urls=urls.filter(function(url){return url.indexOf('turn:')===0&&url.indexOf('transport=udp')!==-1&&url.indexOf('turn:[')===-1;})[0];return!!urls;}
|
||||
return false;});}
|
||||
this.transceivers=[];this._localIceCandidatesBuffer=[];};window.RTCPeerConnection.prototype._emitBufferedCandidates=function(){var self=this;var sections=SDPUtils.splitSections(self.localDescription.sdp);this._localIceCandidatesBuffer.forEach(function(event){var end=!event.candidate||Object.keys(event.candidate).length===0;if(end){for(var j=1;j<sections.length;j++){if(sections[j].indexOf('\r\na=end-of-candidates\r\n')===-1){sections[j]+='a=end-of-candidates\r\n';}}}else if(event.candidate.candidate.indexOf('typ endOfCandidates')===-1){sections[event.candidate.sdpMLineIndex+1]+='a='+event.candidate.candidate+'\r\n';}
|
||||
self.localDescription.sdp=sections.join('');self.dispatchEvent(event);if(self.onicecandidate!==null){self.onicecandidate(event);}
|
||||
if(!event.candidate&&self.iceGatheringState!=='complete'){var complete=self.transceivers.every(function(transceiver){return transceiver.iceGatherer&&transceiver.iceGatherer.state==='completed';});if(complete){self.iceGatheringState='complete';}}});this._localIceCandidatesBuffer=[];};window.RTCPeerConnection.prototype.addStream=function(stream){this.localStreams.push(stream.clone());this._maybeFireNegotiationNeeded();};window.RTCPeerConnection.prototype.removeStream=function(stream){var idx=this.localStreams.indexOf(stream);if(idx>-1){this.localStreams.splice(idx,1);this._maybeFireNegotiationNeeded();}};window.RTCPeerConnection.prototype.getSenders=function(){return this.transceivers.filter(function(transceiver){return!!transceiver.rtpSender;}).map(function(transceiver){return transceiver.rtpSender;});};window.RTCPeerConnection.prototype.getReceivers=function(){return this.transceivers.filter(function(transceiver){return!!transceiver.rtpReceiver;}).map(function(transceiver){return transceiver.rtpReceiver;});};window.RTCPeerConnection.prototype._getCommonCapabilities=function(localCapabilities,remoteCapabilities){var commonCapabilities={codecs:[],headerExtensions:[],fecMechanisms:[]};localCapabilities.codecs.forEach(function(lCodec){for(var i=0;i<remoteCapabilities.codecs.length;i++){var rCodec=remoteCapabilities.codecs[i];if(lCodec.name.toLowerCase()===rCodec.name.toLowerCase()&&lCodec.clockRate===rCodec.clockRate&&lCodec.numChannels===rCodec.numChannels){commonCapabilities.codecs.push(rCodec);rCodec.rtcpFeedback=rCodec.rtcpFeedback.filter(function(fb){for(var j=0;j<lCodec.rtcpFeedback.length;j++){if(lCodec.rtcpFeedback[j].type===fb.type&&lCodec.rtcpFeedback[j].parameter===fb.parameter){return true;}}
|
||||
return false;});break;}}});localCapabilities.headerExtensions.forEach(function(lHeaderExtension){for(var i=0;i<remoteCapabilities.headerExtensions.length;i++){var rHeaderExtension=remoteCapabilities.headerExtensions[i];if(lHeaderExtension.uri===rHeaderExtension.uri){commonCapabilities.headerExtensions.push(rHeaderExtension);break;}}});return commonCapabilities;};window.RTCPeerConnection.prototype._createIceAndDtlsTransports=function(mid,sdpMLineIndex){var self=this;var iceGatherer=new RTCIceGatherer(self.iceOptions);var iceTransport=new RTCIceTransport(iceGatherer);iceGatherer.onlocalcandidate=function(evt){var event=new Event('icecandidate');event.candidate={sdpMid:mid,sdpMLineIndex:sdpMLineIndex};var cand=evt.candidate;var end=!cand||Object.keys(cand).length===0;if(end){if(iceGatherer.state===undefined){iceGatherer.state='completed';}
|
||||
event.candidate.candidate='candidate:1 1 udp 1 0.0.0.0 9 typ endOfCandidates';}else{cand.component=iceTransport.component==='RTCP'?2:1;event.candidate.candidate=SDPUtils.writeCandidate(cand);}
|
||||
var sections=SDPUtils.splitSections(self.localDescription.sdp);if(event.candidate.candidate.indexOf('typ endOfCandidates')===-1){sections[event.candidate.sdpMLineIndex+1]+='a='+event.candidate.candidate+'\r\n';}else{sections[event.candidate.sdpMLineIndex+1]+='a=end-of-candidates\r\n';}
|
||||
self.localDescription.sdp=sections.join('');var complete=self.transceivers.every(function(transceiver){return transceiver.iceGatherer&&transceiver.iceGatherer.state==='completed';});switch(self.iceGatheringState){case'new':self._localIceCandidatesBuffer.push(event);if(end&&complete){self._localIceCandidatesBuffer.push(new Event('icecandidate'));}
|
||||
break;case'gathering':self._emitBufferedCandidates();self.dispatchEvent(event);if(self.onicecandidate!==null){self.onicecandidate(event);}
|
||||
if(complete){self.dispatchEvent(new Event('icecandidate'));if(self.onicecandidate!==null){self.onicecandidate(new Event('icecandidate'));}
|
||||
self.iceGatheringState='complete';}
|
||||
break;case'complete':break;default:break;}};iceTransport.onicestatechange=function(){self._updateConnectionState();};var dtlsTransport=new RTCDtlsTransport(iceTransport);dtlsTransport.ondtlsstatechange=function(){self._updateConnectionState();};dtlsTransport.onerror=function(){dtlsTransport.state='failed';self._updateConnectionState();};return{iceGatherer:iceGatherer,iceTransport:iceTransport,dtlsTransport:dtlsTransport};};window.RTCPeerConnection.prototype._transceive=function(transceiver,send,recv){var params=this._getCommonCapabilities(transceiver.localCapabilities,transceiver.remoteCapabilities);if(send&&transceiver.rtpSender){params.encodings=transceiver.sendEncodingParameters;params.rtcp={cname:SDPUtils.localCName};if(transceiver.recvEncodingParameters.length){params.rtcp.ssrc=transceiver.recvEncodingParameters[0].ssrc;}
|
||||
transceiver.rtpSender.send(params);}
|
||||
if(recv&&transceiver.rtpReceiver){params.encodings=transceiver.recvEncodingParameters;params.rtcp={cname:transceiver.cname};if(transceiver.sendEncodingParameters.length){params.rtcp.ssrc=transceiver.sendEncodingParameters[0].ssrc;}
|
||||
transceiver.rtpReceiver.receive(params);}};window.RTCPeerConnection.prototype.setLocalDescription=function(description){var self=this;var sections;var sessionpart;if(description.type==='offer'){if(this._pendingOffer){sections=SDPUtils.splitSections(description.sdp);sessionpart=sections.shift();sections.forEach(function(mediaSection,sdpMLineIndex){var caps=SDPUtils.parseRtpParameters(mediaSection);self._pendingOffer[sdpMLineIndex].localCapabilities=caps;});this.transceivers=this._pendingOffer;delete this._pendingOffer;}}else if(description.type==='answer'){sections=SDPUtils.splitSections(self.remoteDescription.sdp);sessionpart=sections.shift();var isIceLite=SDPUtils.matchPrefix(sessionpart,'a=ice-lite').length>0;sections.forEach(function(mediaSection,sdpMLineIndex){var transceiver=self.transceivers[sdpMLineIndex];var iceGatherer=transceiver.iceGatherer;var iceTransport=transceiver.iceTransport;var dtlsTransport=transceiver.dtlsTransport;var localCapabilities=transceiver.localCapabilities;var remoteCapabilities=transceiver.remoteCapabilities;var rejected=mediaSection.split('\n',1)[0].split(' ',2)[1]==='0';if(!rejected){var remoteIceParameters=SDPUtils.getIceParameters(mediaSection,sessionpart);if(isIceLite){var cands=SDPUtils.matchPrefix(mediaSection,'a=candidate:').map(function(cand){return SDPUtils.parseCandidate(cand);}).filter(function(cand){return cand.component==='1';});if(cands.length){iceTransport.setRemoteCandidates(cands);}}
|
||||
var remoteDtlsParameters=SDPUtils.getDtlsParameters(mediaSection,sessionpart);if(isIceLite){remoteDtlsParameters.role='server';}
|
||||
if(!self.usingBundle||sdpMLineIndex===0){iceTransport.start(iceGatherer,remoteIceParameters,isIceLite?'controlling':'controlled');dtlsTransport.start(remoteDtlsParameters);}
|
||||
var params=self._getCommonCapabilities(localCapabilities,remoteCapabilities);self._transceive(transceiver,params.codecs.length>0,false);}});}
|
||||
this.localDescription={type:description.type,sdp:description.sdp};switch(description.type){case'offer':this._updateSignalingState('have-local-offer');break;case'answer':this._updateSignalingState('stable');break;default:throw new TypeError('unsupported type "'+description.type+'"');}
|
||||
var hasCallback=arguments.length>1&&typeof arguments[1]==='function';if(hasCallback){var cb=arguments[1];window.setTimeout(function(){cb();if(self.iceGatheringState==='new'){self.iceGatheringState='gathering';}
|
||||
self._emitBufferedCandidates();},0);}
|
||||
var p=Promise.resolve();p.then(function(){if(!hasCallback){if(self.iceGatheringState==='new'){self.iceGatheringState='gathering';}
|
||||
window.setTimeout(self._emitBufferedCandidates.bind(self),500);}});return p;};window.RTCPeerConnection.prototype.setRemoteDescription=function(description){var self=this;var stream=new MediaStream();var receiverList=[];var sections=SDPUtils.splitSections(description.sdp);var sessionpart=sections.shift();var isIceLite=SDPUtils.matchPrefix(sessionpart,'a=ice-lite').length>0;this.usingBundle=SDPUtils.matchPrefix(sessionpart,'a=group:BUNDLE ').length>0;sections.forEach(function(mediaSection,sdpMLineIndex){var lines=SDPUtils.splitLines(mediaSection);var mline=lines[0].substr(2).split(' ');var kind=mline[0];var rejected=mline[1]==='0';var direction=SDPUtils.getDirection(mediaSection,sessionpart);var transceiver;var iceGatherer;var iceTransport;var dtlsTransport;var rtpSender;var rtpReceiver;var sendEncodingParameters;var recvEncodingParameters;var localCapabilities;var track;var remoteCapabilities=SDPUtils.parseRtpParameters(mediaSection);var remoteIceParameters;var remoteDtlsParameters;if(!rejected){remoteIceParameters=SDPUtils.getIceParameters(mediaSection,sessionpart);remoteDtlsParameters=SDPUtils.getDtlsParameters(mediaSection,sessionpart);remoteDtlsParameters.role='client';}
|
||||
recvEncodingParameters=SDPUtils.parseRtpEncodingParameters(mediaSection);var mid=SDPUtils.matchPrefix(mediaSection,'a=mid:');if(mid.length){mid=mid[0].substr(6);}else{mid=SDPUtils.generateIdentifier();}
|
||||
var cname;var remoteSsrc=SDPUtils.matchPrefix(mediaSection,'a=ssrc:').map(function(line){return SDPUtils.parseSsrcMedia(line);}).filter(function(obj){return obj.attribute==='cname';})[0];if(remoteSsrc){cname=remoteSsrc.value;}
|
||||
var isComplete=SDPUtils.matchPrefix(mediaSection,'a=end-of-candidates',sessionpart).length>0;var cands=SDPUtils.matchPrefix(mediaSection,'a=candidate:').map(function(cand){return SDPUtils.parseCandidate(cand);}).filter(function(cand){return cand.component==='1';});if(description.type==='offer'&&!rejected){var transports=self.usingBundle&&sdpMLineIndex>0?{iceGatherer:self.transceivers[0].iceGatherer,iceTransport:self.transceivers[0].iceTransport,dtlsTransport:self.transceivers[0].dtlsTransport}:self._createIceAndDtlsTransports(mid,sdpMLineIndex);if(isComplete){transports.iceTransport.setRemoteCandidates(cands);}
|
||||
localCapabilities=RTCRtpReceiver.getCapabilities(kind);sendEncodingParameters=[{ssrc:(2*sdpMLineIndex+2)*1001}];rtpReceiver=new RTCRtpReceiver(transports.dtlsTransport,kind);track=rtpReceiver.track;receiverList.push([track,rtpReceiver]);stream.addTrack(track);if(self.localStreams.length>0&&self.localStreams[0].getTracks().length>=sdpMLineIndex){var localTrack;if(kind==='audio'){localTrack=self.localStreams[0].getAudioTracks()[0];}else if(kind==='video'){localTrack=self.localStreams[0].getVideoTracks()[0];}
|
||||
if(localTrack){rtpSender=new RTCRtpSender(localTrack,transports.dtlsTransport);}}
|
||||
self.transceivers[sdpMLineIndex]={iceGatherer:transports.iceGatherer,iceTransport:transports.iceTransport,dtlsTransport:transports.dtlsTransport,localCapabilities:localCapabilities,remoteCapabilities:remoteCapabilities,rtpSender:rtpSender,rtpReceiver:rtpReceiver,kind:kind,mid:mid,cname:cname,sendEncodingParameters:sendEncodingParameters,recvEncodingParameters:recvEncodingParameters};self._transceive(self.transceivers[sdpMLineIndex],false,direction==='sendrecv'||direction==='sendonly');}else if(description.type==='answer'&&!rejected){transceiver=self.transceivers[sdpMLineIndex];iceGatherer=transceiver.iceGatherer;iceTransport=transceiver.iceTransport;dtlsTransport=transceiver.dtlsTransport;rtpSender=transceiver.rtpSender;rtpReceiver=transceiver.rtpReceiver;sendEncodingParameters=transceiver.sendEncodingParameters;localCapabilities=transceiver.localCapabilities;self.transceivers[sdpMLineIndex].recvEncodingParameters=recvEncodingParameters;self.transceivers[sdpMLineIndex].remoteCapabilities=remoteCapabilities;self.transceivers[sdpMLineIndex].cname=cname;if((isIceLite||isComplete)&&cands.length){iceTransport.setRemoteCandidates(cands);}
|
||||
if(!self.usingBundle||sdpMLineIndex===0){iceTransport.start(iceGatherer,remoteIceParameters,'controlling');dtlsTransport.start(remoteDtlsParameters);}
|
||||
self._transceive(transceiver,direction==='sendrecv'||direction==='recvonly',direction==='sendrecv'||direction==='sendonly');if(rtpReceiver&&(direction==='sendrecv'||direction==='sendonly')){track=rtpReceiver.track;receiverList.push([track,rtpReceiver]);stream.addTrack(track);}else{delete transceiver.rtpReceiver;}}});this.remoteDescription={type:description.type,sdp:description.sdp};switch(description.type){case'offer':this._updateSignalingState('have-remote-offer');break;case'answer':this._updateSignalingState('stable');break;default:throw new TypeError('unsupported type "'+description.type+'"');}
|
||||
if(stream.getTracks().length){self.remoteStreams.push(stream);window.setTimeout(function(){var event=new Event('addstream');event.stream=stream;self.dispatchEvent(event);if(self.onaddstream!==null){window.setTimeout(function(){self.onaddstream(event);},0);}
|
||||
receiverList.forEach(function(item){var track=item[0];var receiver=item[1];var trackEvent=new Event('track');trackEvent.track=track;trackEvent.receiver=receiver;trackEvent.streams=[stream];self.dispatchEvent(event);if(self.ontrack!==null){window.setTimeout(function(){self.ontrack(trackEvent);},0);}});},0);}
|
||||
if(arguments.length>1&&typeof arguments[1]==='function'){window.setTimeout(arguments[1],0);}
|
||||
return Promise.resolve();};window.RTCPeerConnection.prototype.close=function(){this.transceivers.forEach(function(transceiver){if(transceiver.iceTransport){transceiver.iceTransport.stop();}
|
||||
if(transceiver.dtlsTransport){transceiver.dtlsTransport.stop();}
|
||||
if(transceiver.rtpSender){transceiver.rtpSender.stop();}
|
||||
if(transceiver.rtpReceiver){transceiver.rtpReceiver.stop();}});this._updateSignalingState('closed');};window.RTCPeerConnection.prototype._updateSignalingState=function(newState){this.signalingState=newState;var event=new Event('signalingstatechange');this.dispatchEvent(event);if(this.onsignalingstatechange!==null){this.onsignalingstatechange(event);}};window.RTCPeerConnection.prototype._maybeFireNegotiationNeeded=function(){var event=new Event('negotiationneeded');this.dispatchEvent(event);if(this.onnegotiationneeded!==null){this.onnegotiationneeded(event);}};window.RTCPeerConnection.prototype._updateConnectionState=function(){var self=this;var newState;var states={'new':0,closed:0,connecting:0,checking:0,connected:0,completed:0,failed:0};this.transceivers.forEach(function(transceiver){states[transceiver.iceTransport.state]++;states[transceiver.dtlsTransport.state]++;});states.connected+=states.completed;newState='new';if(states.failed>0){newState='failed';}else if(states.connecting>0||states.checking>0){newState='connecting';}else if(states.disconnected>0){newState='disconnected';}else if(states.new>0){newState='new';}else if(states.connected>0||states.completed>0){newState='connected';}
|
||||
if(newState!==self.iceConnectionState){self.iceConnectionState=newState;var event=new Event('iceconnectionstatechange');this.dispatchEvent(event);if(this.oniceconnectionstatechange!==null){this.oniceconnectionstatechange(event);}}};window.RTCPeerConnection.prototype.createOffer=function(){var self=this;if(this._pendingOffer){throw new Error('createOffer called while there is a pending offer.');}
|
||||
var offerOptions;if(arguments.length===1&&typeof arguments[0]!=='function'){offerOptions=arguments[0];}else if(arguments.length===3){offerOptions=arguments[2];}
|
||||
var tracks=[];var numAudioTracks=0;var numVideoTracks=0;if(this.localStreams.length){numAudioTracks=this.localStreams[0].getAudioTracks().length;numVideoTracks=this.localStreams[0].getVideoTracks().length;}
|
||||
if(offerOptions){if(offerOptions.mandatory||offerOptions.optional){throw new TypeError('Legacy mandatory/optional constraints not supported.');}
|
||||
if(offerOptions.offerToReceiveAudio!==undefined){numAudioTracks=offerOptions.offerToReceiveAudio;}
|
||||
if(offerOptions.offerToReceiveVideo!==undefined){numVideoTracks=offerOptions.offerToReceiveVideo;}}
|
||||
if(this.localStreams.length){this.localStreams[0].getTracks().forEach(function(track){tracks.push({kind:track.kind,track:track,wantReceive:track.kind==='audio'?numAudioTracks>0:numVideoTracks>0});if(track.kind==='audio'){numAudioTracks--;}else if(track.kind==='video'){numVideoTracks--;}});}
|
||||
while(numAudioTracks>0||numVideoTracks>0){if(numAudioTracks>0){tracks.push({kind:'audio',wantReceive:true});numAudioTracks--;}
|
||||
if(numVideoTracks>0){tracks.push({kind:'video',wantReceive:true});numVideoTracks--;}}
|
||||
var sdp=SDPUtils.writeSessionBoilerplate();var transceivers=[];tracks.forEach(function(mline,sdpMLineIndex){var track=mline.track;var kind=mline.kind;var mid=SDPUtils.generateIdentifier();var transports=self.usingBundle&&sdpMLineIndex>0?{iceGatherer:transceivers[0].iceGatherer,iceTransport:transceivers[0].iceTransport,dtlsTransport:transceivers[0].dtlsTransport}:self._createIceAndDtlsTransports(mid,sdpMLineIndex);var localCapabilities=RTCRtpSender.getCapabilities(kind);var rtpSender;var rtpReceiver;var sendEncodingParameters=[{ssrc:(2*sdpMLineIndex+1)*1001}];if(track){rtpSender=new RTCRtpSender(track,transports.dtlsTransport);}
|
||||
if(mline.wantReceive){rtpReceiver=new RTCRtpReceiver(transports.dtlsTransport,kind);}
|
||||
transceivers[sdpMLineIndex]={iceGatherer:transports.iceGatherer,iceTransport:transports.iceTransport,dtlsTransport:transports.dtlsTransport,localCapabilities:localCapabilities,remoteCapabilities:null,rtpSender:rtpSender,rtpReceiver:rtpReceiver,kind:kind,mid:mid,sendEncodingParameters:sendEncodingParameters,recvEncodingParameters:null};});if(this.usingBundle){sdp+='a=group:BUNDLE '+transceivers.map(function(t){return t.mid;}).join(' ')+'\r\n';}
|
||||
tracks.forEach(function(mline,sdpMLineIndex){var transceiver=transceivers[sdpMLineIndex];sdp+=SDPUtils.writeMediaSection(transceiver,transceiver.localCapabilities,'offer',self.localStreams[0]);});this._pendingOffer=transceivers;var desc=new RTCSessionDescription({type:'offer',sdp:sdp});if(arguments.length&&typeof arguments[0]==='function'){window.setTimeout(arguments[0],0,desc);}
|
||||
return Promise.resolve(desc);};window.RTCPeerConnection.prototype.createAnswer=function(){var self=this;var sdp=SDPUtils.writeSessionBoilerplate();if(this.usingBundle){sdp+='a=group:BUNDLE '+this.transceivers.map(function(t){return t.mid;}).join(' ')+'\r\n';}
|
||||
this.transceivers.forEach(function(transceiver){var commonCapabilities=self._getCommonCapabilities(transceiver.localCapabilities,transceiver.remoteCapabilities);sdp+=SDPUtils.writeMediaSection(transceiver,commonCapabilities,'answer',self.localStreams[0]);});var desc=new RTCSessionDescription({type:'answer',sdp:sdp});if(arguments.length&&typeof arguments[0]==='function'){window.setTimeout(arguments[0],0,desc);}
|
||||
return Promise.resolve(desc);};window.RTCPeerConnection.prototype.addIceCandidate=function(candidate){if(candidate===null){this.transceivers.forEach(function(transceiver){transceiver.iceTransport.addRemoteCandidate({});});}else{var mLineIndex=candidate.sdpMLineIndex;if(candidate.sdpMid){for(var i=0;i<this.transceivers.length;i++){if(this.transceivers[i].mid===candidate.sdpMid){mLineIndex=i;break;}}}
|
||||
var transceiver=this.transceivers[mLineIndex];if(transceiver){var cand=Object.keys(candidate.candidate).length>0?SDPUtils.parseCandidate(candidate.candidate):{};if(cand.protocol==='tcp'&&(cand.port===0||cand.port===9)){return;}
|
||||
if(cand.component!=='1'){return;}
|
||||
if(cand.type==='endOfCandidates'){cand={};}
|
||||
transceiver.iceTransport.addRemoteCandidate(cand);var sections=SDPUtils.splitSections(this.remoteDescription.sdp);sections[mLineIndex+1]+=(cand.type?candidate.candidate.trim():'a=end-of-candidates')+'\r\n';this.remoteDescription.sdp=sections.join('');}}
|
||||
if(arguments.length>1&&typeof arguments[1]==='function'){window.setTimeout(arguments[1],0);}
|
||||
return Promise.resolve();};window.RTCPeerConnection.prototype.getStats=function(){var promises=[];this.transceivers.forEach(function(transceiver){['rtpSender','rtpReceiver','iceGatherer','iceTransport','dtlsTransport'].forEach(function(method){if(transceiver[method]){promises.push(transceiver[method].getStats());}});});var cb=arguments.length>1&&typeof arguments[1]==='function'&&arguments[1];return new Promise(function(resolve){var results=new Map();Promise.all(promises).then(function(res){res.forEach(function(result){Object.keys(result).forEach(function(id){results.set(id,result[id]);results[id]=result[id];});});if(cb){window.setTimeout(cb,0,results);}
|
||||
resolve(results);});});};}};module.exports={shimPeerConnection:edgeShim.shimPeerConnection,shimGetUserMedia:require('./getusermedia')};},{"./getusermedia":6,"sdp":1}],6:[function(require,module,exports){'use strict';module.exports=function(){var shimError_=function(e){return{name:{PermissionDeniedError:'NotAllowedError'}[e.name]||e.name,message:e.message,constraint:e.constraint,toString:function(){return this.name;}};};var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(c){return origGetUserMedia(c).catch(function(e){return Promise.reject(shimError_(e));});};};},{}],7:[function(require,module,exports){'use strict';var browserDetails=require('../utils').browserDetails;var firefoxShim={shimOnTrack:function(){if(typeof window==='object'&&window.RTCPeerConnection&&!('ontrack'in
|
||||
window.RTCPeerConnection.prototype)){Object.defineProperty(window.RTCPeerConnection.prototype,'ontrack',{get:function(){return this._ontrack;},set:function(f){if(this._ontrack){this.removeEventListener('track',this._ontrack);this.removeEventListener('addstream',this._ontrackpoly);}
|
||||
this.addEventListener('track',this._ontrack=f);this.addEventListener('addstream',this._ontrackpoly=function(e){e.stream.getTracks().forEach(function(track){var event=new Event('track');event.track=track;event.receiver={track:track};event.streams=[e.stream];this.dispatchEvent(event);}.bind(this));}.bind(this));}});}},shimSourceObject:function(){if(typeof window==='object'){if(window.HTMLMediaElement&&!('srcObject'in window.HTMLMediaElement.prototype)){Object.defineProperty(window.HTMLMediaElement.prototype,'srcObject',{get:function(){return this.mozSrcObject;},set:function(stream){this.mozSrcObject=stream;}});}}},shimPeerConnection:function(){if(typeof window!=='object'||!(window.RTCPeerConnection||window.mozRTCPeerConnection)){return;}
|
||||
if(!window.RTCPeerConnection){window.RTCPeerConnection=function(pcConfig,pcConstraints){if(browserDetails.version<38){if(pcConfig&&pcConfig.iceServers){var newIceServers=[];for(var i=0;i<pcConfig.iceServers.length;i++){var server=pcConfig.iceServers[i];if(server.hasOwnProperty('urls')){for(var j=0;j<server.urls.length;j++){var newServer={url:server.urls[j]};if(server.urls[j].indexOf('turn')===0){newServer.username=server.username;newServer.credential=server.credential;}
|
||||
newIceServers.push(newServer);}}else{newIceServers.push(pcConfig.iceServers[i]);}}
|
||||
pcConfig.iceServers=newIceServers;}}
|
||||
return new mozRTCPeerConnection(pcConfig,pcConstraints);};window.RTCPeerConnection.prototype=mozRTCPeerConnection.prototype;if(mozRTCPeerConnection.generateCertificate){Object.defineProperty(window.RTCPeerConnection,'generateCertificate',{get:function(){return mozRTCPeerConnection.generateCertificate;}});}
|
||||
window.RTCSessionDescription=mozRTCSessionDescription;window.RTCIceCandidate=mozRTCIceCandidate;}
|
||||
['setLocalDescription','setRemoteDescription','addIceCandidate'].forEach(function(method){var nativeMethod=RTCPeerConnection.prototype[method];RTCPeerConnection.prototype[method]=function(){arguments[0]=new((method==='addIceCandidate')?RTCIceCandidate:RTCSessionDescription)(arguments[0]);return nativeMethod.apply(this,arguments);};});var nativeAddIceCandidate=RTCPeerConnection.prototype.addIceCandidate;RTCPeerConnection.prototype.addIceCandidate=function(){return arguments[0]===null?Promise.resolve():nativeAddIceCandidate.apply(this,arguments);};var makeMapStats=function(stats){var map=new Map();Object.keys(stats).forEach(function(key){map.set(key,stats[key]);map[key]=stats[key];});return map;};var nativeGetStats=RTCPeerConnection.prototype.getStats;RTCPeerConnection.prototype.getStats=function(selector,onSucc,onErr){return nativeGetStats.apply(this,[selector||null]).then(function(stats){return makeMapStats(stats);}).then(onSucc,onErr);};}};module.exports={shimOnTrack:firefoxShim.shimOnTrack,shimSourceObject:firefoxShim.shimSourceObject,shimPeerConnection:firefoxShim.shimPeerConnection,shimGetUserMedia:require('./getusermedia')};},{"../utils":10,"./getusermedia":8}],8:[function(require,module,exports){'use strict';var logging=require('../utils').log;var browserDetails=require('../utils').browserDetails;module.exports=function(){var shimError_=function(e){return{name:{SecurityError:'NotAllowedError',PermissionDeniedError:'NotAllowedError'}[e.name]||e.name,message:{'The operation is insecure.':'The request is not allowed by the '+'user agent or the platform in the current context.'}[e.message]||e.message,constraint:e.constraint,toString:function(){return this.name+(this.message&&': ')+this.message;}};};var getUserMedia_=function(constraints,onSuccess,onError){var constraintsToFF37_=function(c){if(typeof c!=='object'||c.require){return c;}
|
||||
var require=[];Object.keys(c).forEach(function(key){if(key==='require'||key==='advanced'||key==='mediaSource'){return;}
|
||||
var r=c[key]=(typeof c[key]==='object')?c[key]:{ideal:c[key]};if(r.min!==undefined||r.max!==undefined||r.exact!==undefined){require.push(key);}
|
||||
if(r.exact!==undefined){if(typeof r.exact==='number'){r.min=r.max=r.exact;}else{c[key]=r.exact;}
|
||||
delete r.exact;}
|
||||
if(r.ideal!==undefined){c.advanced=c.advanced||[];var oc={};if(typeof r.ideal==='number'){oc[key]={min:r.ideal,max:r.ideal};}else{oc[key]=r.ideal;}
|
||||
c.advanced.push(oc);delete r.ideal;if(!Object.keys(r).length){delete c[key];}}});if(require.length){c.require=require;}
|
||||
return c;};constraints=JSON.parse(JSON.stringify(constraints));if(browserDetails.version<38){logging('spec: '+JSON.stringify(constraints));if(constraints.audio){constraints.audio=constraintsToFF37_(constraints.audio);}
|
||||
if(constraints.video){constraints.video=constraintsToFF37_(constraints.video);}
|
||||
logging('ff37: '+JSON.stringify(constraints));}
|
||||
return navigator.mozGetUserMedia(constraints,onSuccess,function(e){onError(shimError_(e));});};var getUserMediaPromise_=function(constraints){return new Promise(function(resolve,reject){getUserMedia_(constraints,resolve,reject);});};if(!navigator.mediaDevices){navigator.mediaDevices={getUserMedia:getUserMediaPromise_,addEventListener:function(){},removeEventListener:function(){}};}
|
||||
navigator.mediaDevices.enumerateDevices=navigator.mediaDevices.enumerateDevices||function(){return new Promise(function(resolve){var infos=[{kind:'audioinput',deviceId:'default',label:'',groupId:''},{kind:'videoinput',deviceId:'default',label:'',groupId:''}];resolve(infos);});};if(browserDetails.version<41){var orgEnumerateDevices=navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices);navigator.mediaDevices.enumerateDevices=function(){return orgEnumerateDevices().then(undefined,function(e){if(e.name==='NotFoundError'){return[];}
|
||||
throw e;});};}
|
||||
if(browserDetails.version<49){var origGetUserMedia=navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);navigator.mediaDevices.getUserMedia=function(c){return origGetUserMedia(c).catch(function(e){return Promise.reject(shimError_(e));});};}
|
||||
navigator.getUserMedia=function(constraints,onSuccess,onError){if(browserDetails.version<44){return getUserMedia_(constraints,onSuccess,onError);}
|
||||
console.warn('navigator.getUserMedia has been replaced by '+'navigator.mediaDevices.getUserMedia');navigator.mediaDevices.getUserMedia(constraints).then(onSuccess,onError);};};},{"../utils":10}],9:[function(require,module,exports){'use strict';var safariShim={shimGetUserMedia:function(){navigator.getUserMedia=navigator.webkitGetUserMedia;}};module.exports={shimGetUserMedia:safariShim.shimGetUserMedia};},{}],10:[function(require,module,exports){'use strict';var logDisabled_=true;var utils={disableLog:function(bool){if(typeof bool!=='boolean'){return new Error('Argument type: '+typeof bool+'. Please use a boolean.');}
|
||||
logDisabled_=bool;return(bool)?'adapter.js logging disabled':'adapter.js logging enabled';},log:function(){if(typeof window==='object'){if(logDisabled_){return;}
|
||||
if(typeof console!=='undefined'&&typeof console.log==='function'){console.log.apply(console,arguments);}}},extractVersion:function(uastring,expr,pos){var match=uastring.match(expr);return match&&match.length>=pos&&parseInt(match[pos],10);},detectBrowser:function(){var result={};result.browser=null;result.version=null;if(typeof window==='undefined'||!window.navigator){result.browser='Not a browser.';return result;}
|
||||
if(navigator.mozGetUserMedia){result.browser='firefox';result.version=this.extractVersion(navigator.userAgent,/Firefox\/([0-9]+)\./,1);}else if(navigator.webkitGetUserMedia){if(window.webkitRTCPeerConnection){result.browser='chrome';result.version=this.extractVersion(navigator.userAgent,/Chrom(e|ium)\/([0-9]+)\./,2);}else{if(navigator.userAgent.match(/Version\/(\d+).(\d+)/)){result.browser='safari';result.version=this.extractVersion(navigator.userAgent,/AppleWebKit\/([0-9]+)\./,1);}else{result.browser='Unsupported webkit-based browser '+'with GUM support but no WebRTC support.';return result;}}}else if(navigator.mediaDevices&&navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)){result.browser='edge';result.version=this.extractVersion(navigator.userAgent,/Edge\/(\d+).(\d+)$/,2);}else{result.browser='Not a supported browser.';return result;}
|
||||
return result;}};module.exports={log:utils.log,disableLog:utils.disableLog,browserDetails:utils.detectBrowser(),extractVersion:utils.extractVersion};},{}]},{},[2])(2)});AdapterJS.parseWebrtcDetectedBrowser();if(navigator.mozGetUserMedia){MediaStreamTrack.getSources=function(successCb){setTimeout(function(){var infos=[{kind:'audio',id:'default',label:'',facing:''},{kind:'video',id:'default',label:'',facing:''}];successCb(infos);},0);};createIceServer=function(url,username,password){console.warn('createIceServer is deprecated. It should be replaced with an application level implementation.');var iceServer=null;var urlParts=url.split(':');if(urlParts[0].indexOf('stun')===0){iceServer={urls:[url]};}else if(urlParts[0].indexOf('turn')===0){if(webrtcDetectedVersion<27){var turnUrlParts=url.split('?');if(turnUrlParts.length===1||turnUrlParts[1].indexOf('transport=udp')===0){iceServer={urls:[turnUrlParts[0]],credential:password,username:username};}}else{iceServer={urls:[url],credential:password,username:username};}}
|
||||
return iceServer;};createIceServers=function(urls,username,password){console.warn('createIceServers is deprecated. It should be replaced with an application level implementation.');var iceServers=[];for(i=0;i<urls.length;i++){var iceServer=createIceServer(urls[i],username,password);if(iceServer!==null){iceServers.push(iceServer);}}
|
||||
return iceServers;};}else if(navigator.webkitGetUserMedia){createIceServer=function(url,username,password){console.warn('createIceServer is deprecated. It should be replaced with an application level implementation.');var iceServer=null;var urlParts=url.split(':');if(urlParts[0].indexOf('stun')===0){iceServer={'url':url};}else if(urlParts[0].indexOf('turn')===0){iceServer={'url':url,'credential':password,'username':username};}
|
||||
return iceServer;};createIceServers=function(urls,username,password){console.warn('createIceServers is deprecated. It should be replaced with an application level implementation.');var iceServers=[];if(webrtcDetectedVersion>=34){iceServers={'urls':urls,'credential':password,'username':username};}else{for(i=0;i<urls.length;i++){var iceServer=createIceServer(urls[i],username,password);if(iceServer!==null){iceServers.push(iceServer);}}}
|
||||
return iceServers;};}
|
||||
if(navigator.mediaDevices&&navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)){getUserMedia=window.getUserMedia=navigator.getUserMedia.bind(navigator);attachMediaStream=function(element,stream){element.srcObject=stream;return element;};reattachMediaStream=function(to,from){to.srcObject=from.srcObject;return to;};}
|
||||
if(attachMediaStream){attachMediaStream_base=attachMediaStream;attachMediaStream=function(element,stream){if((webrtcDetectedBrowser==='chrome'||webrtcDetectedBrowser==='opera')&&!stream){element.src='';}else{attachMediaStream_base(element,stream);}
|
||||
return element;};}
|
||||
if(reattachMediaStream){reattachMediaStream_base=reattachMediaStream;reattachMediaStream=function(to,from){reattachMediaStream_base(to,from);return to;};}
|
||||
window.attachMediaStream=attachMediaStream;window.reattachMediaStream=reattachMediaStream;window.getUserMedia=getUserMedia;AdapterJS.attachMediaStream=attachMediaStream;AdapterJS.reattachMediaStream=reattachMediaStream;AdapterJS.getUserMedia=getUserMedia;if(typeof Promise==='undefined'){requestUserMedia=null;}
|
||||
AdapterJS.maybeThroughWebRTCReady();}else{if(typeof console!=='object'||typeof console.log!=='function'){console={}||console;console.log=function(arg){};console.info=function(arg){};console.error=function(arg){};console.dir=function(arg){};console.exception=function(arg){};console.trace=function(arg){};console.warn=function(arg){};console.count=function(arg){};console.debug=function(arg){};console.count=function(arg){};console.time=function(arg){};console.timeEnd=function(arg){};console.group=function(arg){};console.groupCollapsed=function(arg){};console.groupEnd=function(arg){};}
|
||||
AdapterJS.parseWebrtcDetectedBrowser();isIE=webrtcDetectedBrowser==='IE';AdapterJS.WebRTCPlugin.WaitForPluginReady=function(){while(AdapterJS.WebRTCPlugin.pluginState!==AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY){}};AdapterJS.WebRTCPlugin.callWhenPluginReady=function(callback){if(AdapterJS.WebRTCPlugin.pluginState===AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY){callback();}else{var checkPluginReadyState=setInterval(function(){if(AdapterJS.WebRTCPlugin.pluginState===AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY){clearInterval(checkPluginReadyState);callback();}},100);}};AdapterJS.WebRTCPlugin.setLogLevel=function(logLevel){AdapterJS.WebRTCPlugin.callWhenPluginReady(function(){AdapterJS.WebRTCPlugin.plugin.setLogLevel(logLevel);});};AdapterJS.WebRTCPlugin.injectPlugin=function(){if(document.readyState!=='complete'){return;}
|
||||
if(AdapterJS.WebRTCPlugin.pluginState!==AdapterJS.WebRTCPlugin.PLUGIN_STATES.INITIALIZING){return;}
|
||||
AdapterJS.WebRTCPlugin.pluginState=AdapterJS.WebRTCPlugin.PLUGIN_STATES.INJECTING;if(webrtcDetectedBrowser==='IE'&&webrtcDetectedVersion<=10){var frag=document.createDocumentFragment();AdapterJS.WebRTCPlugin.plugin=document.createElement('div');AdapterJS.WebRTCPlugin.plugin.innerHTML='<object id="'+
|
||||
AdapterJS.WebRTCPlugin.pluginInfo.pluginId+'" type="'+
|
||||
AdapterJS.WebRTCPlugin.pluginInfo.type+'" '+'width="1" height="1">'+'<param name="pluginId" value="'+
|
||||
AdapterJS.WebRTCPlugin.pluginInfo.pluginId+'" /> '+'<param name="windowless" value="false" /> '+'<param name="pageId" value="'+AdapterJS.WebRTCPlugin.pageId+'" /> '+'<param name="onload" value="'+AdapterJS.WebRTCPlugin.pluginInfo.onload+'" />'+'<param name="tag" value="'+AdapterJS.WebRTCPlugin.TAGS.NONE+'" />'+
|
||||
(AdapterJS.options.getAllCams?'<param name="forceGetAllCams" value="True" />':'')+'</object>';while(AdapterJS.WebRTCPlugin.plugin.firstChild){frag.appendChild(AdapterJS.WebRTCPlugin.plugin.firstChild);}
|
||||
document.body.appendChild(frag);AdapterJS.WebRTCPlugin.plugin=document.getElementById(AdapterJS.WebRTCPlugin.pluginInfo.pluginId);}else{AdapterJS.WebRTCPlugin.plugin=document.createElement('object');AdapterJS.WebRTCPlugin.plugin.id=AdapterJS.WebRTCPlugin.pluginInfo.pluginId;if(isIE){AdapterJS.WebRTCPlugin.plugin.width='1px';AdapterJS.WebRTCPlugin.plugin.height='1px';}else{AdapterJS.WebRTCPlugin.plugin.width='0px';AdapterJS.WebRTCPlugin.plugin.height='0px';}
|
||||
AdapterJS.WebRTCPlugin.plugin.type=AdapterJS.WebRTCPlugin.pluginInfo.type;AdapterJS.WebRTCPlugin.plugin.innerHTML='<param name="onload" value="'+
|
||||
AdapterJS.WebRTCPlugin.pluginInfo.onload+'">'+'<param name="pluginId" value="'+
|
||||
AdapterJS.WebRTCPlugin.pluginInfo.pluginId+'">'+'<param name="windowless" value="false" /> '+
|
||||
(AdapterJS.options.getAllCams?'<param name="forceGetAllCams" value="True" />':'')+'<param name="pageId" value="'+AdapterJS.WebRTCPlugin.pageId+'">'+'<param name="tag" value="'+AdapterJS.WebRTCPlugin.TAGS.NONE+'" />';document.body.appendChild(AdapterJS.WebRTCPlugin.plugin);}
|
||||
AdapterJS.WebRTCPlugin.pluginState=AdapterJS.WebRTCPlugin.PLUGIN_STATES.INJECTED;};AdapterJS.WebRTCPlugin.isPluginInstalled=function(comName,plugName,installedCb,notInstalledCb){if(!isIE){var pluginArray=navigator.plugins;for(var i=0;i<pluginArray.length;i++){if(pluginArray[i].name.indexOf(plugName)>=0){installedCb();return;}}
|
||||
notInstalledCb();}else{try{var axo=new ActiveXObject(comName+'.'+plugName);}catch(e){notInstalledCb();return;}
|
||||
installedCb();}};AdapterJS.WebRTCPlugin.defineWebRTCInterface=function(){if(AdapterJS.WebRTCPlugin.pluginState===AdapterJS.WebRTCPlugin.PLUGIN_STATES.READY){console.error('AdapterJS - WebRTC interface has already been defined');return;}
|
||||
AdapterJS.WebRTCPlugin.pluginState=AdapterJS.WebRTCPlugin.PLUGIN_STATES.INITIALIZING;AdapterJS.isDefined=function(variable){return variable!==null&&variable!==undefined;};createIceServer=function(url,username,password){var iceServer=null;var urlParts=url.split(':');if(urlParts[0].indexOf('stun')===0){iceServer={'url':url,'hasCredentials':false};}else if(urlParts[0].indexOf('turn')===0){iceServer={'url':url,'hasCredentials':true,'credential':password,'username':username};}
|
||||
return iceServer;};createIceServers=function(urls,username,password){var iceServers=[];for(var i=0;i<urls.length;++i){iceServers.push(createIceServer(urls[i],username,password));}
|
||||
return iceServers;};RTCSessionDescription=function(info){AdapterJS.WebRTCPlugin.WaitForPluginReady();return AdapterJS.WebRTCPlugin.plugin.ConstructSessionDescription(info.type,info.sdp);};RTCPeerConnection=function(servers,constraints){if(!(servers===undefined||servers===null||Array.isArray(servers.iceServers))){throw new Error('Failed to construct \'RTCPeerConnection\': Malformed RTCConfiguration');}
|
||||
if(typeof constraints!=='undefined'&&constraints!==null){var invalidConstraits=false;invalidConstraits|=typeof constraints!=='object';invalidConstraits|=constraints.hasOwnProperty('mandatory')&&constraints.mandatory!==undefined&&constraints.mandatory!==null&&constraints.mandatory.constructor!==Object;invalidConstraits|=constraints.hasOwnProperty('optional')&&constraints.optional!==undefined&&constraints.optional!==null&&!Array.isArray(constraints.optional);if(invalidConstraits){throw new Error('Failed to construct \'RTCPeerConnection\': Malformed constraints object');}}
|
||||
AdapterJS.WebRTCPlugin.WaitForPluginReady();var iceServers=null;if(servers&&Array.isArray(servers.iceServers)){iceServers=servers.iceServers;for(var i=0;i<iceServers.length;i++){if(iceServers[i].urls&&!iceServers[i].url){iceServers[i].url=iceServers[i].urls;}
|
||||
iceServers[i].hasCredentials=AdapterJS.isDefined(iceServers[i].username)&&AdapterJS.isDefined(iceServers[i].credential);}}
|
||||
if(AdapterJS.WebRTCPlugin.plugin.PEER_CONNECTION_VERSION&&AdapterJS.WebRTCPlugin.plugin.PEER_CONNECTION_VERSION>1){if(iceServers){servers.iceServers=iceServers;}
|
||||
return AdapterJS.WebRTCPlugin.plugin.PeerConnection(servers);}else{var mandatory=(constraints&&constraints.mandatory)?constraints.mandatory:null;var optional=(constraints&&constraints.optional)?constraints.optional:null;return AdapterJS.WebRTCPlugin.plugin.PeerConnection(AdapterJS.WebRTCPlugin.pageId,iceServers,mandatory,optional);}};MediaStreamTrack=function(){};MediaStreamTrack.getSources=function(callback){AdapterJS.WebRTCPlugin.callWhenPluginReady(function(){AdapterJS.WebRTCPlugin.plugin.GetSources(callback);});};getUserMedia=function(constraints,successCallback,failureCallback){constraints.audio=constraints.audio||false;constraints.video=constraints.video||false;AdapterJS.WebRTCPlugin.callWhenPluginReady(function(){AdapterJS.WebRTCPlugin.plugin.getUserMedia(constraints,successCallback,failureCallback);});};window.navigator.getUserMedia=getUserMedia;if(!navigator.mediaDevices&&typeof Promise!=='undefined'){requestUserMedia=function(constraints){return new Promise(function(resolve,reject){getUserMedia(constraints,resolve,reject);});};navigator.mediaDevices={getUserMedia:requestUserMedia,enumerateDevices:function(){return new Promise(function(resolve){var kinds={audio:'audioinput',video:'videoinput'};return MediaStreamTrack.getSources(function(devices){resolve(devices.map(function(device){return{label:device.label,kind:kinds[device.kind],id:device.id,deviceId:device.id,groupId:''};}));});});}};}
|
||||
attachMediaStream=function(element,stream){if(!element||!element.parentNode){return;}
|
||||
var streamId;if(stream===null){streamId='';}else{if(typeof stream.enableSoundTracks!=='undefined'){stream.enableSoundTracks(true);}
|
||||
streamId=stream.id;}
|
||||
var elementId=element.id.length===0?Math.random().toString(36).slice(2):element.id;var nodeName=element.nodeName.toLowerCase();if(nodeName!=='object'){var tag;switch(nodeName){case'audio':tag=AdapterJS.WebRTCPlugin.TAGS.AUDIO;break;case'video':tag=AdapterJS.WebRTCPlugin.TAGS.VIDEO;break;default:tag=AdapterJS.WebRTCPlugin.TAGS.NONE;}
|
||||
var frag=document.createDocumentFragment();var temp=document.createElement('div');var classHTML='';if(element.className){classHTML='class="'+element.className+'" ';}else if(element.attributes&&element.attributes['class']){classHTML='class="'+element.attributes['class'].value+'" ';}
|
||||
temp.innerHTML='<object id="'+elementId+'" '+classHTML+'type="'+AdapterJS.WebRTCPlugin.pluginInfo.type+'">'+'<param name="pluginId" value="'+elementId+'" /> '+'<param name="pageId" value="'+AdapterJS.WebRTCPlugin.pageId+'" /> '+'<param name="windowless" value="true" /> '+'<param name="streamId" value="'+streamId+'" /> '+'<param name="tag" value="'+tag+'" /> '+'</object>';while(temp.firstChild){frag.appendChild(temp.firstChild);}
|
||||
var height='';var width='';if(element.clientWidth||element.clientHeight){width=element.clientWidth;height=element.clientHeight;}
|
||||
else if(element.width||element.height){width=element.width;height=element.height;}
|
||||
element.parentNode.insertBefore(frag,element);frag=document.getElementById(elementId);frag.width=width;frag.height=height;element.parentNode.removeChild(element);}else{var children=element.children;for(var i=0;i!==children.length;++i){if(children[i].name==='streamId'){children[i].value=streamId;break;}}
|
||||
element.setStreamId(streamId);}
|
||||
var newElement=document.getElementById(elementId);AdapterJS.forwardEventHandlers(newElement,element,Object.getPrototypeOf(element));return newElement;};reattachMediaStream=function(to,from){var stream=null;var children=from.children;for(var i=0;i!==children.length;++i){if(children[i].name==='streamId'){AdapterJS.WebRTCPlugin.WaitForPluginReady();stream=AdapterJS.WebRTCPlugin.plugin.getStreamWithId(AdapterJS.WebRTCPlugin.pageId,children[i].value);break;}}
|
||||
if(stream!==null){return attachMediaStream(to,stream);}else{console.log('Could not find the stream associated with this element');}};window.attachMediaStream=attachMediaStream;window.reattachMediaStream=reattachMediaStream;window.getUserMedia=getUserMedia;AdapterJS.attachMediaStream=attachMediaStream;AdapterJS.reattachMediaStream=reattachMediaStream;AdapterJS.getUserMedia=getUserMedia;AdapterJS.forwardEventHandlers=function(destElem,srcElem,prototype){properties=Object.getOwnPropertyNames(prototype);for(var prop in properties){if(prop){propName=properties[prop];if(typeof propName.slice==='function'&&propName.slice(0,2)==='on'&&typeof srcElem[propName]==='function'){AdapterJS.addEvent(destElem,propName.slice(2),srcElem[propName]);}}}
|
||||
var subPrototype=Object.getPrototypeOf(prototype);if(!!subPrototype){AdapterJS.forwardEventHandlers(destElem,srcElem,subPrototype);}};RTCIceCandidate=function(candidate){if(!candidate.sdpMid){candidate.sdpMid='';}
|
||||
AdapterJS.WebRTCPlugin.WaitForPluginReady();return AdapterJS.WebRTCPlugin.plugin.ConstructIceCandidate(candidate.sdpMid,candidate.sdpMLineIndex,candidate.candidate);};AdapterJS.addEvent(document,'readystatechange',AdapterJS.WebRTCPlugin.injectPlugin);AdapterJS.WebRTCPlugin.injectPlugin();};AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCb=AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCb||function(){AdapterJS.addEvent(document,'readystatechange',AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCbPriv);AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCbPriv();};AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCbPriv=function(){if(AdapterJS.options.hidePluginInstallPrompt){return;}
|
||||
var downloadLink=AdapterJS.WebRTCPlugin.pluginInfo.downloadLink;if(downloadLink){var popupString;if(AdapterJS.WebRTCPlugin.pluginInfo.portalLink){popupString='This website requires you to install the '+' <a href="'+AdapterJS.WebRTCPlugin.pluginInfo.portalLink+'" target="_blank">'+AdapterJS.WebRTCPlugin.pluginInfo.companyName+' WebRTC Plugin</a>'+' to work on this browser.';}else{popupString=AdapterJS.TEXT.PLUGIN.REQUIRE_INSTALLATION;}
|
||||
AdapterJS.renderNotificationBar(popupString,AdapterJS.TEXT.PLUGIN.BUTTON,downloadLink);}else{AdapterJS.renderNotificationBar(AdapterJS.TEXT.PLUGIN.NOT_SUPPORTED);}};AdapterJS.WebRTCPlugin.isPluginInstalled(AdapterJS.WebRTCPlugin.pluginInfo.prefix,AdapterJS.WebRTCPlugin.pluginInfo.plugName,AdapterJS.WebRTCPlugin.defineWebRTCInterface,AdapterJS.WebRTCPlugin.pluginNeededButNotInstalledCb);}
|
|
@ -101,14 +101,14 @@ function full_screen(name) {
|
|||
}
|
||||
|
||||
$("#" + video_screen).resize(function(e) {
|
||||
console.log("video size changed to " + $("#" + video_screen).width() + "x" + $("#" + video_screen).height());
|
||||
//console.log("video size changed to " + $("#" + video_screen).width() + "x" + $("#" + video_screen).height());
|
||||
|
||||
if ($("#" + video_screen).width() > $(window).width()) {
|
||||
//if ($("#" + video_screen).width() > $(window).width()) {
|
||||
//resize(false);
|
||||
$("#" + video_screen).width("100%");
|
||||
$("#" + video_screen).height("100%");
|
||||
}
|
||||
|
||||
//$("#" + video_screen).width("100%");
|
||||
//$("#" + video_screen).height("100%");
|
||||
//}
|
||||
real_size();
|
||||
});
|
||||
|
||||
|
||||
|
@ -128,13 +128,41 @@ function resize(up) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
$( window ).resize(function() {
|
||||
real_size();
|
||||
});
|
||||
|
||||
function real_size() {
|
||||
|
||||
|
||||
|
||||
$("#" + video_screen).width("");
|
||||
$("#" + video_screen).height("");
|
||||
/* temasys hack */
|
||||
setTimeout(function() {
|
||||
$("#" + video_screen).width("");
|
||||
$("#" + video_screen).height("");
|
||||
|
||||
var w = $("#" + video_screen).width();
|
||||
var h = $("#" + video_screen).height();
|
||||
|
||||
var new_w;
|
||||
var new_h;
|
||||
var aspect = 1920 / 1080; /*temasys doesn't provide video width hack aspect to wide screen*/
|
||||
|
||||
if (w > h) {
|
||||
new_w = window.innerWidth;
|
||||
new_h = Math.round(window.innerWidth / aspect);
|
||||
} else {
|
||||
new_h = window.innerHeight;
|
||||
new_w = Math.round(window.innerHeight / aspect);
|
||||
}
|
||||
|
||||
$("#" + video_screen).width(new_w);
|
||||
$("#" + video_screen).height(new_h);
|
||||
}, 500);
|
||||
|
||||
console.log("video size changed to fit screen");
|
||||
|
||||
console.log("video size changed to natural default");
|
||||
|
||||
}
|
||||
|
||||
|
@ -202,8 +230,19 @@ function check_vid() {
|
|||
return use_vid;
|
||||
}
|
||||
|
||||
var DISABLE_SPEED_TEST = true;
|
||||
|
||||
function do_speed_test(fn)
|
||||
{
|
||||
|
||||
|
||||
if (DISABLE_SPEED_TEST) {
|
||||
if (fn) {
|
||||
fn();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
goto_page("bwtest");
|
||||
|
||||
vertoHandle.rpcClient.speedTest(1024 * 256, function(e, obj) {
|
||||
|
@ -403,41 +442,67 @@ var callbacks = {
|
|||
}
|
||||
break;
|
||||
case $.verto.enum.message.info:
|
||||
var body = data.body;
|
||||
|
||||
if (data.msg) {
|
||||
data = data.msg;
|
||||
var body = data.body;
|
||||
|
||||
/*
|
||||
// This section has been replaced with messageTextToJQ function
|
||||
|
||||
if (body.match(/\.gif|\.jpg|\.jpeg|\.png/)) {
|
||||
if (body.match(/\.gif|\.jpg|\.jpeg|\.png/)) {
|
||||
var mod = "";
|
||||
if (body.match(/dropbox.com/)) {
|
||||
mod = "?dl=1";
|
||||
mod = "?dl=1";
|
||||
}
|
||||
body = body.replace(/(http[s]{0,1}:\/\/\S+)/g, "<a target='_blank' href='$1'>$1<br><img border='0' class='chatimg' src='$1'" + mod + "><\/a>");
|
||||
} else {
|
||||
} else {
|
||||
body = body.replace(/(http[s]{0,1}:\/\/\S+)/g, "<a target='_blank' href='$1'>$1<\/a>");
|
||||
}
|
||||
}
|
||||
|
||||
if (body.slice(-1) !== "\n") {
|
||||
if (body.slice(-1) !== "\n") {
|
||||
body += "\n";
|
||||
}
|
||||
body = body.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
|
||||
var from = data.from_msg_name || data.from;
|
||||
}
|
||||
body = body.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
|
||||
var from = data.from_msg_name || data.from;
|
||||
|
||||
$("#chatwin").append("<span class=chatuid>" + from + ":</span><br>" + body);
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
$("#chatwin").append("<span class=chatuid>" + from + ":</span><br>" + body);
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
*/
|
||||
|
||||
var from = data.from_msg_name || data.from;
|
||||
|
||||
$('#chatwin')
|
||||
.append($('<span class="chatuid" />').text(from + ':'))
|
||||
.append($('<br />'))
|
||||
.append(messageTextToJQ(body))
|
||||
.append($('<br />'));
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
var from = data.from_msg_name || data.from;
|
||||
|
||||
$('#chatwin')
|
||||
.append($('<span class="chatuid" />').text(from + ':'))
|
||||
.append($('<br />'))
|
||||
.append(messageTextToJQ(body))
|
||||
.append($('<br />'));
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
}
|
||||
|
||||
if (data.txt) {
|
||||
console.log(data.txt);
|
||||
if (data.txt.chars) {
|
||||
var a = [...data.txt.chars];
|
||||
//console.log(a);
|
||||
for (var x in a) {
|
||||
if(a[x] == "\r") {
|
||||
$("#rtt_in").append("\n");
|
||||
continue;
|
||||
} else if (a[x] == "\b") {
|
||||
$("#rtt_in").text($("#rtt_in").text().slice(0, -1));
|
||||
continue;
|
||||
}
|
||||
console.log("[" + a[x] + "]");
|
||||
$("#rtt_in").append(a[x]);
|
||||
}
|
||||
|
||||
var psconsole = $('#rtt_in');
|
||||
if(psconsole.length)
|
||||
psconsole.scrollTop(psconsole[0].scrollHeight - psconsole.height());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case $.verto.enum.message.display:
|
||||
var party = dialog.params.remote_caller_id_name + "<" + dialog.params.remote_caller_id_number + ">";
|
||||
|
@ -486,6 +551,7 @@ var callbacks = {
|
|||
check_vid_res();
|
||||
|
||||
$("#ansbtn").click(function() {
|
||||
console.error("WTF", cur_call, d);
|
||||
cur_call.answer({
|
||||
useStereo: $("#use_stereo").is(':checked'),
|
||||
callee_id_name: $("#cidname").val(),
|
||||
|
@ -548,7 +614,7 @@ var callbacks = {
|
|||
}
|
||||
|
||||
goto_page("incall");
|
||||
|
||||
real_size();
|
||||
break;
|
||||
case $.verto.enum.state.hangup:
|
||||
$("#main_info").html("Call ended with cause: " + d.cause);
|
||||
|
@ -1051,6 +1117,13 @@ function refresh_devices()
|
|||
pop_select("#usecamera","verto_demo_camera_selected", tmp);
|
||||
}
|
||||
|
||||
var tmp;
|
||||
tmp = $.cookie("verto_demo_share_selected") || "false";
|
||||
if (tmp) {
|
||||
$('#useshare option[value=' + tmp + ']').prop('selected', 'selected').change();
|
||||
pop_select("#useshare","verto_demo_share_selected", tmp);
|
||||
}
|
||||
|
||||
tmp = $.cookie("verto_demo_mic_selected") || "false";
|
||||
if (tmp) {
|
||||
$('#usemic option[value=' + tmp + ']').prop('selected', 'selected').change();
|
||||
|
@ -1558,6 +1631,30 @@ function init() {
|
|||
|
||||
setupChat();
|
||||
|
||||
$("#rtt").val("");
|
||||
$("#rtt_in").text("");
|
||||
|
||||
|
||||
$("#rtt").keyup(function (event) {
|
||||
console.error(event);
|
||||
console.log("KEY (" + event.which + ")\n");
|
||||
|
||||
if (event.which == 8) {
|
||||
cur_call.rtt({code: event.which});
|
||||
}
|
||||
|
||||
if (event.which == 13) {
|
||||
$("#rtt").val("");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$("#rtt").keypress(function (event) {
|
||||
console.error(event);
|
||||
console.log("TEXT (" + event.which + ")\n");
|
||||
cur_call.rtt({code: event.which});
|
||||
});
|
||||
|
||||
$("#ext").keyup(function (event) {
|
||||
if (event.keyCode == 13) {
|
||||
$( "#callbtn" ).trigger( "click" );
|
||||
|
|
|
@ -147,6 +147,7 @@ static const char *EVENT_NAMES[] = {
|
|||
"CALL_SETUP_RESULT",
|
||||
"CALL_DETAIL",
|
||||
"DEVICE_STATE",
|
||||
"REAL_TIME_TEXT",
|
||||
"ALL"
|
||||
};
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ typedef enum {
|
|||
ESL_EVENT_CALL_SETUP_RESULT,
|
||||
ESL_EVENT_CALL_DETAIL,
|
||||
ESL_EVENT_DEVICE_STATE,
|
||||
ESL_EVENT_REAL_TIME_TEXT,
|
||||
ESL_EVENT_ALL
|
||||
} esl_event_types_t;
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
media = 1*(alpha-numeric)
|
||||
;typically "audio", "video", "application"
|
||||
;or "data"
|
||||
;or "data" or "text"
|
||||
|
||||
fmt = 1*(alpha-numeric)
|
||||
;typically an RTP payload type for audio
|
||||
|
|
|
@ -1275,7 +1275,7 @@ static void parse_media(sdp_parser_t *p, char *r, sdp_media_t **result)
|
|||
|
||||
media = token
|
||||
;typically "audio", "video", "application"
|
||||
;or "data"
|
||||
;or "data" or "text"
|
||||
|
||||
fmt = token
|
||||
;typically an RTP payload type for audio
|
||||
|
@ -1378,6 +1378,8 @@ void sdp_media_type(sdp_media_t *m, char const *s)
|
|||
m->m_type = sdp_media_image, m->m_type_name = "image";
|
||||
else if (su_casematch(s, "red"))
|
||||
m->m_type = sdp_media_red, m->m_type_name = "red";
|
||||
else if (su_casematch(s, "text"))
|
||||
m->m_type = sdp_media_text, m->m_type_name = "text";
|
||||
else
|
||||
m->m_type = sdp_media_x, m->m_type_name = s;
|
||||
}
|
||||
|
|
|
@ -583,6 +583,7 @@ static void print_media(sdp_printer_t *p,
|
|||
case sdp_media_control: media = "control"; break;
|
||||
case sdp_media_message: media = "message"; break;
|
||||
case sdp_media_image : media = "image"; break;
|
||||
case sdp_media_text : media = "text"; break;
|
||||
default: media = m->m_type_name;
|
||||
}
|
||||
|
||||
|
|
|
@ -232,7 +232,8 @@ typedef enum
|
|||
sdp_media_message, /**< Messaging sessions*/
|
||||
sdp_media_image, /**< Image browsing sessions,
|
||||
* e.g., JPIP or T.38. */
|
||||
sdp_media_red /**< Redundancy. @NEW_1_12_4. */
|
||||
sdp_media_red, /**< Redundancy. @NEW_1_12_4. */
|
||||
sdp_media_text, /**< Realtime Text */
|
||||
} sdp_media_e;
|
||||
|
||||
/** Media transport protocol. */
|
||||
|
|
|
@ -189,7 +189,13 @@ struct switch_core_session {
|
|||
uint32_t decoder_errors;
|
||||
switch_core_video_thread_callback_func_t video_read_callback;
|
||||
void *video_read_user_data;
|
||||
switch_core_video_thread_callback_func_t text_read_callback;
|
||||
void *text_read_user_data;
|
||||
switch_io_routines_t *io_override;
|
||||
switch_slin_data_t *sdata;
|
||||
|
||||
switch_buffer_t *text_buffer;
|
||||
switch_mutex_t *text_mutex;
|
||||
};
|
||||
|
||||
struct switch_media_bug {
|
||||
|
@ -228,6 +234,11 @@ struct switch_media_bug {
|
|||
switch_image_t *spy_img[2];
|
||||
switch_vid_spy_fmt_t spy_fmt;
|
||||
switch_thread_t *video_bug_thread;
|
||||
|
||||
switch_buffer_t *text_buffer;
|
||||
char *text_framedata;
|
||||
uint32_t text_framesize;
|
||||
|
||||
struct switch_media_bug *next;
|
||||
};
|
||||
|
||||
|
|
|
@ -162,6 +162,8 @@ SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer);
|
|||
SWITCH_DECLARE(switch_size_t) switch_buffer_zwrite(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen)
|
||||
const void *data, _In_ switch_size_t datalen);
|
||||
|
||||
SWITCH_DECLARE(void *) switch_buffer_get_head_pointer(switch_buffer_t *buffer);
|
||||
|
||||
/** @} */
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
|
|
@ -317,6 +317,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *c
|
|||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel);
|
||||
|
||||
|
||||
static inline int switch_channel_var_true(switch_channel_t *channel, const char *variable) {
|
||||
return switch_true(switch_channel_get_variable_dup(channel, variable, SWITCH_FALSE, -1));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Start iterating over the entries in the channel variable list.
|
||||
* \param channel the channel to iterate the variables for
|
||||
|
|
|
@ -351,6 +351,8 @@ SWITCH_DECLARE(void) switch_core_media_bug_set_read_demux_frame(_In_ switch_medi
|
|||
*/
|
||||
SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug);
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_core_media_bug_get_text(switch_media_bug_t *bug);
|
||||
|
||||
/*!
|
||||
\brief Test for the existance of a flag on an media bug
|
||||
\param bug the object to test
|
||||
|
@ -1163,6 +1165,8 @@ SWITCH_DECLARE(void *) switch_core_session_get_stream(_In_ switch_core_session_t
|
|||
*/
|
||||
SWITCH_DECLARE(int) switch_core_session_get_stream_count(_In_ switch_core_session_t *session);
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_core_session_get_text_buffer(switch_core_session_t *session);
|
||||
|
||||
/*!
|
||||
\brief Launch a thread designed to exist within the scope of a given session
|
||||
\param session a session to allocate the thread from
|
||||
|
@ -2741,6 +2745,8 @@ SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t
|
|||
SWITCH_DECLARE(switch_call_direction_t) switch_ice_direction(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_session_debug_pool(switch_stream_handle_t *stream);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_override_io_routines(switch_core_session_t *session, switch_io_routines_t *ior);
|
||||
|
||||
SWITCH_DECLARE(const char *)switch_version_major(void);
|
||||
SWITCH_DECLARE(const char *)switch_version_minor(void);
|
||||
SWITCH_DECLARE(const char *)switch_version_micro(void);
|
||||
|
@ -2752,6 +2758,9 @@ SWITCH_DECLARE(const char *)switch_version_full_human(void);
|
|||
|
||||
SWITCH_DECLARE(void) switch_core_autobind_cpu(void);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_start_text_thread(switch_core_session_t *session);
|
||||
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
|
|
@ -41,6 +41,8 @@ typedef struct switch_io_event_hook_read_frame switch_io_event_hook_read_frame_t
|
|||
typedef struct switch_io_event_hook_video_read_frame switch_io_event_hook_video_read_frame_t;
|
||||
typedef struct switch_io_event_hook_write_frame switch_io_event_hook_write_frame_t;
|
||||
typedef struct switch_io_event_hook_video_write_frame switch_io_event_hook_video_write_frame_t;
|
||||
typedef struct switch_io_event_hook_text_read_frame switch_io_event_hook_text_read_frame_t;
|
||||
typedef struct switch_io_event_hook_text_write_frame switch_io_event_hook_text_write_frame_t;
|
||||
typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel_t;
|
||||
typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t;
|
||||
typedef struct switch_io_event_hook_recv_dtmf switch_io_event_hook_recv_dtmf_t;
|
||||
|
@ -54,6 +56,8 @@ typedef switch_status_t (*switch_read_frame_hook_t) (switch_core_session_t *, sw
|
|||
typedef switch_status_t (*switch_video_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_video_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_text_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_text_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_kill_channel_hook_t) (switch_core_session_t *, int);
|
||||
typedef switch_status_t (*switch_send_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction);
|
||||
typedef switch_status_t (*switch_recv_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction);
|
||||
|
@ -108,6 +112,20 @@ struct switch_io_event_hook_video_write_frame {
|
|||
struct switch_io_event_hook_video_write_frame *next;
|
||||
};
|
||||
|
||||
/*! \brief Node in which to store custom read frame channel callback hooks */
|
||||
struct switch_io_event_hook_text_read_frame {
|
||||
/*! the read frame channel callback hook */
|
||||
switch_read_frame_hook_t text_read_frame;
|
||||
struct switch_io_event_hook_text_read_frame *next;
|
||||
};
|
||||
|
||||
/*! \brief Node in which to store custom video_write_frame channel callback hooks */
|
||||
struct switch_io_event_hook_text_write_frame {
|
||||
/*! the video_write_frame channel callback hook */
|
||||
switch_video_write_frame_hook_t text_write_frame;
|
||||
struct switch_io_event_hook_text_write_frame *next;
|
||||
};
|
||||
|
||||
/*! \brief Node in which to store custom kill channel callback hooks */
|
||||
struct switch_io_event_hook_kill_channel {
|
||||
/*! the kill channel callback hook */
|
||||
|
@ -158,8 +176,12 @@ struct switch_io_event_hooks {
|
|||
switch_io_event_hook_video_read_frame_t *video_read_frame;
|
||||
/*! a list of write frame hooks */
|
||||
switch_io_event_hook_write_frame_t *write_frame;
|
||||
/*! a list of video write frame hooks */
|
||||
/*! a list of text write frame hooks */
|
||||
switch_io_event_hook_video_write_frame_t *video_write_frame;
|
||||
/*! a list of text write frame hooks */
|
||||
switch_io_event_hook_text_write_frame_t *text_write_frame;
|
||||
/*! a list of text read frame hooks */
|
||||
switch_io_event_hook_text_read_frame_t *text_read_frame;
|
||||
/*! a list of kill channel hooks */
|
||||
switch_io_event_hook_kill_channel_t *kill_channel;
|
||||
/*! a list of send dtmf hooks */
|
||||
|
@ -225,6 +247,8 @@ NEW_HOOK_DECL_ADD_P(read_frame);
|
|||
NEW_HOOK_DECL_ADD_P(write_frame);
|
||||
NEW_HOOK_DECL_ADD_P(video_read_frame);
|
||||
NEW_HOOK_DECL_ADD_P(video_write_frame);
|
||||
NEW_HOOK_DECL_ADD_P(text_read_frame);
|
||||
NEW_HOOK_DECL_ADD_P(text_write_frame);
|
||||
NEW_HOOK_DECL_ADD_P(kill_channel);
|
||||
NEW_HOOK_DECL_ADD_P(send_dtmf);
|
||||
NEW_HOOK_DECL_ADD_P(recv_dtmf);
|
||||
|
@ -238,6 +262,8 @@ NEW_HOOK_DECL_REM_P(read_frame);
|
|||
NEW_HOOK_DECL_REM_P(write_frame);
|
||||
NEW_HOOK_DECL_REM_P(video_read_frame);
|
||||
NEW_HOOK_DECL_REM_P(video_write_frame);
|
||||
NEW_HOOK_DECL_REM_P(text_read_frame);
|
||||
NEW_HOOK_DECL_REM_P(text_write_frame);
|
||||
NEW_HOOK_DECL_REM_P(kill_channel);
|
||||
NEW_HOOK_DECL_REM_P(send_dtmf);
|
||||
NEW_HOOK_DECL_REM_P(recv_dtmf);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
|
||||
#include <switch.h>
|
||||
#include <switch_msrp.h>
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
|
@ -122,9 +123,11 @@ typedef struct switch_core_media_params_s {
|
|||
|
||||
switch_rtp_bug_flag_t manual_rtp_bugs;
|
||||
switch_rtp_bug_flag_t manual_video_rtp_bugs;
|
||||
switch_rtp_bug_flag_t manual_text_rtp_bugs;
|
||||
|
||||
char *rtcp_audio_interval_msec;
|
||||
char *rtcp_video_interval_msec;
|
||||
char *rtcp_text_interval_msec;
|
||||
|
||||
|
||||
char *extrtpip;
|
||||
|
@ -335,10 +338,10 @@ SWITCH_DECLARE(switch_bool_t) switch_core_media_codec_get_cap(switch_core_sessio
|
|||
|
||||
|
||||
SWITCH_DECLARE(switch_timer_t *) switch_core_media_get_timer(switch_core_session_t *session, switch_media_type_t mtype);
|
||||
SWITCH_DECLARE(void) switch_core_media_start_video_function(switch_core_session_t *session, switch_video_function_t video_function, void *user_data);
|
||||
SWITCH_DECLARE(void) switch_core_media_end_video_function(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_media_start_engine_function(switch_core_session_t *session, switch_media_type_t type, switch_engine_function_t engine_function, void *user_data);
|
||||
SWITCH_DECLARE(void) switch_core_media_end_engine_function(switch_core_session_t *session, switch_media_type_t type);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_start_video_thread(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(int) switch_core_media_check_video_function(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(int) switch_core_media_check_engine_function(switch_core_session_t *session, switch_media_type_t type);
|
||||
SWITCH_DECLARE(void) switch_core_session_video_reinit(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_read_lock_unlock(switch_core_session_t *session, switch_media_type_t type, switch_bool_t lock);
|
||||
|
||||
|
@ -357,7 +360,25 @@ SWITCH_DECLARE(switch_bool_t) switch_core_media_check_dtls(switch_core_session_t
|
|||
SWITCH_DECLARE(switch_status_t) switch_core_media_set_outgoing_bitrate(switch_core_session_t *session, switch_media_type_t type, uint32_t bitrate);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_reset_jb(switch_core_session_t *session, switch_media_type_t type);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_wait_for_video_input_params(switch_core_session_t *session, uint32_t timeout_ms);
|
||||
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_set_text_read_callback(switch_core_session_t *session,
|
||||
switch_core_text_thread_callback_func_t func, void *user_data);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_text_read_callback(switch_core_session_t *session, switch_frame_t *frame);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
|
||||
int stream_id);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
|
||||
int stream_id);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_text_factory_create(switch_rtp_text_factory_t **tfP, switch_memory_pool_t *pool);
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_text_factory_destroy(switch_rtp_text_factory_t **tfP);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_print(switch_core_session_t *session, const char *data);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t *session, const char *fmt, ...);
|
||||
|
||||
SWITCH_DECLARE(switch_msrp_session_t *) switch_core_media_get_msrp_session(switch_core_session_t *session);
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
|
|
@ -1020,6 +1020,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_video_write_overlay_session(swit
|
|||
SWITCH_DECLARE(switch_status_t) switch_ivr_video_write_overlay_session(switch_core_session_t *session, const char *img_path,
|
||||
switch_img_position_t pos, uint8_t alpha);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_capture_text(switch_core_session_t *session, switch_bool_t on);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ typedef enum {
|
|||
|
||||
typedef enum {
|
||||
SJB_VIDEO = 0,
|
||||
SJB_AUDIO
|
||||
SJB_AUDIO,
|
||||
SJB_TEXT
|
||||
} switch_jb_type_t;
|
||||
|
||||
|
||||
|
|
|
@ -119,6 +119,8 @@ typedef switch_status_t (*switch_io_state_change_t) (switch_core_session_t *);
|
|||
typedef switch_status_t (*switch_io_state_run_t) (switch_core_session_t *);
|
||||
typedef switch_status_t (*switch_io_read_video_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_io_write_video_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_io_read_text_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
|
||||
typedef switch_status_t (*switch_io_write_text_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
|
||||
typedef switch_jb_t *(*switch_io_get_jb_t) (switch_core_session_t *, switch_media_type_t);
|
||||
|
||||
typedef enum {
|
||||
|
@ -132,6 +134,8 @@ typedef enum {
|
|||
SWITCH_IO_STATE_CHANGE,
|
||||
SWITCH_IO_READ_VIDEO_FRAME,
|
||||
SWITCH_IO_WRITE_VIDEO_FRAME,
|
||||
SWITCH_IO_READ_TEXT_FRAME,
|
||||
SWITCH_IO_WRITE_TEXT_FRAME,
|
||||
SWITCH_IO_GET_JB,
|
||||
} switch_io_routine_name_t;
|
||||
|
||||
|
@ -157,6 +161,10 @@ struct switch_io_routines {
|
|||
switch_io_read_video_frame_t read_video_frame;
|
||||
/*! write a video frame to a session */
|
||||
switch_io_write_video_frame_t write_video_frame;
|
||||
/*! read a video frame from a session */
|
||||
switch_io_read_text_frame_t read_text_frame;
|
||||
/*! write a video frame to a session */
|
||||
switch_io_write_text_frame_t write_text_frame;
|
||||
/*! change a sessions channel run state */
|
||||
switch_io_state_run_t state_run;
|
||||
/*! get sessions jitterbuffer */
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2011-2016, Seven Du <dujinfang@gmail.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Seven Du <dujinfang@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
*
|
||||
* msrp.h -- MSRP lib
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MSRP_H
|
||||
#define _MSRP_H
|
||||
|
||||
#include <switch.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#define MSRP_LISTEN_PORT 2855
|
||||
#define MSRP_SSL_LISTEN_PORT 2856
|
||||
|
||||
enum {
|
||||
MSRP_ST_WAIT_HEADER,
|
||||
MSRP_ST_PARSE_HEADER,
|
||||
MSRP_ST_WAIT_BODY,
|
||||
MSRP_ST_DONE,
|
||||
MSRP_ST_ERROR,
|
||||
|
||||
MSRP_METHOD_REPLY,
|
||||
MSRP_METHOD_SEND,
|
||||
MSRP_METHOD_AUTH,
|
||||
MSRP_METHOD_REPORT,
|
||||
|
||||
};
|
||||
|
||||
enum {
|
||||
MSRP_H_FROM_PATH,
|
||||
MSRP_H_TO_PATH,
|
||||
MSRP_H_MESSAGE_ID,
|
||||
MSRP_H_CONTENT_TYPE,
|
||||
MSRP_H_SUCCESS_REPORT,
|
||||
MSRP_H_FAILURE_REPORT,
|
||||
MSRP_H_STATUS,
|
||||
MSRP_H_KEEPALIVE,
|
||||
MSRP_H_UNKNOWN
|
||||
};
|
||||
|
||||
typedef struct msrp_msg_s {
|
||||
int state;
|
||||
int method;
|
||||
char *headers[12];
|
||||
int last_header;
|
||||
char *transaction_id;
|
||||
char *delimiter;
|
||||
int code_number;
|
||||
char *code_description;
|
||||
switch_size_t byte_start;
|
||||
switch_size_t byte_end;
|
||||
switch_size_t bytes;
|
||||
switch_size_t payload_bytes;
|
||||
int range_star; /* range-end is '*' */
|
||||
char *last_p;
|
||||
char *payload;
|
||||
struct msrp_msg_s *next;
|
||||
} msrp_msg_t;
|
||||
|
||||
typedef struct msrp_msg_s switch_msrp_msg_t;
|
||||
|
||||
typedef struct msrp_socket_s {
|
||||
switch_port_t port;
|
||||
switch_socket_t *sock;
|
||||
switch_thread_t *thread;
|
||||
int secure;
|
||||
} msrp_socket_t;
|
||||
|
||||
typedef struct msrp_client_socket_s {
|
||||
switch_socket_t *sock;
|
||||
int secure;
|
||||
} msrp_client_socket_t;
|
||||
|
||||
typedef struct {
|
||||
switch_memory_pool_t *pool;
|
||||
int secure;
|
||||
char *remote_path;
|
||||
char *remote_accept_types;
|
||||
char *remote_accept_wrapped_types;
|
||||
char *remote_setup;
|
||||
char *remote_file_selector;
|
||||
char *local_path;
|
||||
char *local_accept_types;
|
||||
char *local_accept_wrapped_types;
|
||||
char *local_setup;
|
||||
char *local_file_selector;
|
||||
int local_port;
|
||||
char *call_id;
|
||||
msrp_msg_t *msrp_msg;
|
||||
msrp_msg_t *last_msg;
|
||||
switch_mutex_t *mutex;
|
||||
switch_size_t msrp_msg_buffer_size;
|
||||
switch_size_t msrp_msg_count;
|
||||
msrp_socket_t *msock;
|
||||
msrp_client_socket_t *csock;
|
||||
switch_frame_t frame;
|
||||
uint8_t frame_data[SWITCH_RTP_MAX_BUF_LEN];
|
||||
} switch_msrp_session_t;
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_msrp_init();
|
||||
SWITCH_DECLARE(switch_status_t) switch_msrp_destroy();
|
||||
SWITCH_DECLARE(switch_msrp_session_t *)switch_msrp_session_new(switch_memory_pool_t *pool, switch_bool_t secure);
|
||||
SWITCH_DECLARE(switch_status_t) switch_msrp_session_destroy(switch_msrp_session_t **ms);
|
||||
// switch_status_t switch_msrp_session_push_msg(switch_msrp_session_t *ms, msrp_msg_t *msg);
|
||||
SWITCH_DECLARE(switch_msrp_msg_t *)switch_msrp_session_pop_msg(switch_msrp_session_t *ms);
|
||||
SWITCH_DECLARE(switch_status_t) switch_msrp_send(switch_msrp_session_t *ms, msrp_msg_t *msg);
|
||||
|
||||
SWITCH_DECLARE(void) switch_msrp_load_apis_and_applications(switch_loadable_module_interface_t **moudle_interface);
|
||||
#endif
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
|
@ -213,6 +213,8 @@ SWITCH_BEGIN_EXTERN_C
|
|||
#define SWITCH_REMOTE_VIDEO_PORT_VARIABLE "remote_video_port"
|
||||
#define SWITCH_LOCAL_VIDEO_IP_VARIABLE "local_video_ip"
|
||||
#define SWITCH_LOCAL_VIDEO_PORT_VARIABLE "local_video_port"
|
||||
#define SWITCH_LOCAL_TEXT_IP_VARIABLE "local_text_ip"
|
||||
#define SWITCH_LOCAL_TEXT_PORT_VARIABLE "local_text_port"
|
||||
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE "hangup_after_bridge"
|
||||
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE "park_after_bridge"
|
||||
#define SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE "park_after_early_bridge"
|
||||
|
@ -234,6 +236,7 @@ SWITCH_BEGIN_EXTERN_C
|
|||
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "5000"
|
||||
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "2000"
|
||||
|
||||
#define TEXT_UNICODE_LINEFEED {0xe2, 0x80, 0xa8}
|
||||
#define MAX_FMTP_LEN 256
|
||||
|
||||
/* Jitter */
|
||||
|
@ -496,7 +499,8 @@ typedef enum {
|
|||
SWITCH_ABC_TYPE_READ_VIDEO_PING,
|
||||
SWITCH_ABC_TYPE_WRITE_VIDEO_PING,
|
||||
SWITCH_ABC_TYPE_STREAM_VIDEO_PING,
|
||||
SWITCH_ABC_TYPE_VIDEO_PATCH
|
||||
SWITCH_ABC_TYPE_VIDEO_PATCH,
|
||||
SWITCH_ABC_TYPE_READ_TEXT
|
||||
} switch_abc_type_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -771,6 +775,7 @@ typedef enum {
|
|||
SWITCH_RTP_FLAG_TMMBR,
|
||||
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||
SWITCH_RTP_FLAG_TEXT,
|
||||
SWITCH_RTP_FLAG_INVALID
|
||||
} switch_rtp_flag_t;
|
||||
|
||||
|
@ -1371,6 +1376,9 @@ typedef enum {
|
|||
CC_JITTERBUFFER,
|
||||
CC_FS_RTP,
|
||||
CC_QUEUEABLE_DTMF_DELAY,
|
||||
CC_IO_OVERRIDE,
|
||||
CC_RTP_RTT,
|
||||
CC_MSRP,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
CC_FLAG_MAX
|
||||
} switch_channel_cap_t;
|
||||
|
@ -1516,6 +1524,14 @@ typedef enum {
|
|||
CF_3P_NOMEDIA_REQUESTED_BLEG,
|
||||
CF_IMAGE_SDP,
|
||||
CF_VIDEO_SDP_RECVD,
|
||||
CF_TEXT_SDP_RECVD,
|
||||
CF_TEXT,
|
||||
CF_TEXT_POSSIBLE,
|
||||
CF_TEXT_PASSIVE,
|
||||
CF_TEXT_ECHO,
|
||||
CF_TEXT_ACTIVE,
|
||||
CF_TEXT_IDLE,
|
||||
CF_MSRP,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
|
||||
CF_FLAG_MAX
|
||||
|
@ -1572,7 +1588,8 @@ typedef enum {
|
|||
SFF_PICTURE_RESET = (1 << 14),
|
||||
SFF_SAME_IMAGE = (1 << 15),
|
||||
SFF_USE_VIDEO_TIMESTAMP = (1 << 16),
|
||||
SFF_ENCODED = (1 << 17)
|
||||
SFF_ENCODED = (1 << 17),
|
||||
SFF_TEXT_LINE_BREAK = (1 << 18)
|
||||
} switch_frame_flag_enum_t;
|
||||
typedef uint32_t switch_frame_flag_t;
|
||||
|
||||
|
@ -1717,9 +1734,10 @@ typedef enum {
|
|||
|
||||
typedef enum {
|
||||
SWITCH_MEDIA_TYPE_AUDIO,
|
||||
SWITCH_MEDIA_TYPE_VIDEO
|
||||
SWITCH_MEDIA_TYPE_VIDEO,
|
||||
SWITCH_MEDIA_TYPE_TEXT
|
||||
} switch_media_type_t;
|
||||
#define SWITCH_MEDIA_TYPE_TOTAL 2
|
||||
#define SWITCH_MEDIA_TYPE_TOTAL 3
|
||||
|
||||
|
||||
/*!
|
||||
|
@ -1778,7 +1796,8 @@ typedef enum {
|
|||
SMBF_VIDEO_PATCH = (1 << 21),
|
||||
SMBF_SPY_VIDEO_STREAM = (1 << 22),
|
||||
SMBF_SPY_VIDEO_STREAM_BLEG = (1 << 23),
|
||||
SMBF_READ_VIDEO_PATCH = (1 << 24)
|
||||
SMBF_READ_VIDEO_PATCH = (1 << 24),
|
||||
SMBF_READ_TEXT_STREAM = (1 << 25)
|
||||
} switch_media_bug_flag_enum_t;
|
||||
typedef uint32_t switch_media_bug_flag_t;
|
||||
|
||||
|
@ -2024,6 +2043,7 @@ typedef enum {
|
|||
SWITCH_EVENT_CALL_SETUP_RESULT,
|
||||
SWITCH_EVENT_CALL_DETAIL,
|
||||
SWITCH_EVENT_DEVICE_STATE,
|
||||
SWITCH_EVENT_REAL_TIME_TEXT,
|
||||
SWITCH_EVENT_ALL
|
||||
} switch_event_types_t;
|
||||
|
||||
|
@ -2239,13 +2259,15 @@ typedef struct switch_console_callback_match switch_console_callback_match_t;
|
|||
typedef void (*switch_media_bug_exec_cb_t)(switch_media_bug_t *bug, void *user_data);
|
||||
|
||||
typedef switch_status_t (*switch_core_video_thread_callback_func_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
||||
typedef switch_status_t (*switch_core_text_thread_callback_func_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
||||
typedef void (*switch_cap_callback_t) (const char *var, const char *val, void *user_data);
|
||||
typedef switch_status_t (*switch_console_complete_callback_t) (const char *, const char *, switch_console_callback_match_t **matches);
|
||||
typedef switch_bool_t (*switch_media_bug_callback_t) (switch_media_bug_t *, void *, switch_abc_type_t);
|
||||
typedef switch_bool_t (*switch_tone_detect_callback_t) (switch_core_session_t *, const char *, const char *);
|
||||
typedef struct switch_xml_binding switch_xml_binding_t;
|
||||
|
||||
typedef void (*switch_video_function_t) (switch_core_session_t *session, void *user_data);
|
||||
typedef void (*switch_engine_function_t) (switch_core_session_t *session, void *user_data);
|
||||
|
||||
|
||||
typedef switch_status_t (*switch_core_codec_encode_func_t) (switch_codec_t *codec,
|
||||
switch_codec_t *other_codec,
|
||||
|
@ -2619,6 +2641,10 @@ typedef enum {
|
|||
SCFC_PAUSE_READ
|
||||
} switch_file_command_t;
|
||||
|
||||
|
||||
struct switch_rtp_text_factory_s;
|
||||
typedef struct switch_rtp_text_factory_s switch_rtp_text_factory_t;
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
|
|
@ -373,6 +373,33 @@ SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size
|
|||
SWITCH_DECLARE(switch_size_t) switch_b64_decode(char *in, char *out, switch_size_t olen);
|
||||
SWITCH_DECLARE(char *) switch_amp_encode(char *s, char *buf, switch_size_t len);
|
||||
|
||||
|
||||
|
||||
static inline char *switch_print_bits(const unsigned char *byte, char *buf, switch_size_t buflen)
|
||||
{
|
||||
|
||||
int i, j = 0, k = 0, l = 0;
|
||||
|
||||
while(k < buflen) {
|
||||
l = 0;
|
||||
for (i = 7; i >= 0; i--) {
|
||||
buf[j++] = (*byte & (1 << i)) ? '1' : '0';
|
||||
if (++l % 4 == 0) {
|
||||
buf[j++] = ' ';
|
||||
}
|
||||
}
|
||||
k++;
|
||||
byte++;
|
||||
}
|
||||
|
||||
if (buf[j-1] == ' ') j--;
|
||||
buf[j++] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static inline switch_bool_t switch_is_digit_string(const char *s)
|
||||
{
|
||||
|
||||
|
|
|
@ -1140,7 +1140,7 @@ SWITCH_STANDARD_APP(record_av_function)
|
|||
switch_core_timer_destroy(&timer);
|
||||
}
|
||||
|
||||
switch_core_media_end_video_function(session);
|
||||
switch_core_media_end_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO);
|
||||
switch_core_session_set_read_codec(session, NULL);
|
||||
switch_core_codec_destroy(&codec);
|
||||
|
||||
|
|
|
@ -3066,6 +3066,61 @@ SWITCH_STANDARD_API(uuid_chat)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define UUID_CAPTURE_TEXT_SYNTAX "<uuid> <on|off>"
|
||||
SWITCH_STANDARD_API(uuid_capture_text)
|
||||
{
|
||||
switch_core_session_t *tsession = NULL;
|
||||
char *uuid = NULL, *onoff = NULL;
|
||||
|
||||
if (!zstr(cmd) && (uuid = strdup(cmd))) {
|
||||
if ((onoff = strchr(uuid, ' '))) {
|
||||
*onoff++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(uuid) || zstr(onoff)) {
|
||||
stream->write_function(stream, "-USAGE: %s\n", UUID_CAPTURE_TEXT_SYNTAX);
|
||||
} else {
|
||||
if ((tsession = switch_core_session_locate(uuid))) {
|
||||
switch_ivr_capture_text(tsession, switch_true(onoff));
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(uuid);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#define UUID_SEND_TEXT_SYNTAX "<uuid> <text>"
|
||||
SWITCH_STANDARD_API(uuid_send_text)
|
||||
{
|
||||
switch_core_session_t *tsession = NULL;
|
||||
char *uuid = NULL, *text = NULL;
|
||||
|
||||
if (!zstr(cmd) && (uuid = strdup(cmd))) {
|
||||
if ((text = strchr(uuid, ' '))) {
|
||||
*text++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(uuid) || zstr(text)) {
|
||||
stream->write_function(stream, "-USAGE: %s\n", UUID_SEND_TEXT_SYNTAX);
|
||||
} else {
|
||||
if ((tsession = switch_core_session_locate(uuid))) {
|
||||
switch_core_session_print(tsession, text);
|
||||
switch_core_session_print(tsession, "\r\n");
|
||||
switch_core_session_rwunlock(tsession);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(uuid);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define UUID_DROP_DTMF_SYNTAX "<uuid> [on | off ] [ mask_digits <digits> | mask_file <file>]"
|
||||
SWITCH_STANDARD_API(uuid_drop_dtmf)
|
||||
{
|
||||
|
@ -7197,6 +7252,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
SWITCH_ADD_API(commands_api_interface, "uuid_broadcast", "Execute dialplan application", uuid_broadcast_function, BROADCAST_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_buglist", "List media bugs on a session", uuid_buglist_function, BUGLIST_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_send_text", "Send text in real-time", uuid_send_text, UUID_SEND_TEXT_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_capture_text", "start/stop capture_text", uuid_capture_text, UUID_CAPTURE_TEXT_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_codec_debug", "Send codec a debug message", uuid_codec_debug_function, CODEC_DEBUG_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_codec_param", "Send codec a param", uuid_codec_param_function, CODEC_PARAM_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "uuid_debug_media", "Debug media", uuid_debug_media_function, DEBUG_MEDIA_SYNTAX);
|
||||
|
@ -7376,6 +7433,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
switch_console_set_complete("add uuid_broadcast ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_buglist ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_chat ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_send_text ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_capture_text ::console::list_uuid");
|
||||
switch_console_set_complete("add uuid_codec_debug ::console::list_uuid audio");
|
||||
switch_console_set_complete("add uuid_codec_debug ::console::list_uuid video");
|
||||
switch_console_set_complete("add uuid_codec_param ::console::list_uuid audio read");
|
||||
|
@ -7439,6 +7498,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
|||
switch_console_set_complete("add file_exists");
|
||||
switch_console_set_complete("add getcputime");
|
||||
|
||||
switch_msrp_load_apis_and_applications(module_interface);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_NOUNLOAD;
|
||||
}
|
||||
|
|
|
@ -1148,6 +1148,13 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m
|
|||
lock_member(member);
|
||||
conference_utils_member_clear_flag(member, MFLAG_INTREE);
|
||||
|
||||
|
||||
switch_safe_free(member->text_framedata);
|
||||
member->text_framesize = 0;
|
||||
if (member->text_buffer) {
|
||||
switch_buffer_destroy(&member->text_buffer);
|
||||
}
|
||||
|
||||
if (member->rec) {
|
||||
conference->recording_members--;
|
||||
}
|
||||
|
|
|
@ -249,6 +249,42 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
|
|||
|
||||
floor_holder = conference->floor_holder;
|
||||
|
||||
for (imember = conference->members; imember; imember = imember->next) {
|
||||
if (!zstr(imember->text_framedata)) {
|
||||
switch_frame_t frame = { 0 };
|
||||
char *framedata;
|
||||
uint32_t framedatalen;
|
||||
const char *caller_id_name = switch_channel_get_variable(imember->channel, "caller_id_name");
|
||||
unsigned char CR[3] = TEXT_UNICODE_LINEFEED;
|
||||
|
||||
|
||||
switch_mutex_lock(imember->text_mutex);
|
||||
|
||||
framedatalen = strlen(imember->text_framedata) + strlen(caller_id_name) + 6;
|
||||
|
||||
switch_zmalloc(framedata, framedatalen);
|
||||
|
||||
switch_snprintf(framedata, framedatalen, "%s::\n%s", caller_id_name, imember->text_framedata);
|
||||
memcpy(framedata + strlen(framedata), CR, sizeof(CR));
|
||||
|
||||
|
||||
frame.data = framedata;
|
||||
frame.datalen = framedatalen;
|
||||
|
||||
for (omember = conference->members; omember; omember = omember->next) {
|
||||
if (omember != imember) {
|
||||
switch_core_session_write_text_frame(omember->session, &frame, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
free(framedata);
|
||||
|
||||
imember->text_framedata[0] = '\0';
|
||||
|
||||
switch_mutex_unlock(imember->text_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Read one frame of audio from each member channel and save it for redistribution */
|
||||
for (imember = conference->members; imember; imember = imember->next) {
|
||||
uint32_t buf_read = 0;
|
||||
|
@ -1610,6 +1646,65 @@ SWITCH_STANDARD_APP(conference_auto_function)
|
|||
}
|
||||
|
||||
|
||||
switch_status_t conference_text_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data)
|
||||
{
|
||||
conference_member_t *member = (conference_member_t *)user_data;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_size_t inuse = 0;
|
||||
|
||||
if (!member) return SWITCH_STATUS_FALSE;
|
||||
|
||||
|
||||
switch_mutex_lock(member->text_mutex);
|
||||
if (!member->text_buffer) {
|
||||
switch_buffer_create_dynamic(&member->text_buffer, 512, 1024, 0);
|
||||
switch_zmalloc(member->text_framedata, 1024);
|
||||
member->text_framesize = 1024;
|
||||
}
|
||||
|
||||
if (frame->data && frame->datalen && !(frame->flags & SFF_CNG)) {
|
||||
switch_buffer_write(member->text_buffer, frame->data, frame->datalen);
|
||||
}
|
||||
|
||||
inuse = switch_buffer_inuse(member->text_buffer);
|
||||
|
||||
if (zstr(member->text_framedata) && inuse && (switch_channel_test_flag(channel, CF_TEXT_IDLE) || switch_test_flag(frame, SFF_TEXT_LINE_BREAK))) {
|
||||
int bytes = 0, ok = 0;
|
||||
char *p;
|
||||
|
||||
if (inuse + 1 > member->text_framesize) {
|
||||
void *tmp = malloc(inuse + 1024);
|
||||
memcpy(tmp, member->text_framedata, member->text_framesize);
|
||||
|
||||
switch_assert(tmp);
|
||||
|
||||
member->text_framesize = inuse + 1024;
|
||||
|
||||
free(member->text_framedata);
|
||||
member->text_framedata = tmp;
|
||||
|
||||
}
|
||||
|
||||
bytes = switch_buffer_read(member->text_buffer, member->text_framedata, inuse);
|
||||
*(member->text_framedata + bytes) = '\0';
|
||||
|
||||
for(p = member->text_framedata; p && *p; p++) {
|
||||
if (*p > 32 && *p < 127) {
|
||||
ok++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
member->text_framedata[0] = '\0';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch_mutex_unlock(member->text_mutex);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Application interface function that is called from the dialplan to join the channel to a conference */
|
||||
SWITCH_STANDARD_APP(conference_function)
|
||||
{
|
||||
|
@ -2123,6 +2218,7 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
switch_mutex_init(&member.fnode_mutex, SWITCH_MUTEX_NESTED, member.pool);
|
||||
switch_mutex_init(&member.audio_in_mutex, SWITCH_MUTEX_NESTED, member.pool);
|
||||
switch_mutex_init(&member.audio_out_mutex, SWITCH_MUTEX_NESTED, member.pool);
|
||||
switch_mutex_init(&member.text_mutex, SWITCH_MUTEX_NESTED, member.pool);
|
||||
switch_thread_rwlock_create(&member.rwlock, member.pool);
|
||||
|
||||
if (conference_member_setup_media(&member, conference)) {
|
||||
|
@ -2197,6 +2293,7 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
|
||||
/* Chime in the core video thread */
|
||||
switch_core_session_set_video_read_callback(session, conference_video_thread_callback, (void *)&member);
|
||||
switch_core_session_set_text_read_callback(session, conference_text_thread_callback, (void *)&member);
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO_ONLY)) {
|
||||
while(conference_utils_member_test_flag((&member), MFLAG_RUNNING) && switch_channel_ready(channel)) {
|
||||
|
@ -2211,6 +2308,7 @@ SWITCH_STANDARD_APP(conference_function)
|
|||
}
|
||||
|
||||
switch_core_session_set_video_read_callback(session, NULL, NULL);
|
||||
switch_core_session_set_text_read_callback(session, NULL, NULL);
|
||||
|
||||
switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
|
||||
|
||||
|
|
|
@ -790,6 +790,13 @@ struct conference_member {
|
|||
int reset_media;
|
||||
int flip;
|
||||
int flip_count;
|
||||
|
||||
switch_mutex_t *text_mutex;
|
||||
switch_buffer_t *text_buffer;
|
||||
char *text_framedata;
|
||||
uint32_t text_framesize;
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -971,6 +978,7 @@ void conference_video_fnode_check(conference_file_node_t *fnode, int canvas_id);
|
|||
switch_status_t conference_video_set_canvas_bgimg(mcu_canvas_t *canvas, const char *img_path);
|
||||
switch_status_t conference_al_parse_position(al_handle_t *al, const char *data);
|
||||
switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
||||
switch_status_t conference_text_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
|
||||
void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_t *thread, void *obj);
|
||||
void conference_member_check_agc_levels(conference_member_t *member);
|
||||
void conference_member_clear_avg(conference_member_t *member);
|
||||
|
|
|
@ -1012,6 +1012,10 @@ SWITCH_STANDARD_APP(set_mute_function)
|
|||
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(capture_text_function)
|
||||
{
|
||||
switch_ivr_capture_text(session, switch_true((char *)data));
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_APP(ring_ready_function)
|
||||
{
|
||||
|
@ -6127,6 +6131,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SWITCH_ADD_CHAT(chat_interface, "event", event_chat_send);
|
||||
SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send);
|
||||
|
||||
|
||||
SWITCH_ADD_API(api_interface, "strepoch", "Convert a date string into epoch time", strepoch_api_function, "<string>");
|
||||
SWITCH_ADD_API(api_interface, "page", "Send a file as a page", page_api_function, "(var1=val1,var2=val2)<var1=val1,var2=val2><chan1>[:_:<chanN>]");
|
||||
SWITCH_ADD_API(api_interface, "strmicroepoch", "Convert a date string into micoepoch time", strmicroepoch_api_function, "<string>");
|
||||
|
@ -6216,6 +6221,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
|||
SWITCH_ADD_APP(app_interface, "multiunset", "Unset many channel variables", SET_LONG_DESC, multiunset_function, "[^^<delim>]<varname> <var2> <var3>",
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "capture_text", "capture text", "capture text", capture_text_function, "", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "[<function>]", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
|
||||
|
|
|
@ -183,7 +183,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
|
|||
switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
||||
eh.mutex = mutex;
|
||||
eh.fd = fd;
|
||||
switch_core_media_start_video_function(session, record_video_thread, &eh);
|
||||
switch_core_media_start_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO, record_video_thread, &eh);
|
||||
}
|
||||
|
||||
|
||||
|
@ -257,7 +257,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
|
|||
close(fd);
|
||||
}
|
||||
|
||||
switch_core_media_end_video_function(session);
|
||||
switch_core_media_end_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO);
|
||||
switch_core_session_set_read_codec(session, NULL);
|
||||
switch_core_codec_destroy(&codec);
|
||||
|
||||
|
@ -751,7 +751,7 @@ SWITCH_STANDARD_APP(decode_video_function)
|
|||
|
||||
switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ);
|
||||
|
||||
switch_core_media_start_video_function(session, decode_video_thread, &max_pictures);
|
||||
switch_core_media_start_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO, decode_video_thread, &max_pictures);
|
||||
|
||||
switch_ivr_play_file(session, NULL, moh, NULL);
|
||||
|
||||
|
@ -762,7 +762,7 @@ SWITCH_STANDARD_APP(decode_video_function)
|
|||
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "OK");
|
||||
|
||||
|
||||
switch_core_media_end_video_function(session);
|
||||
switch_core_media_end_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO);
|
||||
switch_core_session_video_reset(session);
|
||||
}
|
||||
|
||||
|
|
|
@ -287,6 +287,8 @@ switch_io_routines_t rtc_io_routines = {
|
|||
/*.state_change */ NULL,
|
||||
/*.read_video_frame */ rtc_read_video_frame,
|
||||
/*.write_video_frame */ rtc_write_video_frame,
|
||||
/*.read_text_frame */ NULL,
|
||||
/*.write_text_frame */ NULL,
|
||||
/*.state_run*/ NULL,
|
||||
/*.get_jb*/ rtc_get_jb
|
||||
};
|
||||
|
@ -330,6 +332,7 @@ void rtc_attach_private(switch_core_session_t *session, private_object_t *tech_p
|
|||
switch_core_media_check_dtmf_type(session);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_IO_OVERRIDE);
|
||||
switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
|
||||
switch_core_session_set_private(session, tech_pvt);
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
|
|||
static switch_status_t sofia_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t sofia_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t sofia_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t sofia_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t sofia_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t sofia_kill_channel(switch_core_session_t *session, int sig);
|
||||
|
||||
/* BODY OF THE MODULE */
|
||||
|
@ -918,6 +920,33 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t sofia_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
return switch_core_media_read_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_TEXT);
|
||||
}
|
||||
|
||||
static switch_status_t sofia_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_MSRP)) {
|
||||
switch_msrp_session_t *msrp_session = switch_core_media_get_msrp_session(session);
|
||||
|
||||
if (frame && msrp_session) {
|
||||
switch_msrp_msg_t msrp_msg = { 0 };
|
||||
|
||||
msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "message/cpim";
|
||||
// msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "text/plain";
|
||||
msrp_msg.payload = frame->data;
|
||||
msrp_msg.payload_bytes = frame->datalen;
|
||||
|
||||
return switch_msrp_send(msrp_session, &msrp_msg);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
return switch_core_media_write_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_TEXT);
|
||||
}
|
||||
|
||||
static switch_status_t sofia_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
|
||||
|
@ -4279,6 +4308,8 @@ switch_io_routines_t sofia_io_routines = {
|
|||
/*.state_change */ NULL,
|
||||
/*.read_video_frame */ sofia_read_video_frame,
|
||||
/*.write_video_frame */ sofia_write_video_frame,
|
||||
/*.read_text_frame */ sofia_read_text_frame,
|
||||
/*.write_text_frame */ sofia_write_text_frame,
|
||||
/*.state_run*/ NULL,
|
||||
/*.get_jb*/ sofia_get_jb
|
||||
};
|
||||
|
|
|
@ -122,6 +122,8 @@ switch_io_routines_t crtp_io_routines = {
|
|||
/*state_change*/ NULL,
|
||||
/*read_video_frame*/ NULL,
|
||||
/*write_video_frame*/ NULL,
|
||||
/*read_text_frame*/ NULL,
|
||||
/*write_text_frame*/ NULL,
|
||||
/*state_run*/ NULL
|
||||
|
||||
|
||||
|
|
|
@ -159,6 +159,8 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
|
|||
switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_RTP_RTT);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_MSRP);
|
||||
switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY);
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#include <poll.h>
|
||||
#define closesocket(x) close(x)
|
||||
#endif
|
||||
#include <switch_utils.h>
|
||||
#include <switch.h>
|
||||
#include "mcast.h"
|
||||
|
||||
|
||||
|
|
|
@ -130,6 +130,10 @@ static switch_bool_t check_name(const char *name)
|
|||
}
|
||||
|
||||
|
||||
static switch_status_t verto_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
|
||||
static switch_status_t verto_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
|
||||
static void set_text_funcs(switch_core_session_t *session);
|
||||
|
||||
static verto_profile_t *find_profile(const char *name);
|
||||
static jsock_t *get_jsock(const char *uuid);
|
||||
|
||||
|
@ -2116,6 +2120,11 @@ switch_endpoint_interface_t *verto_endpoint_interface = NULL;
|
|||
|
||||
static switch_status_t verto_on_destroy(switch_core_session_t *session)
|
||||
{
|
||||
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
|
||||
|
||||
switch_buffer_destroy(&tech_pvt->text_read_buffer);
|
||||
switch_buffer_destroy(&tech_pvt->text_write_buffer);
|
||||
|
||||
UNPROTECT_INTERFACE(verto_endpoint_interface);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -2576,6 +2585,7 @@ static int verto_recover_callback(switch_core_session_t *session)
|
|||
}
|
||||
|
||||
tech_pvt = switch_core_session_alloc(session, sizeof(*tech_pvt));
|
||||
tech_pvt->pool = switch_core_session_get_pool(session);
|
||||
tech_pvt->session = session;
|
||||
tech_pvt->channel = channel;
|
||||
tech_pvt->jsock_uuid = (char *) jsock_uuid_str;
|
||||
|
@ -3261,7 +3271,7 @@ static void parse_user_vars(cJSON *obj, switch_core_session_t *session)
|
|||
|
||||
static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
|
||||
{
|
||||
cJSON *msg = NULL, *dialog = NULL;
|
||||
cJSON *msg = NULL, *dialog = NULL, *txt = NULL;
|
||||
const char *call_id = NULL, *dtmf = NULL;
|
||||
switch_bool_t r = SWITCH_TRUE;
|
||||
char *proto = VERTO_CHAT_PROTO;
|
||||
|
@ -3298,6 +3308,43 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
|
|||
}
|
||||
}
|
||||
|
||||
if ((txt = cJSON_GetObjectItem(params, "txt"))) {
|
||||
switch_core_session_t *session;
|
||||
|
||||
if ((session = switch_core_session_locate(call_id))) {
|
||||
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
|
||||
char charbuf[2] = "";
|
||||
char *chardata = NULL;
|
||||
cJSON *data;
|
||||
|
||||
if ((data = cJSON_GetObjectItem(txt, "code"))) {
|
||||
charbuf[0] = data->valueint;
|
||||
chardata = charbuf;
|
||||
} else if ((data = cJSON_GetObjectItem(txt, "chars"))) {
|
||||
if (data->valuestring) {
|
||||
chardata = data->valuestring;
|
||||
} else if (data->valueint) {
|
||||
charbuf[0] = data->valueint;
|
||||
chardata = charbuf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (chardata) {
|
||||
switch_mutex_lock(tech_pvt->text_read_mutex);
|
||||
switch_buffer_write(tech_pvt->text_read_buffer, chardata, strlen(chardata));
|
||||
switch_mutex_unlock(tech_pvt->text_read_mutex);
|
||||
|
||||
if ((switch_mutex_trylock(tech_pvt->text_cond_mutex) == SWITCH_STATUS_SUCCESS)) {
|
||||
switch_thread_cond_signal(tech_pvt->text_cond);
|
||||
switch_mutex_unlock(tech_pvt->text_cond_mutex);
|
||||
}
|
||||
}
|
||||
switch_core_session_rwunlock(session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((msg = cJSON_GetObjectItem(params, "msg"))) {
|
||||
switch_event_t *event;
|
||||
char *to = (char *) cJSON_GetObjectCstr(msg, "to");
|
||||
|
@ -3380,6 +3427,8 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
|
||||
{
|
||||
cJSON *obj = cJSON_CreateObject(), *screenShare = NULL, *dedEnc = NULL, *mirrorInput, *bandwidth = NULL, *canvas = NULL;
|
||||
|
@ -3431,12 +3480,13 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock
|
|||
|
||||
tech_pvt = switch_core_session_alloc(session, sizeof(*tech_pvt));
|
||||
tech_pvt->session = session;
|
||||
tech_pvt->pool = switch_core_session_get_pool(session);
|
||||
tech_pvt->channel = channel;
|
||||
tech_pvt->jsock_uuid = switch_core_session_strdup(session, jsock->uuid_str);
|
||||
tech_pvt->r_sdp = switch_core_session_strdup(session, sdp);
|
||||
switch_core_media_set_sdp_codec_string(session, sdp, SDP_TYPE_REQUEST);
|
||||
switch_core_session_set_private_class(session, tech_pvt, SWITCH_PVT_SECONDARY);
|
||||
|
||||
set_text_funcs(session);
|
||||
|
||||
tech_pvt->call_id = switch_core_session_strdup(session, call_id);
|
||||
if ((tech_pvt->smh = switch_core_session_get_media_handle(session))) {
|
||||
|
@ -5042,6 +5092,115 @@ switch_io_routines_t verto_io_routines = {
|
|||
/*.outgoing_channel */ verto_outgoing_channel
|
||||
};
|
||||
|
||||
|
||||
switch_io_routines_t verto_io_override = {
|
||||
/*.outgoing_channel */ NULL,
|
||||
/*.read_frame */ NULL,
|
||||
/*.write_frame */ NULL,
|
||||
/*.kill_channel */ NULL,
|
||||
/*.send_dtmf */ NULL,
|
||||
/*.receive_message */ NULL,
|
||||
/*.receive_event */ NULL,
|
||||
/*.state_change */ NULL,
|
||||
/*.read_video_frame */ NULL,
|
||||
/*.write_video_frame */ NULL,
|
||||
/*.read_text_frame */ verto_read_text_frame,
|
||||
/*.write_text_frame */ verto_write_text_frame,
|
||||
/*.state_run*/ NULL,
|
||||
/*.get_jb*/ NULL
|
||||
};
|
||||
|
||||
|
||||
static switch_status_t verto_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
|
||||
switch_status_t status;
|
||||
|
||||
switch_mutex_lock(tech_pvt->text_cond_mutex);
|
||||
|
||||
status = switch_thread_cond_timedwait(tech_pvt->text_cond, tech_pvt->text_cond_mutex, 100000);
|
||||
switch_mutex_unlock(tech_pvt->text_cond_mutex);
|
||||
|
||||
*frame = &tech_pvt->text_read_frame;
|
||||
(*frame)->flags = 0;
|
||||
|
||||
switch_mutex_lock(tech_pvt->text_read_mutex);
|
||||
if (switch_buffer_inuse(tech_pvt->text_read_buffer)) {
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
tech_pvt->text_read_frame.datalen = switch_buffer_read(tech_pvt->text_read_buffer, tech_pvt->text_read_frame.data, 100);
|
||||
} else {
|
||||
(*frame)->flags |= SFF_CNG;
|
||||
tech_pvt->text_read_frame.datalen = 2;
|
||||
status = SWITCH_STATUS_BREAK;
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->text_read_mutex);
|
||||
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static switch_status_t verto_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
|
||||
{
|
||||
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
|
||||
|
||||
switch_mutex_lock(tech_pvt->text_write_mutex);
|
||||
|
||||
|
||||
if (frame) {
|
||||
switch_buffer_write(tech_pvt->text_write_buffer, frame->data, frame->datalen);
|
||||
}
|
||||
|
||||
if (switch_buffer_inuse(tech_pvt->text_write_buffer)) {
|
||||
uint32_t datalen;
|
||||
switch_byte_t data[SWITCH_RTP_MAX_BUF_LEN] = "";
|
||||
|
||||
if ((datalen = switch_buffer_read(tech_pvt->text_write_buffer, data, 100))) {
|
||||
cJSON *obj = NULL, *txt = NULL, *params = NULL;
|
||||
jsock_t *jsock;
|
||||
|
||||
obj = jrpc_new_req("verto.info", tech_pvt->call_id, ¶ms);
|
||||
txt = json_add_child_obj(params, "txt", NULL);
|
||||
cJSON_AddItemToObject(txt, "chars", cJSON_CreateString((char *)data));
|
||||
|
||||
if ((jsock = get_jsock(tech_pvt->jsock_uuid))) {
|
||||
jsock_queue_event(jsock, &obj, SWITCH_TRUE);
|
||||
switch_thread_rwlock_unlock(jsock->rwlock);
|
||||
} else {
|
||||
cJSON_Delete(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_unlock(tech_pvt->text_write_mutex);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void set_text_funcs(switch_core_session_t *session)
|
||||
{
|
||||
if ((switch_core_session_override_io_routines(session, &verto_io_override) == SWITCH_STATUS_SUCCESS)) {
|
||||
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
|
||||
|
||||
tech_pvt->text_read_frame.data = tech_pvt->text_read_frame_data;
|
||||
|
||||
switch_mutex_init(&tech_pvt->text_read_mutex, SWITCH_MUTEX_NESTED, tech_pvt->pool);
|
||||
switch_mutex_init(&tech_pvt->text_write_mutex, SWITCH_MUTEX_NESTED, tech_pvt->pool);
|
||||
switch_mutex_init(&tech_pvt->text_cond_mutex, SWITCH_MUTEX_NESTED, tech_pvt->pool);
|
||||
switch_thread_cond_create(&tech_pvt->text_cond, tech_pvt->pool);
|
||||
|
||||
switch_buffer_create_dynamic(&tech_pvt->text_read_buffer, 512, 1024, 0);
|
||||
switch_buffer_create_dynamic(&tech_pvt->text_write_buffer, 512, 1024, 0);
|
||||
|
||||
switch_channel_set_flag(switch_core_session_get_channel(session), CF_TEXT);
|
||||
switch_core_session_start_text_thread(session);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char *verto_get_dial_string(const char *uid, switch_stream_handle_t *rstream)
|
||||
{
|
||||
jsock_t *jsock;
|
||||
|
@ -5187,11 +5346,14 @@ static switch_call_cause_t verto_outgoing_channel(switch_core_session_t *session
|
|||
char name[512];
|
||||
|
||||
tech_pvt = switch_core_session_alloc(*new_session, sizeof(*tech_pvt));
|
||||
tech_pvt->pool = switch_core_session_get_pool(*new_session);
|
||||
tech_pvt->session = *new_session;
|
||||
tech_pvt->channel = channel;
|
||||
tech_pvt->jsock_uuid = switch_core_session_strdup(*new_session, jsock_uuid_str);
|
||||
|
||||
switch_core_session_set_private_class(*new_session, tech_pvt, SWITCH_PVT_SECONDARY);
|
||||
|
||||
set_text_funcs(*new_session);
|
||||
|
||||
if (session) {
|
||||
switch_channel_t *ochannel = switch_core_session_get_channel(session);
|
||||
|
||||
|
|
|
@ -173,6 +173,7 @@ typedef enum {
|
|||
} tflag_t;
|
||||
|
||||
typedef struct verto_pvt_s {
|
||||
switch_memory_pool_t *pool;
|
||||
char *jsock_uuid;
|
||||
char *call_id;
|
||||
char *r_sdp;
|
||||
|
@ -184,6 +185,17 @@ typedef struct verto_pvt_s {
|
|||
switch_call_cause_t remote_hangup_cause;
|
||||
time_t detach_time;
|
||||
struct verto_pvt_s *next;
|
||||
switch_byte_t text_read_frame_data[SWITCH_RTP_MAX_BUF_LEN];
|
||||
switch_frame_t text_read_frame;
|
||||
|
||||
switch_thread_cond_t *text_cond;
|
||||
switch_mutex_t *text_cond_mutex;
|
||||
switch_mutex_t *text_read_mutex;
|
||||
switch_mutex_t *text_write_mutex;
|
||||
|
||||
switch_buffer_t *text_read_buffer;
|
||||
switch_buffer_t *text_write_buffer;
|
||||
|
||||
} verto_pvt_t;
|
||||
|
||||
typedef struct verto_vhost_s {
|
||||
|
|
|
@ -53,6 +53,12 @@ struct switch_buffer {
|
|||
int32_t loops;
|
||||
};
|
||||
|
||||
|
||||
SWITCH_DECLARE(void *) switch_buffer_get_head_pointer(switch_buffer_t *buffer)
|
||||
{
|
||||
return buffer->head;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_buffer_reset_partition_data(switch_buffer_t *buffer)
|
||||
{
|
||||
if (!switch_test_flag(buffer, SWITCH_BUFFER_FLAG_PARTITION)) {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <switch_nat.h>
|
||||
#include "private/switch_core_pvt.h"
|
||||
#include <switch_curl.h>
|
||||
#include <switch_msrp.h>
|
||||
#ifndef WIN32
|
||||
#include <switch_private.h>
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
|
@ -2391,6 +2392,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t
|
|||
switch_core_set_signal_handlers();
|
||||
switch_load_network_lists(SWITCH_FALSE);
|
||||
|
||||
switch_msrp_init();
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
|
||||
if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -2905,6 +2908,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
|
|||
switch_scheduler_task_thread_stop();
|
||||
|
||||
switch_rtp_shutdown();
|
||||
switch_msrp_destroy();
|
||||
|
||||
if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
|
||||
switch_nat_shutdown();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -88,6 +88,11 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(switch
|
|||
return bug->session;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_core_media_bug_get_text(switch_media_bug_t *bug)
|
||||
{
|
||||
return bug->text_framedata;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_video_ping_frame(switch_media_bug_t *bug)
|
||||
{
|
||||
return bug->video_ping_frame;
|
||||
|
@ -791,6 +796,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
|
|||
switch_queue_create(&bug->spy_video_queue[1], SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
|
||||
}
|
||||
|
||||
if ((switch_test_flag(bug, SMBF_READ_TEXT_STREAM))) {
|
||||
|
||||
switch_buffer_create_dynamic(&bug->text_buffer, 512, 1024, 0);
|
||||
switch_zmalloc(bug->text_framedata, 1024);
|
||||
bug->text_framesize = 1024;
|
||||
|
||||
}
|
||||
|
||||
if ((switch_test_flag(bug, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM))) {
|
||||
switch_memory_pool_t *pool = switch_core_session_get_pool(session);
|
||||
|
||||
|
@ -1150,6 +1163,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_close(switch_media_bug_t *
|
|||
bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
|
||||
}
|
||||
|
||||
if (bp->text_buffer) {
|
||||
switch_buffer_destroy(&bp->text_buffer);
|
||||
switch_safe_free(bp->text_framedata);
|
||||
}
|
||||
|
||||
if (switch_test_flag(bp, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bp, SMBF_WRITE_VIDEO_STREAM) || switch_test_flag(bp, SMBF_READ_VIDEO_PING) || switch_test_flag(bp, SMBF_WRITE_VIDEO_PING)) {
|
||||
switch_channel_clear_flag_recursive(bp->session->channel, CF_VIDEO_DECODED_READ);
|
||||
}
|
||||
|
|
|
@ -1469,6 +1469,10 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
|
|||
switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel)));
|
||||
|
||||
|
||||
if ((*session)->text_buffer) {
|
||||
switch_buffer_destroy(&(*session)->text_buffer);
|
||||
}
|
||||
|
||||
switch_core_session_reset(*session, SWITCH_TRUE, SWITCH_TRUE);
|
||||
|
||||
switch_core_media_bug_remove_all(*session);
|
||||
|
@ -1880,6 +1884,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(switch_core_se
|
|||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(const char *) switch_core_session_get_text_buffer(switch_core_session_t *session)
|
||||
{
|
||||
const char *buf = NULL;
|
||||
|
||||
if (session->text_buffer) {
|
||||
switch_mutex_lock(session->text_mutex);
|
||||
buf = (const char *)switch_core_session_strdup(session, (const char *) switch_buffer_get_head_pointer(session->text_buffer));
|
||||
switch_mutex_unlock(session->text_mutex);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_session_launch_thread(switch_core_session_t *session, switch_thread_start_t func, void *obj)
|
||||
{
|
||||
switch_thread_t *thread;
|
||||
|
@ -2945,6 +2962,17 @@ SWITCH_DECLARE(void) switch_core_session_raw_read(switch_core_session_t *session
|
|||
switch_core_session_set_codec_slin(session, session->sdata);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_session_override_io_routines(switch_core_session_t *session, switch_io_routines_t *ior)
|
||||
{
|
||||
if (session->endpoint_interface && switch_channel_test_cap(session->channel, CC_IO_OVERRIDE)) {
|
||||
session->io_override = ior;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
|
@ -219,6 +219,7 @@ static char *EVENT_NAMES[] = {
|
|||
"CALL_SETUP_RESULT",
|
||||
"CALL_DETAIL",
|
||||
"DEVICE_STATE",
|
||||
"REAL_TIME_TEXT",
|
||||
"ALL"
|
||||
};
|
||||
|
||||
|
|
|
@ -2728,7 +2728,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
|
|||
char tmp[512], *f;
|
||||
int cdr_off = 0, v_off = 0, cd_off = 0;
|
||||
switch_hold_record_t *hold_record = switch_channel_get_hold_record(channel), *hr;
|
||||
|
||||
const char *text_buffer = NULL;
|
||||
|
||||
if (*xml_cdr) {
|
||||
cdr = *xml_cdr;
|
||||
} else {
|
||||
|
@ -2750,6 +2751,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
|
|||
x_field = switch_xml_add_child_d(x_channel_data, "direction", cd_off++);
|
||||
switch_xml_set_txt_d(x_field, switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
|
||||
|
||||
|
||||
if ((text_buffer = switch_core_session_get_text_buffer(session))) {
|
||||
x_field = switch_xml_add_child_d(x_channel_data, "textlog", cd_off++);
|
||||
switch_xml_set_txt_d(x_field, text_buffer);
|
||||
}
|
||||
|
||||
x_field = switch_xml_add_child_d(x_channel_data, "state_number", cd_off++);
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
|
||||
switch_xml_set_txt_d(x_field, tmp);
|
||||
|
|
|
@ -663,6 +663,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
|
|||
}
|
||||
|
||||
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
|
||||
switch_channel_set_flag(channel, CF_TEXT_ECHO);
|
||||
|
||||
while (switch_channel_ready(channel)) {
|
||||
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
@ -717,6 +718,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
|
|||
|
||||
switch_core_session_video_reset(session);
|
||||
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
|
||||
switch_channel_clear_flag(channel, CF_TEXT_ECHO);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1525,6 +1527,84 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
|
|||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static switch_bool_t text_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case SWITCH_ABC_TYPE_READ_TEXT:
|
||||
{
|
||||
const char *text = switch_core_media_bug_get_text(bug);
|
||||
|
||||
|
||||
if (!zstr(text)) {
|
||||
switch_event_t *event = NULL;
|
||||
switch_core_session_t *session = switch_core_media_bug_get_session(bug);
|
||||
//switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (switch_event_create(&event, SWITCH_EVENT_REAL_TIME_TEXT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_body(event, text, SWITCH_VA_NONE);
|
||||
|
||||
if (switch_true(switch_core_get_variable("fire_text_events"))) {
|
||||
switch_event_t *clone = NULL;
|
||||
|
||||
switch_event_dup(&clone, event);
|
||||
switch_event_fire(&clone);
|
||||
}
|
||||
|
||||
switch_core_session_queue_event(session, &event);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_capture_text(switch_core_session_t *session, switch_bool_t on)
|
||||
{
|
||||
switch_media_bug_t *bug;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "capture_text");
|
||||
|
||||
if (on) {
|
||||
|
||||
if (bug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text bug already attached\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (switch_core_media_bug_add(session, "capture_text", switch_core_session_get_uuid(session),
|
||||
text_callback, NULL, 0,
|
||||
SMBF_READ_TEXT_STREAM,
|
||||
&bug) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_channel_set_private(channel, "capture_text", bug);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
if (bug) {
|
||||
switch_channel_set_private(channel, "capture_text", NULL);
|
||||
switch_core_media_bug_remove(session, &bug);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text bug not attached\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_record_session_mask(switch_core_session_t *session, const char *file, switch_bool_t on)
|
||||
{
|
||||
switch_media_bug_t *bug;
|
||||
|
|
|
@ -39,13 +39,39 @@ static void cleanup_proxy_mode_b(switch_core_session_t *session);
|
|||
/* Bridge Related Stuff*/
|
||||
/*********************************************************************************/
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
struct vid_helper {
|
||||
switch_core_session_t *session_a;
|
||||
switch_core_session_t *session_b;
|
||||
int up;
|
||||
};
|
||||
|
||||
|
||||
static void text_bridge_thread(switch_core_session_t *session, void *obj)
|
||||
{
|
||||
struct vid_helper *vh = obj;
|
||||
switch_status_t status;
|
||||
switch_frame_t *read_frame = 0;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(vh->session_a);
|
||||
switch_channel_t *b_channel = switch_core_session_get_channel(vh->session_b);
|
||||
|
||||
vh->up = 1;
|
||||
|
||||
while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
|
||||
status = switch_core_session_read_text_frame(vh->session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (SWITCH_READ_ACCEPTABLE(status) && !switch_test_flag(read_frame, SFF_CNG)) {
|
||||
switch_core_session_write_text_frame(vh->session_b, read_frame, 0, 0);
|
||||
}
|
||||
|
||||
switch_core_session_write_text_frame(vh->session_a, NULL, 0, 0);
|
||||
}
|
||||
|
||||
vh->up = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
|
||||
static void video_bridge_thread(switch_core_session_t *session, void *obj)
|
||||
{
|
||||
struct vid_helper *vh = obj;
|
||||
|
@ -156,7 +182,7 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
|
|||
|
||||
static void launch_video(struct vid_helper *vh)
|
||||
{
|
||||
switch_core_media_start_video_function(vh->session_a, video_bridge_thread, vh);
|
||||
switch_core_media_start_engine_function(vh->session_a, SWITCH_MEDIA_TYPE_VIDEO, video_bridge_thread, vh);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -267,6 +293,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
const char *exec_app = NULL;
|
||||
const char *exec_data = NULL;
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
uint32_t txt_launch = 0;
|
||||
struct vid_helper th = { 0 };
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
struct vid_helper vh = { 0 };
|
||||
|
@ -382,6 +410,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
|
||||
bridge_filter_dtmf = switch_true(switch_channel_get_variable(chan_a, "bridge_filter_dtmf"));
|
||||
|
||||
|
||||
for (;;) {
|
||||
switch_channel_state_t b_state;
|
||||
switch_status_t status;
|
||||
|
@ -445,6 +474,16 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(chan_a, CF_TEXT) && switch_channel_test_flag(chan_b, CF_TEXT) && !txt_launch) {
|
||||
txt_launch++;
|
||||
|
||||
th.session_a = session_a;
|
||||
th.session_b = session_b;
|
||||
switch_core_media_start_engine_function(th.session_a, SWITCH_MEDIA_TYPE_TEXT, text_bridge_thread, &th);
|
||||
|
||||
}
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) && !vid_launch) {
|
||||
vid_launch++;
|
||||
|
@ -649,6 +688,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
|
||||
end_of_bridge_loop:
|
||||
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
if (vh.up > 0) {
|
||||
vh.up = -1;
|
||||
|
@ -693,8 +733,18 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
|
||||
end:
|
||||
|
||||
|
||||
if (switch_core_media_check_engine_function(session_a, SWITCH_MEDIA_TYPE_TEXT)) {
|
||||
if (th.up == 1) {
|
||||
th.up = -1;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending text thread.\n");
|
||||
switch_core_media_end_engine_function(session_a, SWITCH_MEDIA_TYPE_TEXT);
|
||||
}
|
||||
|
||||
#ifdef SWITCH_VIDEO_IN_THREADS
|
||||
if (switch_core_media_check_video_function(session_a)) {
|
||||
if (switch_core_media_check_engine_function(session_a, SWITCH_MEDIA_TYPE_VIDEO)) {
|
||||
if (vh.up == 1) {
|
||||
vh.up = -1;
|
||||
}
|
||||
|
@ -705,7 +755,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
|
||||
switch_core_media_end_video_function(session_a);
|
||||
switch_core_media_end_engine_function(session_a, SWITCH_MEDIA_TYPE_VIDEO);
|
||||
switch_channel_clear_flag(chan_a, CF_NOT_READY);
|
||||
switch_channel_clear_flag(chan_b, CF_NOT_READY);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#define PERIOD_LEN 250
|
||||
#define MAX_FRAME_PADDING 2
|
||||
#define MAX_MISSING_SEQ 20
|
||||
#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->complete_frames, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__)
|
||||
#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->complete_frames, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__)
|
||||
|
||||
//const char *TOKEN_1 = "ONE";
|
||||
//const char *TOKEN_2 = "TWO";
|
||||
|
@ -101,6 +101,8 @@ struct switch_jb_s {
|
|||
switch_jb_type_t type;
|
||||
switch_core_session_t *session;
|
||||
switch_channel_t *channel;
|
||||
uint32_t buffer_lag;
|
||||
uint32_t flush;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1117,7 +1119,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
|
|||
|
||||
if (!want) want = got;
|
||||
|
||||
if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO) {
|
||||
if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO || jb->type == SJB_TEXT) {
|
||||
jb->next_seq = htons(got + 1);
|
||||
} else {
|
||||
|
||||
|
@ -1203,12 +1205,26 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||
switch_mutex_lock(jb->mutex);
|
||||
|
||||
if (jb->complete_frames == 0) {
|
||||
jb->flush = 0;
|
||||
switch_goto_status(SWITCH_STATUS_BREAK, end);
|
||||
}
|
||||
|
||||
if (jb->complete_frames < jb->frame_len) {
|
||||
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
|
||||
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
|
||||
|
||||
if (jb->type == SJB_TEXT) {
|
||||
if (jb->complete_frames && !jb->buffer_lag) {
|
||||
jb->buffer_lag = 10;
|
||||
}
|
||||
|
||||
if (jb->buffer_lag && --jb->buffer_lag == 0) {
|
||||
jb->flush = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jb->flush) {
|
||||
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
|
||||
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
|
||||
}
|
||||
}
|
||||
|
||||
jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||
|
@ -1254,8 +1270,8 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
|
||||
|
||||
|
@ -1263,7 +1279,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||
jb_debug(jb, 2, "Miss percent %02f too high, resetting buffer.\n", jb->period_miss_pct);
|
||||
switch_jb_reset(jb);
|
||||
}
|
||||
|
||||
|
||||
if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
|
||||
jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq));
|
||||
|
||||
|
@ -1272,7 +1288,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
|||
jb->highest_read_seq = node->packet.header.seq;
|
||||
}
|
||||
|
||||
if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) {
|
||||
if (jb->type == SJB_TEXT || (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts)))) {
|
||||
jb->complete_frames--;
|
||||
jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes);
|
||||
jb->highest_read_ts = node->packet.header.ts;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -520,7 +520,7 @@ typedef enum {
|
|||
static void do_2833(switch_rtp_t *rtp_session);
|
||||
|
||||
|
||||
#define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio"
|
||||
#define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_TEXT] ? "text" : (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio")
|
||||
|
||||
|
||||
static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, const char *host, switch_port_t port)
|
||||
|
@ -1287,7 +1287,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
|
|||
msg.message_id = SWITCH_MESSAGE_INDICATE_STUN_ERROR;
|
||||
switch_core_session_receive_message(rtp_session->session, &msg);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG,
|
||||
"STUN/ICE binding error received on %s channel\n", rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio");
|
||||
"STUN/ICE binding error received on %s channel\n", rtp_type(rtp_session));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3192,7 +3192,7 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
|
|||
ret = SSL_get_error(dtls->ssl, ret);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS packet read err %d\n", rtp_type(rtp_session), ret);
|
||||
}
|
||||
|
||||
|
||||
if (dtls_states[dtls->state]) {
|
||||
r = dtls_states[dtls->state](rtp_session, dtls);
|
||||
}
|
||||
|
@ -3396,8 +3396,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
|
|||
//SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_NONE, NULL);
|
||||
|
||||
SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL");
|
||||
|
||||
SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ECDH:!RC4:!SSLv3:RSA_WITH_AES_128_CBC_SHA");
|
||||
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ECDHE-RSA-AES256-GCM-SHA384");
|
||||
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
|
||||
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "SUITEB128");
|
||||
SSL_CTX_set_read_ahead(dtls->ssl_ctx, 1);
|
||||
#ifdef HAVE_OPENSSL_DTLS_SRTP
|
||||
//SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32");
|
||||
SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80");
|
||||
|
@ -3456,11 +3459,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
|
|||
SSL_set_verify(dtls->ssl, SSL_VERIFY_NONE, NULL);
|
||||
SSL_set_app_data(dtls->ssl, dtls);
|
||||
|
||||
BIO_ctrl(dtls->read_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
|
||||
BIO_ctrl(dtls->write_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
|
||||
SSL_set_mtu(dtls->ssl, 1400);
|
||||
BIO_ctrl(dtls->write_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
|
||||
BIO_ctrl(dtls->read_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
|
||||
//BIO_ctrl(dtls->read_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
|
||||
//BIO_ctrl(dtls->write_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
|
||||
//SSL_set_mtu(dtls->ssl, 1400);
|
||||
//BIO_ctrl(dtls->write_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
|
||||
//BIO_ctrl(dtls->read_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
|
||||
|
||||
|
||||
|
||||
|
@ -3654,7 +3657,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
|
|||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s RECV\n",
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP");
|
||||
rtp_type(rtp_session), idx ? "RTCP" : "RTP");
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 1;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating srtp [%d]\n", stat);
|
||||
|
@ -3676,7 +3679,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
|
|||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s SEND\n",
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP");
|
||||
rtp_type(rtp_session), idx ? "RTCP" : "RTP");
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 1;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating SRTP [%d]\n", stat);
|
||||
|
@ -4085,11 +4088,11 @@ SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_se
|
|||
|
||||
SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session)
|
||||
{
|
||||
if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
|
||||
if (!switch_rtp_ready(rtp_session)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rtp_session->jb;
|
||||
return rtp_session->jb ? rtp_session->jb : rtp_session->vb;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
|
||||
|
@ -4145,13 +4148,13 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r
|
|||
}
|
||||
|
||||
if (!max_frames || frames >= max_frames) {
|
||||
max_frames = frames + 8;
|
||||
max_frames = frames * 10;
|
||||
}
|
||||
|
||||
rtp_session->last_max_vb_frames = max_frames;
|
||||
|
||||
if (!rtp_session->vb) {
|
||||
switch_jb_create(&rtp_session->vb, SJB_VIDEO, frames, max_frames, rtp_session->pool);
|
||||
switch_jb_create(&rtp_session->vb, rtp_session->flags[SWITCH_RTP_FLAG_TEXT] ? SJB_TEXT : SJB_VIDEO, frames, max_frames, rtp_session->pool);
|
||||
switch_jb_set_session(rtp_session->vb, rtp_session->session);
|
||||
} else {
|
||||
switch_jb_set_frames(rtp_session->vb, frames, max_frames);
|
||||
|
@ -4202,7 +4205,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
|
|||
}
|
||||
|
||||
if (max_queue_frames < queue_frames) {
|
||||
max_queue_frames = queue_frames * 6;
|
||||
max_queue_frames = queue_frames * 3;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5687,7 +5690,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
|||
switch_jb_destroy(&rtp_session->vb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rtp_session->has_rtp && *bytes) {
|
||||
uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc);
|
||||
|
||||
|
@ -5746,7 +5749,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
|||
}
|
||||
|
||||
if (!*bytes || rtp_session->has_rtp) {
|
||||
|
||||
|
||||
if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
|
||||
switch_status_t jstatus = switch_jb_get_packet(rtp_session->jb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes);
|
||||
|
||||
|
@ -5806,9 +5809,21 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (vstatus == SWITCH_STATUS_NOTFOUND && rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
|
||||
int pt = get_recv_payload(rtp_session);
|
||||
(*flags) |= SFF_PLC;
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
*bytes = switch_jb_get_last_read_len(rtp_session->vb);
|
||||
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
|
||||
if (pt > -1) {
|
||||
rtp_session->last_rtp_hdr.pt = pt;
|
||||
}
|
||||
}
|
||||
|
||||
if (vstatus == SWITCH_STATUS_SUCCESS) {
|
||||
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
|
||||
|
||||
if (!xcheck_jitter) {
|
||||
check_jitter(rtp_session);
|
||||
xcheck_jitter = *bytes;
|
||||
|
@ -5882,6 +5897,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack)
|
|||
|
||||
}
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
||||
|
||||
switch_rtp_write_raw(rtp_session, (void *) &send_msg, &bytes, SWITCH_FALSE);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq) + i);
|
||||
|
@ -6423,7 +6439,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
}
|
||||
|
||||
if (hot_socket && (rtp_session->hot_hits % 10) != 0) {
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
|
||||
///NOOP
|
||||
} else if (hot_socket && (rtp_session->hot_hits % 10) != 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10, "%s timer while HOT\n", rtp_session_name(rtp_session));
|
||||
switch_core_timer_next(&rtp_session->timer);
|
||||
} else if (hot_socket) {
|
||||
|
@ -6510,10 +6528,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
|
||||
|
||||
|
||||
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d\n", poll_status);
|
||||
//}
|
||||
|
||||
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) {
|
||||
return_cng_frame();
|
||||
}
|
||||
|
@ -6535,7 +6549,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
if (read_pretriggered) {
|
||||
read_pretriggered = 0;
|
||||
} else {
|
||||
|
||||
|
||||
status = read_rtp_packet(rtp_session, &bytes, flags, poll_status, SWITCH_TRUE);
|
||||
|
||||
if (status == SWITCH_STATUS_GENERR) {
|
||||
|
@ -6807,11 +6821,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
|
||||
if (bytes && rtp_session->last_rtp_hdr.m && rtp_session->last_rtp_hdr.pt != rtp_session->recv_te &&
|
||||
!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] &&
|
||||
!rtp_session->flags[SWITCH_RTP_FLAG_TEXT] &&
|
||||
!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) {
|
||||
rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
|
||||
}
|
||||
|
||||
|
||||
if (rtp_session->last_rtp_hdr.pt == rtp_session->cng_pt || rtp_session->last_rtp_hdr.pt == 13) {
|
||||
*flags |= SFF_NOT_AUDIO;
|
||||
} else {
|
||||
|
@ -6894,6 +6908,19 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
}
|
||||
}
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
|
||||
if (!bytes) {
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
|
||||
switch_core_timer_next(&rtp_session->timer);
|
||||
}
|
||||
return_cng_frame();
|
||||
} else {
|
||||
*payload_type = rtp_session->last_rtp_hdr.pt;
|
||||
ret = (int) bytes;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes && (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL])) {
|
||||
/* Fast PASS! */
|
||||
*flags |= SFF_PROXY_PACKET;
|
||||
|
@ -8065,14 +8092,19 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
|
|||
#endif
|
||||
}
|
||||
|
||||
if (switch_test_flag(frame, SFF_RTP_HEADER)) {
|
||||
switch_size_t wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
|
||||
frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
|
||||
|
||||
if (switch_test_flag(frame, SFF_RTP_HEADER) || rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
|
||||
switch_size_t wrote;
|
||||
|
||||
wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
|
||||
frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
|
||||
|
||||
rtp_session->stats.outbound.raw_bytes += wrote;
|
||||
rtp_session->stats.outbound.media_bytes += wrote;
|
||||
rtp_session->stats.outbound.media_packet_count++;
|
||||
rtp_session->stats.outbound.packet_count++;
|
||||
|
||||
return wrote;
|
||||
}
|
||||
|
||||
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {
|
||||
|
|
Loading…
Reference in New Issue