diff --git a/bigbluebutton-client/resources/prod/lib/verto.js b/bigbluebutton-client/resources/prod/lib/verto.js index 5b49416c8c..d213435ef6 100644 --- a/bigbluebutton-client/resources/prod/lib/verto.js +++ b/bigbluebutton-client/resources/prod/lib/verto.js @@ -35,11 +35,11 @@ function clearConfMan() { } function goto_dialog(where) { - $( ":mobile-pagecontainer" ).pagecontainer( "change", "#dialog-" + where, { role: "dialog" } ); + //$( ":mobile-pagecontainer" ).pagecontainer( "change", "#dialog-" + where, { role: "dialog" } ); } function goto_page(where, force) { - $( ":mobile-pagecontainer" ).pagecontainer( "change", "#page-" + where); + //$( ":mobile-pagecontainer" ).pagecontainer( "change", "#page-" + where); } var first_login = false; @@ -738,7 +738,7 @@ function pop(id, cname, dft) { function refresh_devices() { - +/* $("#useshare").selectmenu({}); $("#useshare").selectmenu({}); $("#usemic").selectmenu({}); @@ -799,447 +799,448 @@ function refresh_devices() $("input[type='checkbox']").checkboxradio("refresh"); //console.error($("#usecamera").find(":selected").val()); + */ } function init() { - cur_call = null; - - $("#usecamera").selectmenu({}); - $("#usemic").selectmenu({}); - $("#useshare").selectmenu({}); - - if (!autocall) { - pop("#ext", "verto_demo_ext", "3500"); - } - - pop("#cidname", "verto_demo_name", "FreeSWITCH User"); - pop("#cid", "verto_demo_cid", "1008"); - pop("#textto", "verto_demo_textto", "1000"); - - pop("#login", "verto_demo_login", "1008"); - pop("#passwd", "verto_demo_passwd", "1234"); - - pop("#hostName", "verto_demo_hostname", window.location.hostname); - pop("#wsURL", "verto_demo_wsurl", "wss://" + window.location.hostname + ":8082"); - - var tmp = $.cookie("verto_demo_vid_checked") || "true"; - $.cookie("verto_demo_vid_checked", tmp, { - expires: 365 - }); - - if (tmp !== "true") { - $("#camdiv").hide(); - $(".sharediv").hide(); - } else { - $(".sharediv").show(); - $("#camdiv").show(); - } - - $("#use_vid").prop("checked", tmp === "true").change(function(e) { - tmp = $("#use_vid").is(':checked'); - - if (!tmp) { - $("#camdiv").hide(); - $(".sharediv").hide(); - } else { - $("#camdiv").show(); - $(".sharediv").show(); - } - $.cookie("verto_demo_vid_checked", tmp ? "true" : "false", { - expires: 365 - }); - }); - - - tmp = $.cookie("verto_demo_dedenc_checked") || "false"; - $.cookie("verto_demo_dedenc_checked", tmp, { - expires: 365 - }); - - $("#use_dedenc").prop("checked", tmp === "true").change(function(e) { - tmp = $("#use_dedenc").is(':checked'); - - if (!tmp && $("#mirror_input").is(':checked')) { - $("#mirror_input").click(); - } - - $.cookie("verto_demo_dedenc_checked", tmp ? "true" : "false", { - expires: 365 - }); - }); - - - tmp = $.cookie("verto_demo_mirror_input_checked") || "false"; - $.cookie("verto_demo_mirror_input_checked", tmp, { - expires: 365 - }); - - $("#mirror_input").prop("checked", tmp === "true").change(function(e) { - tmp = $("#mirror_input").is(':checked'); - if (tmp && !$("#use_dedenc").is(':checked')) { - $("#use_dedenc").click(); - } - $.cookie("verto_demo_mirror_input_checked", tmp ? "true" : "false", { - expires: 365 - }); - }); - +// cur_call = null; // - outgoingBandwidth = $.cookie("verto_demo_outgoingBandwidth") || "default"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - - $("#outgoingBandwidth_250kb").prop("checked", outgoingBandwidth === "250").change(function(e) { - if ($("#outgoingBandwidth_250kb").is(':checked')) { - outgoingBandwidth = "250"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_500kb").prop("checked", outgoingBandwidth === "500").change(function(e) { - if ($("#outgoingBandwidth_500kb").is(':checked')) { - outgoingBandwidth = "500"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_1024kb").prop("checked", outgoingBandwidth === "1024").change(function(e) { - if ($("#outgoingBandwidth_1024kb").is(':checked')) { - outgoingBandwidth = "1024"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_1536kb").prop("checked", outgoingBandwidth === "1536").change(function(e) { - if ($("#outgoingBandwidth_1536kb").is(':checked')) { - outgoingBandwidth = "1536"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_2048kb").prop("checked", outgoingBandwidth === "2048").change(function(e) { - if ($("#outgoingBandwidth_2048kb").is(':checked')) { - outgoingBandwidth = "2048"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_5120kb").prop("checked", outgoingBandwidth === "5120").change(function(e) { - if ($("#outgoingBandwidth_5120kb").is(':checked')) { - outgoingBandwidth = "5120"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_0kb").prop("checked", outgoingBandwidth === "0").change(function(e) { - if ($("#outgoingBandwidth_0kb").is(':checked')) { - outgoingBandwidth = "0"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); - - $("#outgoingBandwidth_default").prop("checked", outgoingBandwidth === "default").change(function(e) { - if ($("#outgoingBandwidth_default").is(':checked')) { - outgoingBandwidth = "default"; - $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { - expires: 365 - }); - } - }); +// $("#usecamera").selectmenu({}); +// $("#usemic").selectmenu({}); +// $("#useshare").selectmenu({}); // - - incomingBandwidth = $.cookie("verto_demo_incomingBandwidth") || "default"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - - $("#incomingBandwidth_250kb").prop("checked", incomingBandwidth === "250").change(function(e) { - if ($("#incomingBandwidth_250kb").is(':checked')) { - incomingBandwidth = "250"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_500kb").prop("checked", incomingBandwidth === "500").change(function(e) { - if ($("#incomingBandwidth_500kb").is(':checked')) { - incomingBandwidth = "500"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_1024kb").prop("checked", incomingBandwidth === "1024").change(function(e) { - if ($("#incomingBandwidth_1024kb").is(':checked')) { - incomingBandwidth = "1024"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_1536kb").prop("checked", incomingBandwidth === "1536").change(function(e) { - if ($("#incomingBandwidth_1536kb").is(':checked')) { - incomingBandwidth = "1536"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_2048kb").prop("checked", incomingBandwidth === "2048").change(function(e) { - if ($("#incomingBandwidth_2048kb").is(':checked')) { - incomingBandwidth = "2048"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_5120kb").prop("checked", incomingBandwidth === "5120").change(function(e) { - if ($("#incomingBandwidth_5120kb").is(':checked')) { - incomingBandwidth = "5120"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_0kb").prop("checked", incomingBandwidth === "0").change(function(e) { - if ($("#incomingBandwidth_0kb").is(':checked')) { - incomingBandwidth = "0"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); - - $("#incomingBandwidth_default").prop("checked", incomingBandwidth === "default").change(function(e) { - if ($("#incomingBandwidth_default").is(':checked')) { - incomingBandwidth = "default"; - $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { - expires: 365 - }); - } - }); +// if (!autocall) { +// pop("#ext", "verto_demo_ext", "3500"); +// } // - - vqual = $.cookie("verto_demo_vqual") || "hd"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - - - - $("#vqual_qvga").prop("checked", vqual === "qvga").change(function(e) { - if ($("#vqual_qvga").is(':checked')) { - vqual = "qvga"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - } - }); - - - $("#vqual_vga").prop("checked", vqual === "vga").change(function(e) { - if ($("#vqual_vga").is(':checked')) { - vqual = "vga"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - } - }); - - - $("#vqual_qvga_wide").prop("checked", vqual === "qvga_wide").change(function(e) { - if ($("#vqual_qvga_wide").is(':checked')) { - vqual = "qvga_wide"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - } - }); - - - $("#vqual_vga_wide").prop("checked", vqual === "vga_wide").change(function(e) { - if ($("#vqual_vga_wide").is(':checked')) { - vqual = "vga_wide"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - } - }); - - - $("#vqual_hd").prop("checked", vqual === "hd").change(function(e) { - if ($("#vqual_hd").is(':checked')) { - vqual = "hd"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - } - }); - - - $("#vqual_hhd").prop("checked", vqual === "hhd").change(function(e) { - if ($("#vqual_hhd").is(':checked')) { - vqual = "hhd"; - $.cookie("verto_demo_vqual", vqual, { - expires: 365 - }); - } - }); - - - tmp = $.cookie("verto_demo_stereo_checked") || "true"; - $.cookie("verto_demo_stereo_checked", tmp, { - expires: 365 - }); - - $("#use_stereo").prop("checked", tmp === "true").change(function(e) { - tmp = $("#use_stereo").is(':checked'); - $.cookie("verto_demo_stereo_checked", tmp ? "true" : "false", { - expires: 365 - }); - }); - - tmp = $.cookie("verto_demo_stun_checked") || "true"; - $.cookie("verto_demo_stun_checked", tmp, { - expires: 365 - }); - - $("#use_stun").prop("checked", tmp === "true").change(function(e) { - tmp = $("#use_stun").is(':checked'); - $.cookie("verto_demo_stun_checked", tmp ? "true" : "false", { - expires: 365 - }); - if (verto) { - verto.iceServers(tmp); - } - }); - - - tmp = $.cookie("verto_demo_local_video_checked") || "false"; - $.cookie("verto_demo_local_video_checked", tmp, { - expires: 365 - }); - - $("#local_video").prop("checked", tmp === "true").change(function(e) { - tmp = $("#local_video").is(':checked'); - $.cookie("verto_demo_local_video_checked", tmp ? "true" : "false", { - expires: 365 - }); - if (verto) { - verto.iceServers(tmp); - } - }); - - check_vid_res(); - - verto = new $.verto({ - login: $("#login").val() + "@" + $("#hostName").val(), - passwd: $("#passwd").val(), - socketUrl: $("#wsURL").val(), - tag: "webcam", - //localTag: $("#local_video").is(':checked') ? "local_webcam" : null, - ringFile: "sounds/bell_ring2.wav", - loginParams: {foo: true, bar: "yes"}, - videoParams: { - "minWidth": vid_width, - "minHeight": vid_height, - "maxWidth": vid_width, - "maxHeight": vid_height, - "minFrameRate": 15, - "vertoBestFrameRate": 30, - //chromeMediaSource: 'screen', - //mediaSource: 'screen' - }, -// audioParams: { -// googAutoGainControl: false, -// googNoiseSuppression: false, -// googHighpassFilter: false -// }, - - iceServers: $("#use_stun").is(':checked') - },callbacks); - - - $("#login").change(function(e) { - $("#cid").val(e.currentTarget.value); - $.cookie("verto_demo_cid", e.currentTarget.value, { - expires: 365 - }); - }); - - $("#vtxtbtn").click(function() { - verto.message({ - to: $("#textto").val(), - body: $("#textmsg").val() - }); - $("#textmsg").val(""); - }); - - $("#logoutbtn").click(function() { - verto.logout(); - online(false); - }); - - $("#loginbtn").click(function() { - online(false); - verto.loginData({ - login: $("#login").val() + "@" + $("#hostName").val(), - passwd: $("#passwd").val() - }); - verto.login(); - goto_page("main"); - }); - - $("#xferdiv").hide(); -// $("#webcam").hide(); - - online(false); - - setupChat(); - - $("#ext").keyup(function (event) { - if (event.keyCode == 13) { - $( "#callbtn" ).trigger( "click" ); - } - }); - - $(document).keypress(function(event) { - if (!(cur_call && event.target.id == "page-incall")) return; - var key = String.fromCharCode(event.keyCode); - var i = parseInt(key); - - - if (key === "#" || key === "*" || key === "0" || (i > 0 && i <= 9)) { - cur_call.dtmf(key); - } - }); - - if (window.location.hostname !== "webrtc.freeswitch.org") { - $("#directory").hide(); - } - - refresh_devices(); +// pop("#cidname", "verto_demo_name", "FreeSWITCH User"); +// pop("#cid", "verto_demo_cid", "1008"); +// pop("#textto", "verto_demo_textto", "1000"); +// +// pop("#login", "verto_demo_login", "1008"); +// pop("#passwd", "verto_demo_passwd", "1234"); +// +// pop("#hostName", "verto_demo_hostname", window.location.hostname); +// pop("#wsURL", "verto_demo_wsurl", "wss://" + window.location.hostname + ":8082"); +// +// var tmp = $.cookie("verto_demo_vid_checked") || "true"; +// $.cookie("verto_demo_vid_checked", tmp, { +// expires: 365 +// }); +// +// if (tmp !== "true") { +// $("#camdiv").hide(); +// $(".sharediv").hide(); +// } else { +// $(".sharediv").show(); +// $("#camdiv").show(); +// } +// +// $("#use_vid").prop("checked", tmp === "true").change(function(e) { +// tmp = $("#use_vid").is(':checked'); +// +// if (!tmp) { +// $("#camdiv").hide(); +// $(".sharediv").hide(); +// } else { +// $("#camdiv").show(); +// $(".sharediv").show(); +// } +// $.cookie("verto_demo_vid_checked", tmp ? "true" : "false", { +// expires: 365 +// }); +// }); +// +// +// tmp = $.cookie("verto_demo_dedenc_checked") || "false"; +// $.cookie("verto_demo_dedenc_checked", tmp, { +// expires: 365 +// }); +// +// $("#use_dedenc").prop("checked", tmp === "true").change(function(e) { +// tmp = $("#use_dedenc").is(':checked'); +// +// if (!tmp && $("#mirror_input").is(':checked')) { +// $("#mirror_input").click(); +// } +// +// $.cookie("verto_demo_dedenc_checked", tmp ? "true" : "false", { +// expires: 365 +// }); +// }); +// +// +// tmp = $.cookie("verto_demo_mirror_input_checked") || "false"; +// $.cookie("verto_demo_mirror_input_checked", tmp, { +// expires: 365 +// }); +// +// $("#mirror_input").prop("checked", tmp === "true").change(function(e) { +// tmp = $("#mirror_input").is(':checked'); +// if (tmp && !$("#use_dedenc").is(':checked')) { +// $("#use_dedenc").click(); +// } +// $.cookie("verto_demo_mirror_input_checked", tmp ? "true" : "false", { +// expires: 365 +// }); +// }); +// +//// +// outgoingBandwidth = $.cookie("verto_demo_outgoingBandwidth") || "default"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// +// $("#outgoingBandwidth_250kb").prop("checked", outgoingBandwidth === "250").change(function(e) { +// if ($("#outgoingBandwidth_250kb").is(':checked')) { +// outgoingBandwidth = "250"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_500kb").prop("checked", outgoingBandwidth === "500").change(function(e) { +// if ($("#outgoingBandwidth_500kb").is(':checked')) { +// outgoingBandwidth = "500"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_1024kb").prop("checked", outgoingBandwidth === "1024").change(function(e) { +// if ($("#outgoingBandwidth_1024kb").is(':checked')) { +// outgoingBandwidth = "1024"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_1536kb").prop("checked", outgoingBandwidth === "1536").change(function(e) { +// if ($("#outgoingBandwidth_1536kb").is(':checked')) { +// outgoingBandwidth = "1536"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_2048kb").prop("checked", outgoingBandwidth === "2048").change(function(e) { +// if ($("#outgoingBandwidth_2048kb").is(':checked')) { +// outgoingBandwidth = "2048"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_5120kb").prop("checked", outgoingBandwidth === "5120").change(function(e) { +// if ($("#outgoingBandwidth_5120kb").is(':checked')) { +// outgoingBandwidth = "5120"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_0kb").prop("checked", outgoingBandwidth === "0").change(function(e) { +// if ($("#outgoingBandwidth_0kb").is(':checked')) { +// outgoingBandwidth = "0"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#outgoingBandwidth_default").prop("checked", outgoingBandwidth === "default").change(function(e) { +// if ($("#outgoingBandwidth_default").is(':checked')) { +// outgoingBandwidth = "default"; +// $.cookie("verto_demo_outgoingBandwidth", outgoingBandwidth, { +// expires: 365 +// }); +// } +// }); +//// +// +// incomingBandwidth = $.cookie("verto_demo_incomingBandwidth") || "default"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// +// $("#incomingBandwidth_250kb").prop("checked", incomingBandwidth === "250").change(function(e) { +// if ($("#incomingBandwidth_250kb").is(':checked')) { +// incomingBandwidth = "250"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_500kb").prop("checked", incomingBandwidth === "500").change(function(e) { +// if ($("#incomingBandwidth_500kb").is(':checked')) { +// incomingBandwidth = "500"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_1024kb").prop("checked", incomingBandwidth === "1024").change(function(e) { +// if ($("#incomingBandwidth_1024kb").is(':checked')) { +// incomingBandwidth = "1024"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_1536kb").prop("checked", incomingBandwidth === "1536").change(function(e) { +// if ($("#incomingBandwidth_1536kb").is(':checked')) { +// incomingBandwidth = "1536"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_2048kb").prop("checked", incomingBandwidth === "2048").change(function(e) { +// if ($("#incomingBandwidth_2048kb").is(':checked')) { +// incomingBandwidth = "2048"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_5120kb").prop("checked", incomingBandwidth === "5120").change(function(e) { +// if ($("#incomingBandwidth_5120kb").is(':checked')) { +// incomingBandwidth = "5120"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_0kb").prop("checked", incomingBandwidth === "0").change(function(e) { +// if ($("#incomingBandwidth_0kb").is(':checked')) { +// incomingBandwidth = "0"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +// +// $("#incomingBandwidth_default").prop("checked", incomingBandwidth === "default").change(function(e) { +// if ($("#incomingBandwidth_default").is(':checked')) { +// incomingBandwidth = "default"; +// $.cookie("verto_demo_incomingBandwidth", incomingBandwidth, { +// expires: 365 +// }); +// } +// }); +//// +// +// vqual = $.cookie("verto_demo_vqual") || "hd"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// +// +// +// $("#vqual_qvga").prop("checked", vqual === "qvga").change(function(e) { +// if ($("#vqual_qvga").is(':checked')) { +// vqual = "qvga"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// } +// }); +// +// +// $("#vqual_vga").prop("checked", vqual === "vga").change(function(e) { +// if ($("#vqual_vga").is(':checked')) { +// vqual = "vga"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// } +// }); +// +// +// $("#vqual_qvga_wide").prop("checked", vqual === "qvga_wide").change(function(e) { +// if ($("#vqual_qvga_wide").is(':checked')) { +// vqual = "qvga_wide"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// } +// }); +// +// +// $("#vqual_vga_wide").prop("checked", vqual === "vga_wide").change(function(e) { +// if ($("#vqual_vga_wide").is(':checked')) { +// vqual = "vga_wide"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// } +// }); +// +// +// $("#vqual_hd").prop("checked", vqual === "hd").change(function(e) { +// if ($("#vqual_hd").is(':checked')) { +// vqual = "hd"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// } +// }); +// +// +// $("#vqual_hhd").prop("checked", vqual === "hhd").change(function(e) { +// if ($("#vqual_hhd").is(':checked')) { +// vqual = "hhd"; +// $.cookie("verto_demo_vqual", vqual, { +// expires: 365 +// }); +// } +// }); +// +// +// tmp = $.cookie("verto_demo_stereo_checked") || "true"; +// $.cookie("verto_demo_stereo_checked", tmp, { +// expires: 365 +// }); +// +// $("#use_stereo").prop("checked", tmp === "true").change(function(e) { +// tmp = $("#use_stereo").is(':checked'); +// $.cookie("verto_demo_stereo_checked", tmp ? "true" : "false", { +// expires: 365 +// }); +// }); +// +// tmp = $.cookie("verto_demo_stun_checked") || "true"; +// $.cookie("verto_demo_stun_checked", tmp, { +// expires: 365 +// }); +// +// $("#use_stun").prop("checked", tmp === "true").change(function(e) { +// tmp = $("#use_stun").is(':checked'); +// $.cookie("verto_demo_stun_checked", tmp ? "true" : "false", { +// expires: 365 +// }); +// if (verto) { +// verto.iceServers(tmp); +// } +// }); +// +// +// tmp = $.cookie("verto_demo_local_video_checked") || "false"; +// $.cookie("verto_demo_local_video_checked", tmp, { +// expires: 365 +// }); +// +// $("#local_video").prop("checked", tmp === "true").change(function(e) { +// tmp = $("#local_video").is(':checked'); +// $.cookie("verto_demo_local_video_checked", tmp ? "true" : "false", { +// expires: 365 +// }); +// if (verto) { +// verto.iceServers(tmp); +// } +// }); +// +// check_vid_res(); +// +// verto = new $.verto({ +// login: $("#login").val() + "@" + $("#hostName").val(), +// passwd: $("#passwd").val(), +// socketUrl: $("#wsURL").val(), +// tag: "webcam", +// //localTag: $("#local_video").is(':checked') ? "local_webcam" : null, +// ringFile: "sounds/bell_ring2.wav", +// loginParams: {foo: true, bar: "yes"}, +// videoParams: { +// "minWidth": vid_width, +// "minHeight": vid_height, +// "maxWidth": vid_width, +// "maxHeight": vid_height, +// "minFrameRate": 15, +// "vertoBestFrameRate": 30, +// //chromeMediaSource: 'screen', +// //mediaSource: 'screen' +// }, +//// audioParams: { +//// googAutoGainControl: false, +//// googNoiseSuppression: false, +//// googHighpassFilter: false +//// }, +// +// iceServers: $("#use_stun").is(':checked') +// },callbacks); +// +// +// $("#login").change(function(e) { +// $("#cid").val(e.currentTarget.value); +// $.cookie("verto_demo_cid", e.currentTarget.value, { +// expires: 365 +// }); +// }); +// +// $("#vtxtbtn").click(function() { +// verto.message({ +// to: $("#textto").val(), +// body: $("#textmsg").val() +// }); +// $("#textmsg").val(""); +// }); +// +// $("#logoutbtn").click(function() { +// verto.logout(); +// online(false); +// }); +// +// $("#loginbtn").click(function() { +// online(false); +// verto.loginData({ +// login: $("#login").val() + "@" + $("#hostName").val(), +// passwd: $("#passwd").val() +// }); +// verto.login(); +// goto_page("main"); +// }); +// +// $("#xferdiv").hide(); +//// $("#webcam").hide(); +// +// online(false); +// +// setupChat(); +// +// $("#ext").keyup(function (event) { +// if (event.keyCode == 13) { +// $( "#callbtn" ).trigger( "click" ); +// } +// }); +// +// $(document).keypress(function(event) { +// if (!(cur_call && event.target.id == "page-incall")) return; +// var key = String.fromCharCode(event.keyCode); +// var i = parseInt(key); +// +// +// if (key === "#" || key === "*" || key === "0" || (i > 0 && i <= 9)) { +// cur_call.dtmf(key); +// } +// }); +// +// if (window.location.hostname !== "webrtc.freeswitch.org") { +// $("#directory").hide(); +// } +// +// refresh_devices(); } $(window).load(function() { diff --git a/bigbluebutton-client/resources/prod/lib/verto_extension.js b/bigbluebutton-client/resources/prod/lib/verto_extension.js index 6d757c24dc..e4f4c3b8b0 100755 --- a/bigbluebutton-client/resources/prod/lib/verto_extension.js +++ b/bigbluebutton-client/resources/prod/lib/verto_extension.js @@ -45,11 +45,11 @@ function callIntoConference(voiceBridge, conferenceUsername, conferenceIdNumber, console.log("11111"); callbacks.onWSClose = function(v, success) { console.log("22222"); - console.log("33333"); - if(toDisplayDisconnectCallback) { // will only display the error the first time - if(wasCallSuccessful) { // a call was established through the websocket - console.log("4444"); - // the connection was dropped in an already established call + console.log("33333"); + if(toDisplayDisconnectCallback) { // will only display the error the first time + if(wasCallSuccessful) { // a call was established through the websocket + console.log("4444"); + // the connection was dropped in an already established call console.log("websocket disconnected"); callback({'status':'failed', 'errorcode': 1001}); // WebSocket disconnected toDisplayDisconnectCallback = false; @@ -281,8 +281,8 @@ function makeVerto(callbacks, stunsConfig) { var vertoPort = "8082"; //var hostName = window.location.hostname; var hostName = "192.168.23.45"; - var socketUrl = "ws://" + hostName + ":5066"; - //var socketUrl = "wss://" + hostName + ":" + vertoPort; + //var socketUrl = "ws://" + hostName + ":5066"; + var socketUrl = "wss://" + hostName + ":" + vertoPort; var login = "1009"; var password = "fred"; var minWidth = "320"; diff --git a/bigbluebutton-client/resources/prod/lib/verto_extension_share.js b/bigbluebutton-client/resources/prod/lib/verto_extension_share.js index c0be535456..0fe8d27287 100755 --- a/bigbluebutton-client/resources/prod/lib/verto_extension_share.js +++ b/bigbluebutton-client/resources/prod/lib/verto_extension_share.js @@ -1,104 +1,2947 @@ -function screenStart(state, callback) { - console.log("2"); - //var imported = document.createElement('script'); - //imported.src = '/client/lib/verto.js'; - //document.head.appendChild(imported); +var iceTimerSent = 0; +var iceTimerCompleted = 0; +var iceTimer; +(function($) { + function findLine(sdpLines, prefix, substr) { + return findLineInRange(sdpLines, 0, -1, prefix, substr); + } - console.log("loggedIn=" + isLoggedIntoVerto()); - if(!isLoggedIntoVerto()) { // start the verto log in procedure - console.log("aaa"); - // runs when the websocket is successfully created - callbacks.onWSLogin = function(v, success) { - cur_call = true; - console.log("bbbb"); - doshare(state); - goto_page("main"); - console.log("logged in. starting screenshare"); - $("#webcam").show() - $("#webcam").css("z-index","1000") - } - console.log("ccc"); - // set up verto - $.verto.init({}, init); - } else { - console.log("ddddd"); - console.log("already logged into verto, going straight to making a call"); - cur_call = true; - doshare(state); - goto_page("main"); - $("#webcam").show() - $("#webcam").css("z-index","1000") - } + function findLineInRange(sdpLines, startLine, endLine, prefix, substr) { + var realEndLine = (endLine != -1) ? endLine : sdpLines.length; + for (var i = startLine; i < realEndLine; ++i) { + if (sdpLines[i].indexOf(prefix) === 0) { + if (!substr || sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) { + return i; + } + } + } + return null; + } - console.log("eee" + state); - if (state) { - callback({'status':'success', 'message': 'screenshare started'}); - } else { - callback({'status':'success', 'message': 'screenshare ended'}); - } -} + function getCodecPayloadType(sdpLine) { + var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); + var result = sdpLine.match(pattern); + return (result && result.length == 2) ? result[1] : null; + } -function doshare(on) { - if (!on) { - if (share_call) { - share_call.hangup(); - } - return; - } + 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.enabled = true; + this.mediaData = { + SDP: null, + profile: {}, + candidateList: [] + }; + if (moz) { + this.constraints = { + offerToReceiveAudio: true, + offerToReceiveVideo: this.options.useVideo ? true : false, + }; + } else { + this.constraints = { + optional: [{ + 'DtlsSrtpKeyAgreement': 'true' + }], + mandatory: { + OfferToReceiveAudio: true, + OfferToReceiveVideo: this.options.useVideo ? true : false, + } + }; + } + if (self.options.useVideo) { + self.options.useVideo.style.display = 'none'; + } + setCompat(); + checkCompat(); + }; + $.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; + } + } + 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) { + opusPayload = getCodecPayloadType(sdpLines[opusIndex]); + } + var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString()); + if (fmtpLineIndex === null) return sdp; + sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; stereo=1'); + sdp = sdpLines.join('\r\n'); + return sdp; + }; - if (share_call) { - return; - } + function setCompat() { + $.FSRTC.moz = !!navigator.mozGetUserMedia; + if (!navigator.getUserMedia) { + navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia; + } + } - $('#ext').trigger('change'); - $("#main_info").html("Trying"); - check_vid_res(); - outgoingBandwidth = "5120"; - incomingBandwidth = "5120"; + function checkCompat() { + if (!navigator.getUserMedia) { + alert('This application cannot function in this browser.'); + return false; + } + return true; + } - var sharedev = "screen"; - //var sharedev = $("#useshare").find(":selected").val(); + 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); + } - if (sharedev !== "screen") { - console.log("Attempting Screen Capture with non-screen device...."); - share_call = verto.newCall({ - destination_number: extension + "-screen", - caller_id_name: conferenceUsername + " (Screen)", - caller_id_number: conferenceIdNumber + " (screen)", - outgoingBandwidth: outgoingBandwidth, - incomingBandwidth: incomingBandwidth, - useCamera: sharedev, - useVideo: true, - screenShare: true, - dedEnc: $("#use_dedenc").is(':checked'), - mirrorInput: $("#mirror_input").is(':checked') - }); - return; - } + function onStreamSuccess(self, stream) { + console.log("Stream Success"); + doCallback(self, "onStream", stream); + } - getScreenId(function (error, sourceId, screen_constraints) { - console.log("Attempting Screen Capture...."); - share_call = verto.newCall({ - destination_number: extension + "-screen", - caller_id_name: conferenceUsername + " (Screen)", - caller_id_number: conferenceIdNumber + " (screen)", - // destination_number: extension, - // caller_id_name: conferenceUsername, - // caller_id_number: conferenceIdNumber, - outgoingBandwidth: outgoingBandwidth, - incomingBandwidth: incomingBandwidth, - videoParams: screen_constraints.video.mandatory, - useCamera: true, - useVideo: true, - screenShare: true, - dedEnc: true, - mirrorInput: true, - tag: "webcam" - }); - }); + function onICE(self, candidate) { + self.mediaData.candidate = candidate; + self.mediaData.candidateList.push(self.mediaData.candidate); + doCallback(self, "onICE"); + } -} -function vertoScreenStart() { - alert("start"); - screenStart(true, function(){}); -} + function doCallback(self, func, arg) { + if (func in self.options.callbacks) { + self.options.callbacks[func](self, arg); + } + } + + function onICEComplete(self, candidate) { + console.log("ICE Complete"); + doCallback(self, "onICEComplete"); + } + + function onChannelError(self, e) { + console.error("Channel Error", e); + doCallback(self, "onError", e); + } + + 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); + } + + 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; + } + + 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.stop = function() { + var self = this; + if (self.options.useVideo) { + self.options.useVideo.style.display = 'none'; + self.options.useVideo[moz ? 'mozSrcObject' : 'src'] = null; + } + if (self.localStream) { + self.localStream.stop(); + self.localStream = null; + } + if (self.options.localVideo) { + self.options.localVideo.style.display = 'none'; + self.options.localVideo[moz ? 'mozSrcObject' : 'src'] = null; + } + if (self.options.localVideoStream) { + self.options.localVideoStream.stop(); + } + if (self.peer) { + console.log("stopping peer"); + self.peer.stop(); + } + }; + $.FSRTC.prototype.getMute = function() { + var self = this; + return self.enabled; + } + $.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; + } + self.enabled = audioTracks[i].enabled; + } + return !self.enabled; + } + $.FSRTC.prototype.createAnswer = function(params) { + var self = this; + self.type = "answer"; + self.remoteSDP = params.sdp; + console.debug("inbound sdp: ", params.sdp); + self.options.useCamera = params.useCamera || "any"; + self.options.useMic = params.useMic || "any"; + + 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); + } + + 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.videoParams && obj.options.screenShare) { + console.error("SCREEN SHARE++"); + console.log(obj); + audio = false; + } else { + audio = { + mandatory: obj.options.audioParams, + optional: [] + }; + if (obj.options.useMic !== "any") { + audio.optional = [{ + sourceId: obj.options.useMic + }] + } + } + 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 = {}; + if (window.moz) { + video = obj.options.videoParams; + if (!video.width) video.width = video.minWidth; + if (!video.height) video.height = video.minHeight; + if (!video.frameRate) video.frameRate = video.minFrameRate; + } else { + video = { + mandatory: obj.options.videoParams, + optional: [] + } + } + /*var useVideo=obj.options.useVideo;if(useVideo&&obj.options.useCamera&&obj.options.useCamera!=="none"){if(obj.options.useCamera!=="any"){video.optional=[{sourceId:obj.options.useCamera}]}}else{video=null;useVideo=null;}*/ + return { + audio: audio, + video: video, + useVideo: true + }; + } + $.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; + 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) { + console.error("SKIP"); + } : 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(mediaParams); + console.log("Audio constraints", mediaParams.audio); + console.log("Video constraints", mediaParams.video); + getUserMedia({ + constraints: { + audio: mediaParams.audio, + video: mediaParams.video + }, + video: mediaParams.useVideo, + onsuccess: onSuccess, + onerror: onError + }); + }; + window.moz = !!navigator.mozGetUserMedia; + + function RTCPeerConnection(options) { + 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; + + + //todo Anton + peer.onicecandidate=function(event){ + if(event.candidate){options.onICE(event.candidate); + clearTimeout(iceTimer); + iceTimer=setTimeout(function(){ + iceTimerSent=1; + if(iceTimerCompleted==0){ + 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);}}}},1000);}else{if(iceTimerSent==0){clearTimeout(iceTimer);iceTimerCompleted=1;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);}}}}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i 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) { + if (func) return func(); + 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 + }; + if (window.moz) { + video = video.mandatory; + if (!video.width) video.width = video.minWidth; + if (!video.height) video.height = video.minHeight; + if (!video.frameRate) video.frameRate = video.minFrameRate; + } + getUserMedia({ + constraints: { + audio: ttl++ == 0, + video: video + }, + onsuccess: function(e) { + e.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 = []; + $.FSRTC.validRes = []; + resI = 0; + checkRes(cam, func); + } + $.FSRTC.checkPerms = function() { + getUserMedia({ + constraints: { + audio: true, + video: true, + }, + onsuccess: function(e) { + e.stop(); + console.info("media perm init complete"); + }, + onerror: function(e) { + console.error("media perm init error"); + } + }); + } +})(jQuery); +(function($) { + $.JsonRpcClient = function(options) { + var self = this; + this.options = $.extend({ + ajaxUrl: null, + socketUrl: null, + onmessage: null, + login: null, + passwd: null, + sessid: null, + loginParams: null, + userVariables: null, + getSocket: function(onmessage_cb) { + return self._getSocket(onmessage_cb); + } + }, options); + self.ws_cnt = 0; + this.wsOnMessage = function(event) { + self._wsOnMessage(event); + }; + }; + $.JsonRpcClient.prototype._ws_socket = null; + $.JsonRpcClient.prototype._ws_callbacks = {}; + $.JsonRpcClient.prototype._current_id = 1; + $.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) { + if (!params) { + params = {}; + } + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + var request = { + jsonrpc: '2.0', + method: method, + params: params, + id: this._current_id++ + }; + if (!success_cb) { + success_cb = function(e) { + console.log("Success: ", e); + }; + } + if (!error_cb) { + error_cb = function(e) { + console.log("Error: ", e); + }; + } + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request, success_cb, error_cb); + return; + } + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.call used with no websocket and no http endpoint."; + } + $.ajax({ + type: 'POST', + url: this.options.ajaxUrl, + data: $.toJSON(request), + dataType: 'json', + cache: false, + success: function(data) { + if ('error' in data) error_cb(data.error, this); + success_cb(data.result, this); + }, + error: function(jqXHR, textStatus, errorThrown) { + try { + var response = $.parseJSON(jqXHR.responseText); + if ('console' in window) console.log(response); + error_cb(response.error, this); + } catch (err) { + error_cb({ + error: jqXHR.responseText + }, this); + } + } + }); + }; + $.JsonRpcClient.prototype.notify = function(method, params) { + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + var request = { + jsonrpc: '2.0', + method: method, + params: params + }; + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request); + return; + } + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.notify used with no websocket and no http endpoint."; + } + $.ajax({ + type: 'POST', + url: this.options.ajaxUrl, + data: $.toJSON(request), + dataType: 'json', + cache: false + }); + }; + $.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) { + var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb); + callback(batch); + batch._execute(); + }; + $.JsonRpcClient.prototype.socketReady = function() { + if (this._ws_socket === null || this._ws_socket.readyState > 1) { + return false; + } + return true; + }; + $.JsonRpcClient.prototype.closeSocket = function() { + var self = this; + if (self.socketReady()) { + self._ws_socket.onclose = function(w) { + console.log("Closing Socket"); + }; + self._ws_socket.close(); + } + }; + $.JsonRpcClient.prototype.loginData = function(params) { + var self = this; + self.options.login = params.login; + self.options.passwd = params.passwd; + self.options.loginParams = params.loginParams; + self.options.userVariables = params.userVariables; + }; + $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { + var self = this; + if (self.to) { + clearTimeout(self.to); + } + if (!self.socketReady()) { + self.authing = false; + if (self._ws_socket) { + delete self._ws_socket; + } + self._ws_socket = new WebSocket(self.options.socketUrl); + if (self._ws_socket) { + self._ws_socket.onmessage = onmessage_cb; + self._ws_socket.onclose = function(w) { + if (!self.ws_sleep) { + self.ws_sleep = 1000; + } + if (self.options.onWSClose) { + self.options.onWSClose(self); + } + console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec"); + self.to = setTimeout(function() { + console.log("Attempting Reconnection...."); + self.connectSocket(onmessage_cb); + }, self.ws_sleep); + self.ws_cnt++; + if (self.ws_sleep < 3000 && (self.ws_cnt % 10) === 0) { + self.ws_sleep += 1000; + } + }; + self._ws_socket.onopen = function() { + if (self.to) { + clearTimeout(self.to); + } + self.ws_sleep = 1000; + self.ws_cnt = 0; + if (self.options.onWSConnect) { + self.options.onWSConnect(self); + } + var req; + while ((req = $.JsonRpcClient.q.pop())) { + self._ws_socket.send(req); + } + }; + } + } + return self._ws_socket ? true : false; + }; + $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { + if (this.options.socketUrl === null || !("WebSocket" in window)) return null; + this.connectSocket(onmessage_cb); + return this._ws_socket; + }; + $.JsonRpcClient.q = []; + $.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) { + var request_json = $.toJSON(request); + if (socket.readyState < 1) { + self = this; + $.JsonRpcClient.q.push(request_json); + } else { + socket.send(request_json); + } + if ('id' in request && typeof success_cb !== 'undefined') { + this._ws_callbacks[request.id] = { + request: request_json, + request_obj: request, + success_cb: success_cb, + error_cb: error_cb + }; + } + }; + $.JsonRpcClient.prototype._wsOnMessage = function(event) { + var response; + try { + response = $.parseJSON(event.data); + if (typeof response === 'object' && 'jsonrpc' in response && response.jsonrpc === '2.0') { + if ('result' in response && this._ws_callbacks[response.id]) { + var success_cb = this._ws_callbacks[response.id].success_cb; + delete this._ws_callbacks[response.id]; + success_cb(response.result, this); + return; + } else if ('error' in response && this._ws_callbacks[response.id]) { + var error_cb = this._ws_callbacks[response.id].error_cb; + var orig_req = this._ws_callbacks[response.id].request; + if (!self.authing && response.error.code == -32000 && self.options.login && self.options.passwd) { + self.authing = true; + this.call("login", { + login: self.options.login, + passwd: self.options.passwd, + loginParams: self.options.loginParams, + userVariables: self.options.userVariables + }, this._ws_callbacks[response.id].request_obj.method == "login" ? function(e) { + self.authing = false; + console.log("logged in"); + delete self._ws_callbacks[response.id]; + if (self.options.onWSLogin) { + self.options.onWSLogin(true, self); + } + } : function(e) { + self.authing = false; + console.log("logged in, resending request id: " + response.id); + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send(orig_req); + } + if (self.options.onWSLogin) { + self.options.onWSLogin(true, self); + } + }, function(e) { + console.log("error logging in, request id:", response.id); + delete self._ws_callbacks[response.id]; + error_cb(response.error, this); + if (self.options.onWSLogin) { + self.options.onWSLogin(false, self); + } + }); + return; + } + delete this._ws_callbacks[response.id]; + error_cb(response.error, this); + return; + } + } + } catch (err) { + console.log("ERROR: " + err); + return; + } + if (typeof this.options.onmessage === 'function') { + event.eventData = response; + if (!event.eventData) { + event.eventData = {}; + } + var reply = this.options.onmessage(event); + if (reply && typeof reply === "object" && event.eventData.id) { + var msg = { + jsonrpc: "2.0", + id: event.eventData.id, + result: reply + }; + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send($.toJSON(msg)); + } + } + } + }; + $.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) { + this._requests = []; + this.jsonrpcclient = jsonrpcclient; + this.all_done_cb = all_done_cb; + this.error_cb = typeof error_cb === 'function' ? error_cb : function() {}; + }; + $.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) { + if (!params) { + params = {}; + } + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + if (!success_cb) { + success_cb = function(e) { + console.log("Success: ", e); + }; + } + if (!error_cb) { + error_cb = function(e) { + console.log("Error: ", e); + }; + } + this._requests.push({ + request: { + jsonrpc: '2.0', + method: method, + params: params, + id: this.jsonrpcclient._current_id++ + }, + success_cb: success_cb, + error_cb: error_cb + }); + }; + $.JsonRpcClient._batchObject.prototype.notify = function(method, params) { + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + this._requests.push({ + request: { + jsonrpc: '2.0', + method: method, + params: params + } + }); + }; + $.JsonRpcClient._batchObject.prototype._execute = function() { + var self = this; + if (this._requests.length === 0) return; + var batch_request = []; + var handlers = {}; + var i = 0; + var call; + var success_cb; + var error_cb; + var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); + if (socket !== null) { + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + success_cb = ('success_cb' in call) ? call.success_cb : undefined; + error_cb = ('error_cb' in call) ? call.error_cb : undefined; + self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); + } + if (typeof all_done_cb === 'function') all_done_cb(result); + return; + } + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + batch_request.push(call.request); + if ('id' in call.request) { + handlers[call.request.id] = { + success_cb: call.success_cb, + error_cb: call.error_cb + }; + } + } + success_cb = function(data) { + self._batchCb(data, handlers, self.all_done_cb); + }; + if (self.jsonrpcclient.options.ajaxUrl === null) { + throw "$.JsonRpcClient.batch used with no websocket and no http endpoint."; + } + $.ajax({ + url: self.jsonrpcclient.options.ajaxUrl, + data: $.toJSON(batch_request), + dataType: 'json', + cache: false, + type: 'POST', + error: function(jqXHR, textStatus, errorThrown) { + self.error_cb(jqXHR, textStatus, errorThrown); + }, + success: success_cb + }); + }; + $.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) { + for (var i = 0; i < result.length; i++) { + var response = result[i]; + if ('error' in response) { + if (response.id === null || !(response.id in handlers)) { + if ('console' in window) console.log(response); + } else { + handlers[response.id].error_cb(response.error, this); + } + } else { + if (!(response.id in handlers) && 'console' in window) { + console.log(response); + } else { + handlers[response.id].success_cb(response.result, this); + } + } + } + if (typeof all_done_cb === 'function') all_done_cb(result); + }; +})(jQuery); +(function($) { + var sources = []; + var generateGUID = (typeof(window.crypto) !== 'undefined' && typeof(window.crypto.getRandomValues) !== 'undefined') ? function() { + var buf = new Uint16Array(8); + window.crypto.getRandomValues(buf); + var S4 = function(num) { + var ret = num.toString(16); + while (ret.length < 4) { + ret = "0" + ret; + } + return ret; + }; + return (S4(buf[0]) + S4(buf[1]) + "-" + S4(buf[2]) + "-" + S4(buf[3]) + "-" + S4(buf[4]) + "-" + S4(buf[5]) + S4(buf[6]) + S4(buf[7])); + } : function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, + v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + }; + $.verto = function(options, callbacks) { + var verto = this; + $.verto.saved.push(verto); + verto.options = $.extend({ + login: null, + passwd: null, + socketUrl: null, + tag: null, + localTag: null, + videoParams: {}, + audioParams: {}, + loginParams: {}, + userVariables: {}, + iceServers: false, + ringSleep: 6000 + }, options); + verto.sessid = $.cookie('verto_session_uuid') || generateGUID(); + $.cookie('verto_session_uuid', verto.sessid, { + expires: 1 + }); + verto.dialogs = {}; + verto.callbacks = callbacks || {}; + verto.eventSUBS = {}; + verto.rpcClient = new $.JsonRpcClient({ + login: verto.options.login, + passwd: verto.options.passwd, + socketUrl: verto.options.socketUrl, + loginParams: verto.options.loginParams, + userVariables: verto.options.userVariables, + sessid: verto.sessid, + onmessage: function(e) { + return verto.handleMessage(e.eventData); + }, + onWSConnect: function(o) { + o.call('login', {}); + }, + onWSLogin: function(success) { + if (verto.callbacks.onWSLogin) { + verto.callbacks.onWSLogin(verto, success); + } + }, + onWSClose: function(success) { + if (verto.callbacks.onWSClose) { + verto.callbacks.onWSClose(verto, success); + } + verto.purge(); + } + }); + if (verto.options.ringFile && verto.options.tag) { + verto.ringer = $("#" + verto.options.tag); + } + verto.rpcClient.call('login', {}); + }; + $.verto.prototype.videoParams = function(on) { + var verto = this; + verto.options.videoParams = on; + }; + $.verto.prototype.iceServers = function(on) { + var verto = this; + verto.options.iceServers = on; + }; + $.verto.prototype.loginData = function(params) { + var verto = this; + verto.options.login = params.login; + verto.options.passwd = params.passwd; + verto.rpcClient.loginData(params); + }; + $.verto.prototype.logout = function(msg) { + var verto = this; + verto.rpcClient.closeSocket(); + if (verto.callbacks.onWSClose) { + verto.callbacks.onWSClose(verto, false); + } + verto.purge(); + }; + $.verto.prototype.login = function(msg) { + var verto = this; + verto.logout(); + verto.rpcClient.call('login', {}); + }; + $.verto.prototype.message = function(msg) { + var verto = this; + var err = 0; + if (!msg.to) { + console.error("Missing To"); + err++; + } + if (!msg.body) { + console.error("Missing Body"); + err++; + } + if (err) { + return false; + } + verto.sendMethod("verto.info", { + msg: msg + }); + return true; + }; + $.verto.prototype.processReply = function(method, success, e) { + var verto = this; + var i; + switch (method) { + case "verto.subscribe": + for (i in e.unauthorizedChannels) { + drop_bad(verto, e.unauthorizedChannels[i]); + } + for (i in e.subscribedChannels) { + mark_ready(verto, e.subscribedChannels[i]); + } + break; + case "verto.unsubscribe": + break; + } + }; + $.verto.prototype.sendMethod = function(method, params) { + var verto = this; + verto.rpcClient.call(method, params, function(e) { + verto.processReply(method, true, e); + }, function(e) { + verto.processReply(method, false, e); + }); + }; + + function do_sub(verto, channel, obj) {} + + function drop_bad(verto, channel) { + console.error("drop unauthorized channel: " + channel); + delete verto.eventSUBS[channel]; + } + + function mark_ready(verto, channel) { + for (var j in verto.eventSUBS[channel]) { + verto.eventSUBS[channel][j].ready = true; + console.log("subscribed to channel: " + channel); + if (verto.eventSUBS[channel][j].readyHandler) { + verto.eventSUBS[channel][j].readyHandler(verto, channel); + } + } + } + var SERNO = 1; + + function do_subscribe(verto, channel, subChannels, sparams) { + var params = sparams || {}; + var local = params.local; + var obj = { + eventChannel: channel, + userData: params.userData, + handler: params.handler, + ready: false, + readyHandler: params.readyHandler, + serno: SERNO++ + }; + var isnew = false; + if (!verto.eventSUBS[channel]) { + verto.eventSUBS[channel] = []; + subChannels.push(channel); + isnew = true; + } + verto.eventSUBS[channel].push(obj); + if (local) { + obj.ready = true; + obj.local = true; + } + if (!isnew && verto.eventSUBS[channel][0].ready) { + obj.ready = true; + if (obj.readyHandler) { + obj.readyHandler(verto, channel); + } + } + return { + serno: obj.serno, + eventChannel: channel + }; + } + $.verto.prototype.subscribe = function(channel, sparams) { + var verto = this; + var r = []; + var subChannels = []; + var params = sparams || {}; + if (typeof(channel) === "string") { + r.push(do_subscribe(verto, channel, subChannels, params)); + } else { + for (var i in channel) { + r.push(do_subscribe(verto, channel, subChannels, params)); + } + } + if (subChannels.length) { + verto.sendMethod("verto.subscribe", { + eventChannel: subChannels.length == 1 ? subChannels[0] : subChannels, + subParams: params.subParams + }); + } + return r; + }; + $.verto.prototype.unsubscribe = function(handle) { + var verto = this; + var i; + if (!handle) { + for (i in verto.eventSUBS) { + if (verto.eventSUBS[i]) { + verto.unsubscribe(verto.eventSUBS[i]); + } + } + } else { + var unsubChannels = {}; + var sendChannels = []; + var channel; + if (typeof(handle) == "string") { + delete verto.eventSUBS[handle]; + unsubChannels[handle]++; + } else { + for (i in handle) { + if (typeof(handle[i]) == "string") { + channel = handle[i]; + delete verto.eventSUBS[channel]; + unsubChannels[channel]++; + } else { + var repl = []; + channel = handle[i].eventChannel; + for (var j in verto.eventSUBS[channel]) { + if (verto.eventSUBS[channel][j].serno == handle[i].serno) {} else { + repl.push(verto.eventSUBS[channel][j]); + } + } + verto.eventSUBS[channel] = repl; + if (verto.eventSUBS[channel].length === 0) { + delete verto.eventSUBS[channel]; + unsubChannels[channel]++; + } + } + } + } + for (var u in unsubChannels) { + console.log("Sending Unsubscribe for: ", u); + sendChannels.push(u); + } + if (sendChannels.length) { + verto.sendMethod("verto.unsubscribe", { + eventChannel: sendChannels.length == 1 ? sendChannels[0] : sendChannels + }); + } + } + }; + $.verto.prototype.broadcast = function(channel, params) { + var verto = this; + var msg = { + eventChannel: channel, + data: {} + }; + for (var i in params) { + msg.data[i] = params[i]; + } + verto.sendMethod("verto.broadcast", msg); + }; + $.verto.prototype.purge = function(callID) { + var verto = this; + var x = 0; + var i; + for (i in verto.dialogs) { + if (!x) { + console.log("purging dialogs"); + } + x++; + verto.dialogs[i].setState($.verto.enum.state.purge); + } + for (i in verto.eventSUBS) { + if (verto.eventSUBS[i]) { + console.log("purging subscription: " + i); + delete verto.eventSUBS[i]; + } + } + }; + $.verto.prototype.hangup = function(callID) { + var verto = this; + if (callID) { + var dialog = verto.dialogs[callID]; + if (dialog) { + dialog.hangup(); + } + } else { + for (var i in verto.dialogs) { + verto.dialogs[i].hangup(); + } + } + }; + $.verto.prototype.newCall = function(args, callbacks) { + var verto = this; + if (!verto.rpcClient.socketReady()) { + console.error("Not Connected..."); + return; + } + var dialog = new $.verto.dialog($.verto.enum.direction.outbound, this, args); + dialog.invite(); + if (callbacks) { + dialog.callbacks = callbacks; + } + return dialog; + }; + $.verto.prototype.handleMessage = function(data) { + var verto = this; + if (!(data && data.method)) { + console.error("Invalid Data", data); + return; + } + if (data.params.callID) { + var dialog = verto.dialogs[data.params.callID]; + if (data.method === "verto.attach" && dialog) { + delete dialog.verto.dialogs[dialog.callID]; + dialog.rtc.stop(); + dialog = null; + } + if (dialog) { + switch (data.method) { + case 'verto.bye': + dialog.hangup(data.params); + break; + case 'verto.answer': + dialog.handleAnswer(data.params); + break; + case 'verto.media': + dialog.handleMedia(data.params); + break; + case 'verto.display': + dialog.handleDisplay(data.params); + break; + case 'verto.info': + dialog.handleInfo(data.params); + break; + default: + console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", dialog, data.method); + break; + } + } else { + switch (data.method) { + case 'verto.attach': + data.params.attach = true; + if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { + data.params.useVideo = true; + } + if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { + data.params.useStereo = true; + } + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + dialog.setState($.verto.enum.state.recovering); + break; + case 'verto.invite': + if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { + data.params.wantVideo = true; + } + if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { + data.params.useStereo = true; + } + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + break; + default: + console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED"); + break; + } + } + return { + method: data.method + }; + } else { + switch (data.method) { + case 'verto.punt': + verto.purge(); + verto.logout(); + break; + case 'verto.event': + var list = null; + var key = null; + if (data.params) { + key = data.params.eventChannel; + } + if (key) { + list = verto.eventSUBS[key]; + if (!list) { + list = verto.eventSUBS[key.split(".")[0]]; + } + } + if (!list && key && key === verto.sessid) { + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.pvtEvent, data.params); + } + } else if (!list && key && verto.dialogs[key]) { + verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent, data.params); + } else if (!list) { + if (!key) { + key = "UNDEFINED"; + } + console.error("UNSUBBED or invalid EVENT " + key + " IGNORED"); + } else { + for (var i in list) { + var sub = list[i]; + if (!sub || !sub.ready) { + console.error("invalid EVENT for " + key + " IGNORED"); + } else if (sub.handler) { + sub.handler(verto, data.params, sub.userData); + } else if (verto.callbacks.onEvent) { + verto.callbacks.onEvent(verto, data.params, sub.userData); + } else { + console.log("EVENT:", data.params); + } + } + } + break; + case "verto.info": + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.info, data.params.msg); + } + console.debug("MESSAGE from: " + data.params.msg.from, data.params.msg.body); + break; + default: + console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", data.method); + break; + } + } + }; + var del_array = function(array, name) { + var r = []; + var len = array.length; + for (var i = 0; i < len; i++) { + if (array[i] != name) { + r.push(array[i]); + } + } + return r; + }; + var hashArray = function() { + var vha = this; + var hash = {}; + var array = []; + vha.reorder = function(a) { + array = a; + var h = hash; + hash = {}; + var len = array.length; + for (var i = 0; i < len; i++) { + var key = array[i]; + if (h[key]) { + hash[key] = h[key]; + delete h[key]; + } + } + h = undefined; + }; + vha.clear = function() { + hash = undefined; + array = undefined; + hash = {}; + array = []; + }; + vha.add = function(name, val, insertAt) { + var redraw = false; + if (!hash[name]) { + if (insertAt === undefined || insertAt < 0 || insertAt >= array.length) { + array.push(name); + } else { + var x = 0; + var n = []; + var len = array.length; + for (var i = 0; i < len; i++) { + if (x++ == insertAt) { + n.push(name); + } + n.push(array[i]); + } + array = undefined; + array = n; + n = undefined; + redraw = true; + } + } + hash[name] = val; + return redraw; + }; + vha.del = function(name) { + var r = false; + if (hash[name]) { + array = del_array(array, name); + delete hash[name]; + r = true; + } else { + console.error("can't del nonexistant key " + name); + } + return r; + }; + vha.get = function(name) { + return hash[name]; + }; + vha.order = function() { + return array; + }; + vha.hash = function() { + return hash; + }; + vha.indexOf = function(name) { + var len = array.length; + for (var i = 0; i < len; i++) { + if (array[i] == name) { + return i; + } + } + }; + vha.arrayLen = function() { + return array.length; + }; + vha.asArray = function() { + var r = []; + var len = array.length; + for (var i = 0; i < len; i++) { + var key = array[i]; + r.push(hash[key]); + } + return r; + }; + vha.each = function(cb) { + var len = array.length; + for (var i = 0; i < len; i++) { + cb(array[i], hash[array[i]]); + } + }; + vha.dump = function(html) { + var str = ""; + vha.each(function(name, val) { + str += "name: " + name + " val: " + JSON.stringify(val) + (html ? "
" : "\n"); + }); + return str; + }; + }; + $.verto.liveArray = function(verto, context, name, config) { + var la = this; + var lastSerno = 0; + var binding = null; + var user_obj = config.userObj; + var local = false; + hashArray.call(la); + la._add = la.add; + la._del = la.del; + la._reorder = la.reorder; + la._clear = la.clear; + la.context = context; + la.name = name; + la.user_obj = user_obj; + la.verto = verto; + la.broadcast = function(channel, obj) { + verto.broadcast(channel, obj); + }; + la.errs = 0; + la.clear = function() { + la._clear(); + lastSerno = 0; + if (la.onChange) { + la.onChange(la, { + action: "clear" + }); + } + }; + la.checkSerno = function(serno) { + if (serno < 0) { + return true; + } + if (lastSerno > 0 && serno != (lastSerno + 1)) { + if (la.onErr) { + la.onErr(la, { + lastSerno: lastSerno, + serno: serno + }); + } + la.errs++; + console.debug(la.errs); + if (la.errs < 3) { + la.bootstrap(la.user_obj); + } + return false; + } else { + lastSerno = serno; + return true; + } + }; + la.reorder = function(serno, a) { + if (la.checkSerno(serno)) { + la._reorder(a); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "reorder" + }); + } + } + }; + la.init = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "init", + index: index, + key: key, + data: val + }); + } + } + }; + la.bootObj = function(serno, val) { + if (la.checkSerno(serno)) { + for (var i in val) { + la._add(val[i][0], val[i][1]); + } + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "bootObj", + data: val, + redraw: true + }); + } + } + }; + la.add = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + var redraw = la._add(key, val, index); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "add", + index: index, + key: key, + data: val, + redraw: redraw + }); + } + } + }; + la.modify = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + la._add(key, val, index); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "modify", + key: key, + data: val, + index: index + }); + } + } + }; + la.del = function(serno, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + if (index === null || index < 0 || index === undefined) { + index = la.indexOf(key); + } + var ok = la._del(key); + if (ok && la.onChange) { + la.onChange(la, { + serno: serno, + action: "del", + key: key, + index: index + }); + } + } + }; + var eventHandler = function(v, e, la) { + var packet = e.data; + if (packet.name != la.name) { + return; + } + switch (packet.action) { + case "init": + la.init(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + break; + case "bootObj": + la.bootObj(packet.wireSerno, packet.data); + break; + case "add": + la.add(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + break; + case "modify": + if (!(packet.arrIndex || packet.hashKey)) { + console.error("Invalid Packet", packet); + } else { + la.modify(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + } + break; + case "del": + if (!(packet.arrIndex || packet.hashKey)) { + console.error("Invalid Packet", packet); + } else { + la.del(packet.wireSerno, packet.hashKey, packet.arrIndex); + } + break; + case "clear": + la.clear(); + break; + case "reorder": + la.reorder(packet.wireSerno, packet.order); + break; + default: + if (la.checkSerno(packet.wireSerno)) { + if (la.onChange) { + la.onChange(la, { + serno: packet.wireSerno, + action: packet.action, + data: packet.data + }); + } + } + break; + } + }; + if (la.context) { + binding = la.verto.subscribe(la.context, { + handler: eventHandler, + userData: la, + subParams: config.subParams + }); + } + la.destroy = function() { + la._clear(); + la.verto.unsubscribe(binding); + }; + la.sendCommand = function(cmd, obj) { + var self = la; + self.broadcast(self.context, { + liveArray: { + command: cmd, + context: self.context, + name: self.name, + obj: obj + } + }); + }; + la.bootstrap = function(obj) { + var self = la; + la.sendCommand("bootstrap", obj); + }; + la.changepage = function(obj) { + var self = la; + self.clear(); + self.broadcast(self.context, { + liveArray: { + command: "changepage", + context: la.context, + name: la.name, + obj: obj + } + }); + }; + la.heartbeat = function(obj) { + var self = la; + var callback = function() { + self.heartbeat.call(self, obj); + }; + self.broadcast(self.context, { + liveArray: { + command: "heartbeat", + context: self.context, + name: self.name, + obj: obj + } + }); + self.hb_pid = setTimeout(callback, 30000); + }; + la.bootstrap(la.user_obj); + }; + $.verto.liveTable = function(verto, context, name, jq, config) { + var dt; + var la = new $.verto.liveArray(verto, context, name, { + subParams: config.subParams + }); + var lt = this; + lt.liveArray = la; + lt.dataTable = dt; + lt.verto = verto; + lt.destroy = function() { + if (dt) { + dt.fnDestroy(); + } + if (la) { + la.destroy(); + } + dt = null; + la = null; + }; + la.onErr = function(obj, args) { + console.error("Error: ", obj, args); + }; + la.onChange = function(obj, args) { + var index = 0; + var iserr = 0; + if (!dt) { + if (!config.aoColumns) { + if (args.action != "init") { + return; + } + config.aoColumns = []; + for (var i in args.data) { + config.aoColumns.push({ + "sTitle": args.data[i] + }); + } + } + dt = jq.dataTable(config); + } + if (dt && (args.action == "del" || args.action == "modify")) { + index = args.index; + if (index === undefined && args.key) { + index = la.indexOf(args.key); + } + if (index === undefined) { + console.error("INVALID PACKET Missing INDEX\n", args); + return; + } + } + if (config.onChange) { + config.onChange(obj, args); + } + try { + switch (args.action) { + case "bootObj": + if (!args.data) { + console.error("missing data"); + return; + } + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + dt.fnAdjustColumnSizing(); + break; + case "add": + if (!args.data) { + console.error("missing data"); + return; + } + if (args.redraw > -1) { + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + } else { + dt.fnAddData(args.data); + } + dt.fnAdjustColumnSizing(); + break; + case "modify": + if (!args.data) { + return; + } + dt.fnUpdate(args.data, index); + dt.fnAdjustColumnSizing(); + break; + case "del": + dt.fnDeleteRow(index); + dt.fnAdjustColumnSizing(); + break; + case "clear": + dt.fnClearTable(); + break; + case "reorder": + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + break; + case "hide": + jq.hide(); + break; + case "show": + jq.show(); + break; + } + } catch (err) { + console.error("ERROR: " + err); + iserr++; + } + if (iserr) { + obj.errs++; + if (obj.errs < 3) { + obj.bootstrap(obj.user_obj); + } + } else { + obj.errs = 0; + } + }; + la.onChange(la, { + action: "init" + }); + }; + var CONFMAN_SERNO = 1; + $.verto.confMan = function(verto, params) { + var confMan = this; + confMan.params = $.extend({ + tableID: null, + statusID: null, + mainModID: null, + dialog: null, + hasVid: false, + laData: null, + onBroadcast: null, + onLaChange: null, + onLaRow: null + }, params); + confMan.verto = verto; + confMan.serno = CONFMAN_SERNO++; + + function genMainMod(jq) { + var play_id = "play_" + confMan.serno; + var stop_id = "stop_" + confMan.serno; + var recording_id = "recording_" + confMan.serno; + var snapshot_id = "snapshot_" + confMan.serno; + var rec_stop_id = "recording_stop" + confMan.serno; + var div_id = "confman_" + confMan.serno; + var html = "

" + "" + "" + "" + "" + + (confMan.params.hasVid ? "" : "") + "

"; + jq.html(html); + if (confMan.params.hasVid) { + var vlayout_id = "confman_vid_layout_" + confMan.serno; + var vlselect_id = "confman_vl_select_" + confMan.serno; + var vlhtml = "

" + "Video Layout " + "

"; + jq.append(vlhtml); + $("#" + vlselect_id).change(function() { + var val = $("#" + vlselect_id).find(":selected").val(); + if (val !== "none") { + confMan.modCommand("vid-layout", null, val); + } + }); + $("#" + snapshot_id).click(function() { + var file = prompt("Please enter file name", ""); + if (file) { + confMan.modCommand("vid-write-png", null, file); + } + }); + } + $("#" + play_id).click(function() { + var file = prompt("Please enter file name", ""); + if (file) { + confMan.modCommand("play", null, file); + } + }); + $("#" + stop_id).click(function() { + confMan.modCommand("stop", null, "all"); + }); + $("#" + recording_id).click(function() { + var file = prompt("Please enter file name", ""); + if (file) { + confMan.modCommand("recording", null, ["start", file]); + } + }); + $("#" + rec_stop_id).click(function() { + confMan.modCommand("recording", null, ["stop", "all"]); + }); + } + + function genControls(jq, rowid) { + var x = parseInt(rowid); + var kick_id = "kick_" + x; + var tmute_id = "tmute_" + x; + var tvmute_id = "tvmute_" + x; + var vbanner_id = "vbanner_" + x; + var tvpresenter_id = "tvpresenter_" + x; + var tvfloor_id = "tvfloor_" + x; + var box_id = "box_" + x; + var volup_id = "volume_in_up" + x; + var voldn_id = "volume_in_dn" + x; + var transfer_id = "transfer" + x; + var html = "
" + "" + "" + + (confMan.params.hasVid ? "" : "") + + (confMan.params.hasVid ? "" : "") + + (confMan.params.hasVid ? "" : "") + + (confMan.params.hasVid ? "" : "") + "" + "" + "" + "
"; + jq.html(html); + if (!jq.data("mouse")) { + $("#" + box_id).hide(); + } + jq.mouseover(function(e) { + jq.data({ + "mouse": true + }); + $("#" + box_id).show(); + }); + jq.mouseout(function(e) { + jq.data({ + "mouse": false + }); + $("#" + box_id).hide(); + }); + $("#" + transfer_id).click(function() { + var xten = prompt("Enter Extension"); + if (xten) { + confMan.modCommand("transfer", x, xten); + } + }); + $("#" + kick_id).click(function() { + confMan.modCommand("kick", x); + }); + $("#" + tmute_id).click(function() { + confMan.modCommand("tmute", x); + }); + if (confMan.params.hasVid) { + $("#" + tvmute_id).click(function() { + confMan.modCommand("tvmute", x); + }); + $("#" + tvpresenter_id).click(function() { + confMan.modCommand("vid-res-id", x, "presenter"); + }); + $("#" + tvfloor_id).click(function() { + confMan.modCommand("vid-floor", x, "force"); + }); + $("#" + vbanner_id).click(function() { + var text = prompt("Please enter text", ""); + if (text) { + confMan.modCommand("vid-banner", x, escape(text)); + } + }); + } + $("#" + volup_id).click(function() { + confMan.modCommand("volume_in", x, "up"); + }); + $("#" + voldn_id).click(function() { + confMan.modCommand("volume_in", x, "down"); + }); + return html; + } + var atitle = ""; + var awidth = 0; + if (confMan.params.laData.role === "moderator") { + atitle = "Action"; + awidth = 300; + if (confMan.params.mainModID) { + genMainMod($(confMan.params.mainModID)); + $(confMan.params.displayID).html("Moderator Controls Ready

"); + } else { + $(confMan.params.mainModID).html(""); + } + verto.subscribe(confMan.params.laData.modChannel, { + handler: function(v, e) { + if (confMan.params.onBroadcast) { + confMan.params.onBroadcast(verto, confMan, e.data); + } + if (e.data["conf-command"] === "list-videoLayouts") { + var vlselect_id = "#confman_vl_select_" + confMan.serno; + var vlayout_id = "#confman_vid_layout_" + confMan.serno; + var x = 0; + var options; + $(vlselect_id).selectmenu({}); + $(vlselect_id).selectmenu("enable"); + $(vlselect_id).empty(); + $(vlselect_id).append(new Option("Choose a Layout", "none")); + if (e.data.responseData) { + options = e.data.responseData.sort(); + for (var i in options) { + $(vlselect_id).append(new Option(options[i], options[i])); + x++; + } + } + if (x) { + $(vlselect_id).selectmenu('refresh', true); + } else { + $(vlayout_id).hide(); + } + } else { + if (!confMan.destroyed && confMan.params.displayID) { + $(confMan.params.displayID).html(e.data.response + "

"); + if (confMan.lastTimeout) { + clearTimeout(confMan.lastTimeout); + confMan.lastTimeout = 0; + } + confMan.lastTimeout = setTimeout(function() { + $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready

"); + }, 4000); + } + } + } + }); + if (confMan.params.hasVid) { + confMan.modCommand("list-videoLayouts", null, null); + } + } + var row_callback = null; + if (confMan.params.laData.role === "moderator") { + row_callback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { + if (!aData[5]) { + var $row = $('td:eq(5)', nRow); + genControls($row, aData); + if (confMan.params.onLaRow) { + confMan.params.onLaRow(verto, confMan, $row, aData); + } + } + }; + } + confMan.lt = new $.verto.liveTable(verto, confMan.params.laData.laChannel, confMan.params.laData.laName, $(confMan.params.tableID), { + subParams: { + callID: confMan.params.dialog ? confMan.params.dialog.callID : null + }, + "onChange": function(obj, args) { + $(confMan.params.statusID).text("Conference Members: " + " (" + obj.arrayLen() + " Total)"); + if (confMan.params.onLaChange) { + confMan.params.onLaChange(verto, confMan, $.verto.enum.confEvent.laChange, obj, args); + } + }, + "aaData": [], + "aoColumns": [{ + "sTitle": "ID" + }, { + "sTitle": "Number" + }, { + "sTitle": "Name" + }, { + "sTitle": "Codec" + }, { + "sTitle": "Status", + "sWidth": confMan.params.hasVid ? "200px" : "150px" + }, { + "sTitle": atitle, + "sWidth": awidth, + }], + "bAutoWidth": true, + "bDestroy": true, + "bSort": false, + "bInfo": false, + "bFilter": false, + "bLengthChange": false, + "bPaginate": false, + "iDisplayLength": 1000, + "oLanguage": { + "sEmptyTable": "The Conference is Empty....." + }, + "fnRowCallback": row_callback + }); + }; + $.verto.confMan.prototype.modCommand = function(cmd, id, value) { + var confMan = this; + confMan.verto.rpcClient.call("verto.broadcast", { + "eventChannel": confMan.params.laData.modChannel, + "data": { + "application": "conf-control", + "command": cmd, + "id": id, + "value": value + } + }); + }; + $.verto.confMan.prototype.destroy = function() { + var confMan = this; + confMan.destroyed = true; + if (confMan.lt) { + confMan.lt.destroy(); + } + if (confMan.params.laData.modChannel) { + confMan.verto.unsubscribe(confMan.params.laData.modChannel); + } + if (confMan.params.mainModID) { + $(confMan.params.mainModID).html(""); + } + }; + $.verto.dialog = function(direction, verto, params) { + var dialog = this; + dialog.params = $.extend({ + useVideo: verto.options.useVideo, + useStereo: verto.options.useStereo, + screenShare: false, + useCamera: "any", + useMic: "any", + tag: verto.options.tag, + localTag: verto.options.localTag, + login: verto.options.login, + videoParams: verto.options.videoParams + }, params); + dialog.verto = verto; + dialog.direction = direction; + dialog.lastState = null; + dialog.state = dialog.lastState = $.verto.enum.state.new; + dialog.callbacks = verto.callbacks; + dialog.answered = false; + dialog.attach = params.attach || false; + dialog.screenShare = params.screenShare || false; + dialog.useCamera = params.useCamera; + dialog.useMic = params.useMic; + if (dialog.params.callID) { + dialog.callID = dialog.params.callID; + } else { + dialog.callID = dialog.params.callID = generateGUID(); + } + if (dialog.params.tag) { + dialog.audioStream = document.getElementById(dialog.params.tag); + if (dialog.params.useVideo) { + dialog.videoStream = dialog.audioStream; + } + } + if (dialog.params.localTag) { + dialog.localVideo = document.getElementById(dialog.params.localTag); + } + dialog.verto.dialogs[dialog.callID] = dialog; + var RTCcallbacks = {}; + if (dialog.direction == $.verto.enum.direction.inbound) { + if (dialog.params.display_direction === "outbound") { + dialog.params.remote_caller_id_name = dialog.params.caller_id_name; + dialog.params.remote_caller_id_number = dialog.params.caller_id_number; + } else { + dialog.params.remote_caller_id_name = dialog.params.callee_id_name; + dialog.params.remote_caller_id_number = dialog.params.callee_id_number; + } + if (!dialog.params.remote_caller_id_name) { + dialog.params.remote_caller_id_name = "Nobody"; + } + 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) { + if (rtc.type == "offer") { + console.log("offer", rtc.mediaData.SDP); + 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.localVideo, + useVideo: dialog.videoStream, + 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 + }); + 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; + } + 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; + } + return false; + } + $.verto.dialog.prototype.setState = function(state) { + var dialog = this; + if (dialog.state == $.verto.enum.state.ringing) { + dialog.stopRinging(); + } + if (dialog.state == state || !checkStateChange(dialog.state, state)) { + console.error("Dialog " + dialog.callID + ": INVALID state change from " + dialog.state.name + " to " + state.name); + dialog.hangup(); + return false; + } + console.info("Dialog " + dialog.callID + ": state change from " + dialog.state.name + " to " + state.name); + dialog.lastState = dialog.state; + dialog.state = state; + if (!dialog.causeCode) { + dialog.causeCode = 16; + } + if (!dialog.cause) { + dialog.cause = "NORMAL CLEARING"; + } + if (dialog.callbacks.onDialogState) { + dialog.callbacks.onDialogState(this); + } + switch (dialog.state) { + case $.verto.enum.state.trying: + setTimeout(function() { + if (dialog.state == $.verto.enum.state.trying) { + dialog.setState($.verto.enum.state.hangup); + } + }, 30000); + break; + case $.verto.enum.state.purge: + dialog.setState($.verto.enum.state.destroy); + break; + case $.verto.enum.state.hangup: + if (dialog.lastState.val > $.verto.enum.state.requesting.val && dialog.lastState.val < $.verto.enum.state.hangup.val) { + dialog.sendMethod("verto.bye", {}); + } + dialog.setState($.verto.enum.state.destroy); + break; + case $.verto.enum.state.destroy: + delete dialog.verto.dialogs[dialog.callID]; + if (!dialog.params.screenShare) { + dialog.rtc.stop(); + } + break; + } + return true; + }; + $.verto.dialog.prototype.processReply = function(method, success, e) { + var dialog = this; + switch (method) { + case "verto.answer": + case "verto.attach": + if (success) { + dialog.setState($.verto.enum.state.active); + } else { + dialog.hangup(); + } + break; + case "verto.invite": + if (success) { + dialog.setState($.verto.enum.state.trying); + } else { + dialog.setState($.verto.enum.state.destroy); + } + break; + case "verto.bye": + dialog.hangup(); + break; + case "verto.modify": + if (e.holdState) { + if (e.holdState == "held") { + if (dialog.state != $.verto.enum.state.held) { + dialog.setState($.verto.enum.state.held); + } + } else if (e.holdState == "active") { + if (dialog.state != $.verto.enum.state.active) { + dialog.setState($.verto.enum.state.active); + } + } + } + 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(what) { + var dialog = this; + return dialog.rtc.getMute(what); + }; + $.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++; + } + 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 = {}; + } + params.sdp = dialog.params.sdp; + if (params) { + if (params.useVideo) { + dialog.useVideo(true); + } + dialog.params.callee_id_name = params.callee_id_name; + dialog.params.callee_id_number = params.callee_id_number; + } + 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 (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 + }, + 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 = []; + $(window).bind('beforeunload', function() { + for (var i in $.verto.saved) { + var verto = $.verto.saved[i]; + if (verto) { + verto.purge(); + verto.logout(); + } + } + return $.verto.warnOnUnload; + }); + $.verto.videoDevices = []; + $.verto.audioDevices = []; + var checkDevices = function(runtime) { + console.info("enumerating devices"); + var aud = [], + vid = []; + if (MediaStreamTrack.getSources) { + MediaStreamTrack.getSources(function(media_sources) { + for (var i = 0; i < media_sources.length; i++) { + console.log(media_sources[i]); + if (media_sources[i].kind == 'video') { + vid.push(media_sources[i]); + } else { + aud.push(media_sources[i]); + } + } + $.verto.videoDevices = vid; + $.verto.audioDevices = aud; + console.info("Audio Devices", $.verto.audioDevices); + console.info("Video Devices", $.verto.videoDevices); + runtime(); + }); + } else { + if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { + console.log("enumerateDevices() not supported."); + return; + } + 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 { + aud.push({ + id: device.deviceId, + kind: "audio", + label: device.label + }); + } + }); + $.verto.videoDevices = vid; + $.verto.audioDevices = aud; + console.info("Audio Devices", $.verto.audioDevices); + console.info("Video Devices", $.verto.videoDevices); + runtime(); + }).catch(function(err) { + console.log(err.name + ": " + error.message); + runtime(); + }); + } + }; + $.verto.init = function(obj, runtime) { + checkDevices(function() { + $.FSRTC.getValidRes(obj.camera, runtime); + }); + } +})(jQuery); \ No newline at end of file diff --git a/bigbluebutton-client/resources/prod/lib/verto_min.js b/bigbluebutton-client/resources/prod/lib/verto_min.js index d7ce44f911..0fe8d27287 100644 --- a/bigbluebutton-client/resources/prod/lib/verto_min.js +++ b/bigbluebutton-client/resources/prod/lib/verto_min.js @@ -1,263 +1,2947 @@ +var iceTimerSent = 0; +var iceTimerCompleted = 0; +var iceTimer; +(function($) { + function findLine(sdpLines, prefix, substr) { + return findLineInRange(sdpLines, 0, -1, prefix, substr); + } -var iceTimerSent=0;var iceTimerCompleted=0;var iceTimer;(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} - function findLineInRange(sdpLines,startLine,endLine,prefix,substr){var realEndLine=(endLine!=-1)?endLine:sdpLines.length;for(var i=startLine;iw&&$.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){if(func)return func();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};if(window.moz){video=video.mandatory;if(!video.width)video.width=video.minWidth;if(!video.height)video.height=video.minHeight;if(!video.frameRate)video.frameRate=video.minFrameRate;} - getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.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=[];$.FSRTC.validRes=[];resI=0;checkRes(cam,func);} - $.FSRTC.checkPerms=function(){getUserMedia({constraints:{audio:true,video:true,},onsuccess:function(e){e.stop();console.info("media perm init complete");},onerror:function(e){console.error("media perm init error");}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};} - if(this.options.sessid){params.sessid=this.options.sessid;} - var request={jsonrpc:'2.0',method:method,params:params,id:this._current_id++};if(!success_cb){success_cb=function(e){console.log("Success: ",e);};} - if(!error_cb){error_cb=function(e){console.log("Error: ",e);};} - var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this._wsCall(socket,request,success_cb,error_cb);return;} - if(this.options.ajaxUrl===null){throw"$.JsonRpcClient.call used with no websocket and no http endpoint.";} - $.ajax({type:'POST',url:this.options.ajaxUrl,data:$.toJSON(request),dataType:'json',cache:false,success:function(data){if('error'in data)error_cb(data.error,this);success_cb(data.result,this);},error:function(jqXHR,textStatus,errorThrown){try{var response=$.parseJSON(jqXHR.responseText);if('console'in window)console.log(response);error_cb(response.error,this);}catch(err){error_cb({error:jqXHR.responseText},this);}}});};$.JsonRpcClient.prototype.notify=function(method,params){if(this.options.sessid){params.sessid=this.options.sessid;} - var request={jsonrpc:'2.0',method:method,params:params};var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this._wsCall(socket,request);return;} - if(this.options.ajaxUrl===null){throw"$.JsonRpcClient.notify used with no websocket and no http endpoint.";} - $.ajax({type:'POST',url:this.options.ajaxUrl,data:$.toJSON(request),dataType:'json',cache:false});};$.JsonRpcClient.prototype.batch=function(callback,all_done_cb,error_cb){var batch=new $.JsonRpcClient._batchObject(this,all_done_cb,error_cb);callback(batch);batch._execute();};$.JsonRpcClient.prototype.socketReady=function(){if(this._ws_socket===null||this._ws_socket.readyState>1){return false;} - return true;};$.JsonRpcClient.prototype.closeSocket=function(){var self=this;if(self.socketReady()){self._ws_socket.onclose=function(w){console.log("Closing Socket");};self._ws_socket.close();}};$.JsonRpcClient.prototype.loginData=function(params){var self=this;self.options.login=params.login;self.options.passwd=params.passwd;self.options.loginParams=params.loginParams;self.options.userVariables=params.userVariables;};$.JsonRpcClient.prototype.connectSocket=function(onmessage_cb){var self=this;if(self.to){clearTimeout(self.to);} - if(!self.socketReady()){self.authing=false;if(self._ws_socket){delete self._ws_socket;} - self._ws_socket=new WebSocket(self.options.socketUrl);if(self._ws_socket){self._ws_socket.onmessage=onmessage_cb;self._ws_socket.onclose=function(w){if(!self.ws_sleep){self.ws_sleep=1000;} - if(self.options.onWSClose){self.options.onWSClose(self);} - console.error("Websocket Lost "+self.ws_cnt+" sleep: "+self.ws_sleep+"msec");self.to=setTimeout(function(){console.log("Attempting Reconnection....");self.connectSocket(onmessage_cb);},self.ws_sleep);self.ws_cnt++;if(self.ws_sleep<3000&&(self.ws_cnt%10)===0){self.ws_sleep+=1000;}};self._ws_socket.onopen=function(){if(self.to){clearTimeout(self.to);} - self.ws_sleep=1000;self.ws_cnt=0;if(self.options.onWSConnect){self.options.onWSConnect(self);} - var req;while((req=$.JsonRpcClient.q.pop())){self._ws_socket.send(req);}};}} - return self._ws_socket?true:false;};$.JsonRpcClient.prototype._getSocket=function(onmessage_cb){if(this.options.socketUrl===null||!("WebSocket"in window))return null;this.connectSocket(onmessage_cb);return this._ws_socket;};$.JsonRpcClient.q=[];$.JsonRpcClient.prototype._wsCall=function(socket,request,success_cb,error_cb){var request_json=$.toJSON(request);if(socket.readyState<1){self=this;$.JsonRpcClient.q.push(request_json);}else{socket.send(request_json);} - if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}else if('error'in response&&this._ws_callbacks[response.id]){var error_cb=this._ws_callbacks[response.id].error_cb;var orig_req=this._ws_callbacks[response.id].request;if(!self.authing&&response.error.code==-32000&&self.options.login&&self.options.passwd){self.authing=true;this.call("login",{login:self.options.login,passwd:self.options.passwd,loginParams:self.options.loginParams,userVariables:self.options.userVariables},this._ws_callbacks[response.id].request_obj.method=="login"?function(e){self.authing=false;console.log("logged in");delete self._ws_callbacks[response.id];if(self.options.onWSLogin){self.options.onWSLogin(true,self);}}:function(e){self.authing=false;console.log("logged in, resending request id: "+response.id);var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send(orig_req);} - if(self.options.onWSLogin){self.options.onWSLogin(true,self);}},function(e){console.log("error logging in, request id:",response.id);delete self._ws_callbacks[response.id];error_cb(response.error,this);if(self.options.onWSLogin){self.options.onWSLogin(false,self);}});return;} - delete this._ws_callbacks[response.id];error_cb(response.error,this);return;}}}catch(err){console.log("ERROR: "+err);return;} - if(typeof this.options.onmessage==='function'){event.eventData=response;if(!event.eventData){event.eventData={};} - var reply=this.options.onmessage(event);if(reply&&typeof reply==="object"&&event.eventData.id){var msg={jsonrpc:"2.0",id:event.eventData.id,result:reply};var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send($.toJSON(msg));}}}};$.JsonRpcClient._batchObject=function(jsonrpcclient,all_done_cb,error_cb){this._requests=[];this.jsonrpcclient=jsonrpcclient;this.all_done_cb=all_done_cb;this.error_cb=typeof error_cb==='function'?error_cb:function(){};};$.JsonRpcClient._batchObject.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};} - if(this.options.sessid){params.sessid=this.options.sessid;} - if(!success_cb){success_cb=function(e){console.log("Success: ",e);};} - if(!error_cb){error_cb=function(e){console.log("Error: ",e);};} - this._requests.push({request:{jsonrpc:'2.0',method:method,params:params,id:this.jsonrpcclient._current_id++},success_cb:success_cb,error_cb:error_cb});};$.JsonRpcClient._batchObject.prototype.notify=function(method,params){if(this.options.sessid){params.sessid=this.options.sessid;} - this._requests.push({request:{jsonrpc:'2.0',method:method,params:params}});};$.JsonRpcClient._batchObject.prototype._execute=function(){var self=this;if(this._requests.length===0)return;var batch_request=[];var handlers={};var i=0;var call;var success_cb;var error_cb;var socket=self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage);if(socket!==null){for(i=0;i0){data.params.useVideo=true;} - if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;} - dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);dialog.setState($.verto.enum.state.recovering);break;case'verto.invite':if(data.params.sdp&&data.params.sdp.indexOf("m=video")>0){data.params.wantVideo=true;} - if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;} - dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);break;default:console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED");break;}} - return{method:data.method};}else{switch(data.method){case'verto.punt':verto.purge();verto.logout();break;case'verto.event':var list=null;var key=null;if(data.params){key=data.params.eventChannel;} - if(key){list=verto.eventSUBS[key];if(!list){list=verto.eventSUBS[key.split(".")[0]];}} - if(!list&&key&&key===verto.sessid){if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.pvtEvent,data.params);}}else if(!list&&key&&verto.dialogs[key]){verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent,data.params);}else if(!list){if(!key){key="UNDEFINED";} - console.error("UNSUBBED or invalid EVENT "+key+" IGNORED");}else{for(var i in list){var sub=list[i];if(!sub||!sub.ready){console.error("invalid EVENT for "+key+" IGNORED");}else if(sub.handler){sub.handler(verto,data.params,sub.userData);}else if(verto.callbacks.onEvent){verto.callbacks.onEvent(verto,data.params,sub.userData);}else{console.log("EVENT:",data.params);}}} - break;case"verto.info":if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.info,data.params.msg);} - console.debug("MESSAGE from: "+data.params.msg.from,data.params.msg.body);break;default:console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED",data.method);break;}}};var del_array=function(array,name){var r=[];var len=array.length;for(var i=0;i=array.length){array.push(name);}else{var x=0;var n=[];var len=array.length;for(var i=0;i":"\n");});return str;};};$.verto.liveArray=function(verto,context,name,config){var la=this;var lastSerno=0;var binding=null;var user_obj=config.userObj;var local=false;hashArray.call(la);la._add=la.add;la._del=la.del;la._reorder=la.reorder;la._clear=la.clear;la.context=context;la.name=name;la.user_obj=user_obj;la.verto=verto;la.broadcast=function(channel,obj){verto.broadcast(channel,obj);};la.errs=0;la.clear=function(){la._clear();lastSerno=0;if(la.onChange){la.onChange(la,{action:"clear"});}};la.checkSerno=function(serno){if(serno<0){return true;} - if(lastSerno>0&&serno!=(lastSerno+1)){if(la.onErr){la.onErr(la,{lastSerno:lastSerno,serno:serno});} - la.errs++;console.debug(la.errs);if(la.errs<3){la.bootstrap(la.user_obj);} - return false;}else{lastSerno=serno;return true;}};la.reorder=function(serno,a){if(la.checkSerno(serno)){la._reorder(a);if(la.onChange){la.onChange(la,{serno:serno,action:"reorder"});}}};la.init=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} - if(la.checkSerno(serno)){if(la.onChange){la.onChange(la,{serno:serno,action:"init",index:index,key:key,data:val});}}};la.bootObj=function(serno,val){if(la.checkSerno(serno)){for(var i in val){la._add(val[i][0],val[i][1]);} - if(la.onChange){la.onChange(la,{serno:serno,action:"bootObj",data:val,redraw:true});}}};la.add=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} - if(la.checkSerno(serno)){var redraw=la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"add",index:index,key:key,data:val,redraw:redraw});}}};la.modify=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} - if(la.checkSerno(serno)){la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"modify",key:key,data:val,index:index});}}};la.del=function(serno,key,index){if(key===null||key===undefined){key=serno;} - if(la.checkSerno(serno)){if(index===null||index<0||index===undefined){index=la.indexOf(key);} - var ok=la._del(key);if(ok&&la.onChange){la.onChange(la,{serno:serno,action:"del",key:key,index:index});}}};var eventHandler=function(v,e,la){var packet=e.data;if(packet.name!=la.name){return;} - switch(packet.action){case"init":la.init(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"bootObj":la.bootObj(packet.wireSerno,packet.data);break;case"add":la.add(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"modify":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.modify(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);} - break;case"del":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.del(packet.wireSerno,packet.hashKey,packet.arrIndex);} - break;case"clear":la.clear();break;case"reorder":la.reorder(packet.wireSerno,packet.order);break;default:if(la.checkSerno(packet.wireSerno)){if(la.onChange){la.onChange(la,{serno:packet.wireSerno,action:packet.action,data:packet.data});}} - break;}};if(la.context){binding=la.verto.subscribe(la.context,{handler:eventHandler,userData:la,subParams:config.subParams});} - la.destroy=function(){la._clear();la.verto.unsubscribe(binding);};la.sendCommand=function(cmd,obj){var self=la;self.broadcast(self.context,{liveArray:{command:cmd,context:self.context,name:self.name,obj:obj}});};la.bootstrap=function(obj){var self=la;la.sendCommand("bootstrap",obj);};la.changepage=function(obj){var self=la;self.clear();self.broadcast(self.context,{liveArray:{command:"changepage",context:la.context,name:la.name,obj:obj}});};la.heartbeat=function(obj){var self=la;var callback=function(){self.heartbeat.call(self,obj);};self.broadcast(self.context,{liveArray:{command:"heartbeat",context:self.context,name:self.name,obj:obj}});self.hb_pid=setTimeout(callback,30000);};la.bootstrap(la.user_obj);};$.verto.liveTable=function(verto,context,name,jq,config){var dt;var la=new $.verto.liveArray(verto,context,name,{subParams:config.subParams});var lt=this;lt.liveArray=la;lt.dataTable=dt;lt.verto=verto;lt.destroy=function(){if(dt){dt.fnDestroy();} - if(la){la.destroy();} - dt=null;la=null;};la.onErr=function(obj,args){console.error("Error: ",obj,args);};la.onChange=function(obj,args){var index=0;var iserr=0;if(!dt){if(!config.aoColumns){if(args.action!="init"){return;} - config.aoColumns=[];for(var i in args.data){config.aoColumns.push({"sTitle":args.data[i]});}} - dt=jq.dataTable(config);} - if(dt&&(args.action=="del"||args.action=="modify")){index=args.index;if(index===undefined&&args.key){index=la.indexOf(args.key);} - if(index===undefined){console.error("INVALID PACKET Missing INDEX\n",args);return;}} - if(config.onChange){config.onChange(obj,args);} - try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data");return;} - dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} - if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);} - dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;} - dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} - if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.confMan=function(verto,params){var confMan=this;confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var snapshot_id="snapshot_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="

"+""+""+""+""+ - (confMan.params.hasVid?"":"")+"

";jq.html(html);if(confMan.params.hasVid){var vlayout_id="confman_vid_layout_"+confMan.serno;var vlselect_id="confman_vl_select_"+confMan.serno;var vlhtml="

"+"Video Layout "+"

";jq.append(vlhtml);$("#"+vlselect_id).change(function(){var val=$("#"+vlselect_id).find(":selected").val();if(val!=="none"){confMan.modCommand("vid-layout",null,val);}});$("#"+snapshot_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("vid-write-png",null,file);}});} - $("#"+play_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("play",null,file);}});$("#"+stop_id).click(function(){confMan.modCommand("stop",null,"all");});$("#"+recording_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("recording",null,["start",file]);}});$("#"+rec_stop_id).click(function(){confMan.modCommand("recording",null,["stop","all"]);});} - function genControls(jq,rowid){var x=parseInt(rowid);var kick_id="kick_"+x;var tmute_id="tmute_"+x;var tvmute_id="tvmute_"+x;var vbanner_id="vbanner_"+x;var tvpresenter_id="tvpresenter_"+x;var tvfloor_id="tvfloor_"+x;var box_id="box_"+x;var volup_id="volume_in_up"+x;var voldn_id="volume_in_dn"+x;var transfer_id="transfer"+x;var html="
"+""+""+ - (confMan.params.hasVid?"":"")+ - (confMan.params.hasVid?"":"")+ - (confMan.params.hasVid?"":"")+ - (confMan.params.hasVid?"":"")+""+""+""+"
";jq.html(html);if(!jq.data("mouse")){$("#"+box_id).hide();} - jq.mouseover(function(e){jq.data({"mouse":true});$("#"+box_id).show();});jq.mouseout(function(e){jq.data({"mouse":false});$("#"+box_id).hide();});$("#"+transfer_id).click(function(){var xten=prompt("Enter Extension");if(xten){confMan.modCommand("transfer",x,xten);}});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});if(confMan.params.hasVid){$("#"+tvmute_id).click(function(){confMan.modCommand("tvmute",x);});$("#"+tvpresenter_id).click(function(){confMan.modCommand("vid-res-id",x,"presenter");});$("#"+tvfloor_id).click(function(){confMan.modCommand("vid-floor",x,"force");});$("#"+vbanner_id).click(function(){var text=prompt("Please enter text","");if(text){confMan.modCommand("vid-banner",x,escape(text));}});} - $("#"+volup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_in",x,"down");});return html;} - var atitle="";var awidth=0;if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=300;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready

");}else{$(confMan.params.mainModID).html("");} - verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);} - if(e.data["conf-command"]==="list-videoLayouts"){var vlselect_id="#confman_vl_select_"+confMan.serno;var vlayout_id="#confman_vid_layout_"+confMan.serno;var x=0;var options;$(vlselect_id).selectmenu({});$(vlselect_id).selectmenu("enable");$(vlselect_id).empty();$(vlselect_id).append(new Option("Choose a Layout","none"));if(e.data.responseData){options=e.data.responseData.sort();for(var i in options){$(vlselect_id).append(new Option(options[i],options[i]));x++;}} - if(x){$(vlselect_id).selectmenu('refresh',true);}else{$(vlayout_id).hide();}}else{if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"

");if(confMan.lastTimeout){clearTimeout(confMan.lastTimeout);confMan.lastTimeout=0;} - confMan.lastTimeout=setTimeout(function(){$(confMan.params.displayID).html(confMan.destroyed?"":"Moderator Controls Ready

");},4000);}}}});if(confMan.params.hasVid){confMan.modCommand("list-videoLayouts",null,null);}} - var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};} - confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID"},{"sTitle":"Number"},{"sTitle":"Name"},{"sTitle":"Codec"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"200px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1000,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} - if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);} - if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:"any",useMic:"any",tag:verto.options.tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=params.useCamera;dialog.useMic=params.useMic;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} - if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}} - if(dialog.params.localTag){dialog.localVideo=document.getElementById(dialog.params.localTag);} - dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;} - if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="Nobody";} - 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){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.SDP);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.localVideo,useVideo:dialog.videoStream,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});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;} - 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;} - return false;} - $.verto.dialog.prototype.setState=function(state){var dialog=this;if(dialog.state==$.verto.enum.state.ringing){dialog.stopRinging();} - if(dialog.state==state||!checkStateChange(dialog.state,state)){console.error("Dialog "+dialog.callID+": INVALID state change from "+dialog.state.name+" to "+state.name);dialog.hangup();return false;} - console.info("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;} - if(!dialog.cause){dialog.cause="NORMAL CLEARING";} - if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);} - switch(dialog.state){case $.verto.enum.state.trying:setTimeout(function(){if(dialog.state==$.verto.enum.state.trying){dialog.setState($.verto.enum.state.hangup);}},30000);break;case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});} - dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(!dialog.params.screenShare){dialog.rtc.stop();} - break;} - return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} - break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} - break;case"verto.bye":dialog.hangup();break;case"verto.modify":if(e.holdState){if(e.holdState=="held"){if(dialog.state!=$.verto.enum.state.held){dialog.setState($.verto.enum.state.held);}}else if(e.holdState=="active"){if(dialog.state!=$.verto.enum.state.active){dialog.setState($.verto.enum.state.active);}}} - 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(what){var dialog=this;return dialog.rtc.getMute(what);};$.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++;} - 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={};} - params.sdp=dialog.params.sdp;if(params){if(params.useVideo){dialog.useVideo(true);} - dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;} - 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(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},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=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.purge();verto.logout();}} - return $.verto.warnOnUnload;});$.verto.videoDevices=[];$.verto.audioDevices=[];var checkDevices=function(runtime){console.info("enumerating devices");var aud=[],vid=[];if(MediaStreamTrack.getSources){MediaStreamTrack.getSources(function(media_sources){for(var i=0;i 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) { + if (func) return func(); + 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 + }; + if (window.moz) { + video = video.mandatory; + if (!video.width) video.width = video.minWidth; + if (!video.height) video.height = video.minHeight; + if (!video.frameRate) video.frameRate = video.minFrameRate; + } + getUserMedia({ + constraints: { + audio: ttl++ == 0, + video: video + }, + onsuccess: function(e) { + e.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 = []; + $.FSRTC.validRes = []; + resI = 0; + checkRes(cam, func); + } + $.FSRTC.checkPerms = function() { + getUserMedia({ + constraints: { + audio: true, + video: true, + }, + onsuccess: function(e) { + e.stop(); + console.info("media perm init complete"); + }, + onerror: function(e) { + console.error("media perm init error"); + } + }); + } +})(jQuery); +(function($) { + $.JsonRpcClient = function(options) { + var self = this; + this.options = $.extend({ + ajaxUrl: null, + socketUrl: null, + onmessage: null, + login: null, + passwd: null, + sessid: null, + loginParams: null, + userVariables: null, + getSocket: function(onmessage_cb) { + return self._getSocket(onmessage_cb); + } + }, options); + self.ws_cnt = 0; + this.wsOnMessage = function(event) { + self._wsOnMessage(event); + }; + }; + $.JsonRpcClient.prototype._ws_socket = null; + $.JsonRpcClient.prototype._ws_callbacks = {}; + $.JsonRpcClient.prototype._current_id = 1; + $.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) { + if (!params) { + params = {}; + } + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + var request = { + jsonrpc: '2.0', + method: method, + params: params, + id: this._current_id++ + }; + if (!success_cb) { + success_cb = function(e) { + console.log("Success: ", e); + }; + } + if (!error_cb) { + error_cb = function(e) { + console.log("Error: ", e); + }; + } + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request, success_cb, error_cb); + return; + } + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.call used with no websocket and no http endpoint."; + } + $.ajax({ + type: 'POST', + url: this.options.ajaxUrl, + data: $.toJSON(request), + dataType: 'json', + cache: false, + success: function(data) { + if ('error' in data) error_cb(data.error, this); + success_cb(data.result, this); + }, + error: function(jqXHR, textStatus, errorThrown) { + try { + var response = $.parseJSON(jqXHR.responseText); + if ('console' in window) console.log(response); + error_cb(response.error, this); + } catch (err) { + error_cb({ + error: jqXHR.responseText + }, this); + } + } + }); + }; + $.JsonRpcClient.prototype.notify = function(method, params) { + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + var request = { + jsonrpc: '2.0', + method: method, + params: params + }; + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request); + return; + } + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.notify used with no websocket and no http endpoint."; + } + $.ajax({ + type: 'POST', + url: this.options.ajaxUrl, + data: $.toJSON(request), + dataType: 'json', + cache: false + }); + }; + $.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) { + var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb); + callback(batch); + batch._execute(); + }; + $.JsonRpcClient.prototype.socketReady = function() { + if (this._ws_socket === null || this._ws_socket.readyState > 1) { + return false; + } + return true; + }; + $.JsonRpcClient.prototype.closeSocket = function() { + var self = this; + if (self.socketReady()) { + self._ws_socket.onclose = function(w) { + console.log("Closing Socket"); + }; + self._ws_socket.close(); + } + }; + $.JsonRpcClient.prototype.loginData = function(params) { + var self = this; + self.options.login = params.login; + self.options.passwd = params.passwd; + self.options.loginParams = params.loginParams; + self.options.userVariables = params.userVariables; + }; + $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { + var self = this; + if (self.to) { + clearTimeout(self.to); + } + if (!self.socketReady()) { + self.authing = false; + if (self._ws_socket) { + delete self._ws_socket; + } + self._ws_socket = new WebSocket(self.options.socketUrl); + if (self._ws_socket) { + self._ws_socket.onmessage = onmessage_cb; + self._ws_socket.onclose = function(w) { + if (!self.ws_sleep) { + self.ws_sleep = 1000; + } + if (self.options.onWSClose) { + self.options.onWSClose(self); + } + console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec"); + self.to = setTimeout(function() { + console.log("Attempting Reconnection...."); + self.connectSocket(onmessage_cb); + }, self.ws_sleep); + self.ws_cnt++; + if (self.ws_sleep < 3000 && (self.ws_cnt % 10) === 0) { + self.ws_sleep += 1000; + } + }; + self._ws_socket.onopen = function() { + if (self.to) { + clearTimeout(self.to); + } + self.ws_sleep = 1000; + self.ws_cnt = 0; + if (self.options.onWSConnect) { + self.options.onWSConnect(self); + } + var req; + while ((req = $.JsonRpcClient.q.pop())) { + self._ws_socket.send(req); + } + }; + } + } + return self._ws_socket ? true : false; + }; + $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { + if (this.options.socketUrl === null || !("WebSocket" in window)) return null; + this.connectSocket(onmessage_cb); + return this._ws_socket; + }; + $.JsonRpcClient.q = []; + $.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) { + var request_json = $.toJSON(request); + if (socket.readyState < 1) { + self = this; + $.JsonRpcClient.q.push(request_json); + } else { + socket.send(request_json); + } + if ('id' in request && typeof success_cb !== 'undefined') { + this._ws_callbacks[request.id] = { + request: request_json, + request_obj: request, + success_cb: success_cb, + error_cb: error_cb + }; + } + }; + $.JsonRpcClient.prototype._wsOnMessage = function(event) { + var response; + try { + response = $.parseJSON(event.data); + if (typeof response === 'object' && 'jsonrpc' in response && response.jsonrpc === '2.0') { + if ('result' in response && this._ws_callbacks[response.id]) { + var success_cb = this._ws_callbacks[response.id].success_cb; + delete this._ws_callbacks[response.id]; + success_cb(response.result, this); + return; + } else if ('error' in response && this._ws_callbacks[response.id]) { + var error_cb = this._ws_callbacks[response.id].error_cb; + var orig_req = this._ws_callbacks[response.id].request; + if (!self.authing && response.error.code == -32000 && self.options.login && self.options.passwd) { + self.authing = true; + this.call("login", { + login: self.options.login, + passwd: self.options.passwd, + loginParams: self.options.loginParams, + userVariables: self.options.userVariables + }, this._ws_callbacks[response.id].request_obj.method == "login" ? function(e) { + self.authing = false; + console.log("logged in"); + delete self._ws_callbacks[response.id]; + if (self.options.onWSLogin) { + self.options.onWSLogin(true, self); + } + } : function(e) { + self.authing = false; + console.log("logged in, resending request id: " + response.id); + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send(orig_req); + } + if (self.options.onWSLogin) { + self.options.onWSLogin(true, self); + } + }, function(e) { + console.log("error logging in, request id:", response.id); + delete self._ws_callbacks[response.id]; + error_cb(response.error, this); + if (self.options.onWSLogin) { + self.options.onWSLogin(false, self); + } + }); + return; + } + delete this._ws_callbacks[response.id]; + error_cb(response.error, this); + return; + } + } + } catch (err) { + console.log("ERROR: " + err); + return; + } + if (typeof this.options.onmessage === 'function') { + event.eventData = response; + if (!event.eventData) { + event.eventData = {}; + } + var reply = this.options.onmessage(event); + if (reply && typeof reply === "object" && event.eventData.id) { + var msg = { + jsonrpc: "2.0", + id: event.eventData.id, + result: reply + }; + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send($.toJSON(msg)); + } + } + } + }; + $.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) { + this._requests = []; + this.jsonrpcclient = jsonrpcclient; + this.all_done_cb = all_done_cb; + this.error_cb = typeof error_cb === 'function' ? error_cb : function() {}; + }; + $.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) { + if (!params) { + params = {}; + } + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + if (!success_cb) { + success_cb = function(e) { + console.log("Success: ", e); + }; + } + if (!error_cb) { + error_cb = function(e) { + console.log("Error: ", e); + }; + } + this._requests.push({ + request: { + jsonrpc: '2.0', + method: method, + params: params, + id: this.jsonrpcclient._current_id++ + }, + success_cb: success_cb, + error_cb: error_cb + }); + }; + $.JsonRpcClient._batchObject.prototype.notify = function(method, params) { + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + this._requests.push({ + request: { + jsonrpc: '2.0', + method: method, + params: params + } + }); + }; + $.JsonRpcClient._batchObject.prototype._execute = function() { + var self = this; + if (this._requests.length === 0) return; + var batch_request = []; + var handlers = {}; + var i = 0; + var call; + var success_cb; + var error_cb; + var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); + if (socket !== null) { + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + success_cb = ('success_cb' in call) ? call.success_cb : undefined; + error_cb = ('error_cb' in call) ? call.error_cb : undefined; + self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); + } + if (typeof all_done_cb === 'function') all_done_cb(result); + return; + } + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + batch_request.push(call.request); + if ('id' in call.request) { + handlers[call.request.id] = { + success_cb: call.success_cb, + error_cb: call.error_cb + }; + } + } + success_cb = function(data) { + self._batchCb(data, handlers, self.all_done_cb); + }; + if (self.jsonrpcclient.options.ajaxUrl === null) { + throw "$.JsonRpcClient.batch used with no websocket and no http endpoint."; + } + $.ajax({ + url: self.jsonrpcclient.options.ajaxUrl, + data: $.toJSON(batch_request), + dataType: 'json', + cache: false, + type: 'POST', + error: function(jqXHR, textStatus, errorThrown) { + self.error_cb(jqXHR, textStatus, errorThrown); + }, + success: success_cb + }); + }; + $.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) { + for (var i = 0; i < result.length; i++) { + var response = result[i]; + if ('error' in response) { + if (response.id === null || !(response.id in handlers)) { + if ('console' in window) console.log(response); + } else { + handlers[response.id].error_cb(response.error, this); + } + } else { + if (!(response.id in handlers) && 'console' in window) { + console.log(response); + } else { + handlers[response.id].success_cb(response.result, this); + } + } + } + if (typeof all_done_cb === 'function') all_done_cb(result); + }; +})(jQuery); +(function($) { + var sources = []; + var generateGUID = (typeof(window.crypto) !== 'undefined' && typeof(window.crypto.getRandomValues) !== 'undefined') ? function() { + var buf = new Uint16Array(8); + window.crypto.getRandomValues(buf); + var S4 = function(num) { + var ret = num.toString(16); + while (ret.length < 4) { + ret = "0" + ret; + } + return ret; + }; + return (S4(buf[0]) + S4(buf[1]) + "-" + S4(buf[2]) + "-" + S4(buf[3]) + "-" + S4(buf[4]) + "-" + S4(buf[5]) + S4(buf[6]) + S4(buf[7])); + } : function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, + v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + }; + $.verto = function(options, callbacks) { + var verto = this; + $.verto.saved.push(verto); + verto.options = $.extend({ + login: null, + passwd: null, + socketUrl: null, + tag: null, + localTag: null, + videoParams: {}, + audioParams: {}, + loginParams: {}, + userVariables: {}, + iceServers: false, + ringSleep: 6000 + }, options); + verto.sessid = $.cookie('verto_session_uuid') || generateGUID(); + $.cookie('verto_session_uuid', verto.sessid, { + expires: 1 + }); + verto.dialogs = {}; + verto.callbacks = callbacks || {}; + verto.eventSUBS = {}; + verto.rpcClient = new $.JsonRpcClient({ + login: verto.options.login, + passwd: verto.options.passwd, + socketUrl: verto.options.socketUrl, + loginParams: verto.options.loginParams, + userVariables: verto.options.userVariables, + sessid: verto.sessid, + onmessage: function(e) { + return verto.handleMessage(e.eventData); + }, + onWSConnect: function(o) { + o.call('login', {}); + }, + onWSLogin: function(success) { + if (verto.callbacks.onWSLogin) { + verto.callbacks.onWSLogin(verto, success); + } + }, + onWSClose: function(success) { + if (verto.callbacks.onWSClose) { + verto.callbacks.onWSClose(verto, success); + } + verto.purge(); + } + }); + if (verto.options.ringFile && verto.options.tag) { + verto.ringer = $("#" + verto.options.tag); + } + verto.rpcClient.call('login', {}); + }; + $.verto.prototype.videoParams = function(on) { + var verto = this; + verto.options.videoParams = on; + }; + $.verto.prototype.iceServers = function(on) { + var verto = this; + verto.options.iceServers = on; + }; + $.verto.prototype.loginData = function(params) { + var verto = this; + verto.options.login = params.login; + verto.options.passwd = params.passwd; + verto.rpcClient.loginData(params); + }; + $.verto.prototype.logout = function(msg) { + var verto = this; + verto.rpcClient.closeSocket(); + if (verto.callbacks.onWSClose) { + verto.callbacks.onWSClose(verto, false); + } + verto.purge(); + }; + $.verto.prototype.login = function(msg) { + var verto = this; + verto.logout(); + verto.rpcClient.call('login', {}); + }; + $.verto.prototype.message = function(msg) { + var verto = this; + var err = 0; + if (!msg.to) { + console.error("Missing To"); + err++; + } + if (!msg.body) { + console.error("Missing Body"); + err++; + } + if (err) { + return false; + } + verto.sendMethod("verto.info", { + msg: msg + }); + return true; + }; + $.verto.prototype.processReply = function(method, success, e) { + var verto = this; + var i; + switch (method) { + case "verto.subscribe": + for (i in e.unauthorizedChannels) { + drop_bad(verto, e.unauthorizedChannels[i]); + } + for (i in e.subscribedChannels) { + mark_ready(verto, e.subscribedChannels[i]); + } + break; + case "verto.unsubscribe": + break; + } + }; + $.verto.prototype.sendMethod = function(method, params) { + var verto = this; + verto.rpcClient.call(method, params, function(e) { + verto.processReply(method, true, e); + }, function(e) { + verto.processReply(method, false, e); + }); + }; + + function do_sub(verto, channel, obj) {} + + function drop_bad(verto, channel) { + console.error("drop unauthorized channel: " + channel); + delete verto.eventSUBS[channel]; + } + + function mark_ready(verto, channel) { + for (var j in verto.eventSUBS[channel]) { + verto.eventSUBS[channel][j].ready = true; + console.log("subscribed to channel: " + channel); + if (verto.eventSUBS[channel][j].readyHandler) { + verto.eventSUBS[channel][j].readyHandler(verto, channel); + } + } + } + var SERNO = 1; + + function do_subscribe(verto, channel, subChannels, sparams) { + var params = sparams || {}; + var local = params.local; + var obj = { + eventChannel: channel, + userData: params.userData, + handler: params.handler, + ready: false, + readyHandler: params.readyHandler, + serno: SERNO++ + }; + var isnew = false; + if (!verto.eventSUBS[channel]) { + verto.eventSUBS[channel] = []; + subChannels.push(channel); + isnew = true; + } + verto.eventSUBS[channel].push(obj); + if (local) { + obj.ready = true; + obj.local = true; + } + if (!isnew && verto.eventSUBS[channel][0].ready) { + obj.ready = true; + if (obj.readyHandler) { + obj.readyHandler(verto, channel); + } + } + return { + serno: obj.serno, + eventChannel: channel + }; + } + $.verto.prototype.subscribe = function(channel, sparams) { + var verto = this; + var r = []; + var subChannels = []; + var params = sparams || {}; + if (typeof(channel) === "string") { + r.push(do_subscribe(verto, channel, subChannels, params)); + } else { + for (var i in channel) { + r.push(do_subscribe(verto, channel, subChannels, params)); + } + } + if (subChannels.length) { + verto.sendMethod("verto.subscribe", { + eventChannel: subChannels.length == 1 ? subChannels[0] : subChannels, + subParams: params.subParams + }); + } + return r; + }; + $.verto.prototype.unsubscribe = function(handle) { + var verto = this; + var i; + if (!handle) { + for (i in verto.eventSUBS) { + if (verto.eventSUBS[i]) { + verto.unsubscribe(verto.eventSUBS[i]); + } + } + } else { + var unsubChannels = {}; + var sendChannels = []; + var channel; + if (typeof(handle) == "string") { + delete verto.eventSUBS[handle]; + unsubChannels[handle]++; + } else { + for (i in handle) { + if (typeof(handle[i]) == "string") { + channel = handle[i]; + delete verto.eventSUBS[channel]; + unsubChannels[channel]++; + } else { + var repl = []; + channel = handle[i].eventChannel; + for (var j in verto.eventSUBS[channel]) { + if (verto.eventSUBS[channel][j].serno == handle[i].serno) {} else { + repl.push(verto.eventSUBS[channel][j]); + } + } + verto.eventSUBS[channel] = repl; + if (verto.eventSUBS[channel].length === 0) { + delete verto.eventSUBS[channel]; + unsubChannels[channel]++; + } + } + } + } + for (var u in unsubChannels) { + console.log("Sending Unsubscribe for: ", u); + sendChannels.push(u); + } + if (sendChannels.length) { + verto.sendMethod("verto.unsubscribe", { + eventChannel: sendChannels.length == 1 ? sendChannels[0] : sendChannels + }); + } + } + }; + $.verto.prototype.broadcast = function(channel, params) { + var verto = this; + var msg = { + eventChannel: channel, + data: {} + }; + for (var i in params) { + msg.data[i] = params[i]; + } + verto.sendMethod("verto.broadcast", msg); + }; + $.verto.prototype.purge = function(callID) { + var verto = this; + var x = 0; + var i; + for (i in verto.dialogs) { + if (!x) { + console.log("purging dialogs"); + } + x++; + verto.dialogs[i].setState($.verto.enum.state.purge); + } + for (i in verto.eventSUBS) { + if (verto.eventSUBS[i]) { + console.log("purging subscription: " + i); + delete verto.eventSUBS[i]; + } + } + }; + $.verto.prototype.hangup = function(callID) { + var verto = this; + if (callID) { + var dialog = verto.dialogs[callID]; + if (dialog) { + dialog.hangup(); + } + } else { + for (var i in verto.dialogs) { + verto.dialogs[i].hangup(); + } + } + }; + $.verto.prototype.newCall = function(args, callbacks) { + var verto = this; + if (!verto.rpcClient.socketReady()) { + console.error("Not Connected..."); + return; + } + var dialog = new $.verto.dialog($.verto.enum.direction.outbound, this, args); + dialog.invite(); + if (callbacks) { + dialog.callbacks = callbacks; + } + return dialog; + }; + $.verto.prototype.handleMessage = function(data) { + var verto = this; + if (!(data && data.method)) { + console.error("Invalid Data", data); + return; + } + if (data.params.callID) { + var dialog = verto.dialogs[data.params.callID]; + if (data.method === "verto.attach" && dialog) { + delete dialog.verto.dialogs[dialog.callID]; + dialog.rtc.stop(); + dialog = null; + } + if (dialog) { + switch (data.method) { + case 'verto.bye': + dialog.hangup(data.params); + break; + case 'verto.answer': + dialog.handleAnswer(data.params); + break; + case 'verto.media': + dialog.handleMedia(data.params); + break; + case 'verto.display': + dialog.handleDisplay(data.params); + break; + case 'verto.info': + dialog.handleInfo(data.params); + break; + default: + console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", dialog, data.method); + break; + } + } else { + switch (data.method) { + case 'verto.attach': + data.params.attach = true; + if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { + data.params.useVideo = true; + } + if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { + data.params.useStereo = true; + } + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + dialog.setState($.verto.enum.state.recovering); + break; + case 'verto.invite': + if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { + data.params.wantVideo = true; + } + if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { + data.params.useStereo = true; + } + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + break; + default: + console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED"); + break; + } + } + return { + method: data.method + }; + } else { + switch (data.method) { + case 'verto.punt': + verto.purge(); + verto.logout(); + break; + case 'verto.event': + var list = null; + var key = null; + if (data.params) { + key = data.params.eventChannel; + } + if (key) { + list = verto.eventSUBS[key]; + if (!list) { + list = verto.eventSUBS[key.split(".")[0]]; + } + } + if (!list && key && key === verto.sessid) { + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.pvtEvent, data.params); + } + } else if (!list && key && verto.dialogs[key]) { + verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent, data.params); + } else if (!list) { + if (!key) { + key = "UNDEFINED"; + } + console.error("UNSUBBED or invalid EVENT " + key + " IGNORED"); + } else { + for (var i in list) { + var sub = list[i]; + if (!sub || !sub.ready) { + console.error("invalid EVENT for " + key + " IGNORED"); + } else if (sub.handler) { + sub.handler(verto, data.params, sub.userData); + } else if (verto.callbacks.onEvent) { + verto.callbacks.onEvent(verto, data.params, sub.userData); + } else { + console.log("EVENT:", data.params); + } + } + } + break; + case "verto.info": + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.info, data.params.msg); + } + console.debug("MESSAGE from: " + data.params.msg.from, data.params.msg.body); + break; + default: + console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", data.method); + break; + } + } + }; + var del_array = function(array, name) { + var r = []; + var len = array.length; + for (var i = 0; i < len; i++) { + if (array[i] != name) { + r.push(array[i]); + } + } + return r; + }; + var hashArray = function() { + var vha = this; + var hash = {}; + var array = []; + vha.reorder = function(a) { + array = a; + var h = hash; + hash = {}; + var len = array.length; + for (var i = 0; i < len; i++) { + var key = array[i]; + if (h[key]) { + hash[key] = h[key]; + delete h[key]; + } + } + h = undefined; + }; + vha.clear = function() { + hash = undefined; + array = undefined; + hash = {}; + array = []; + }; + vha.add = function(name, val, insertAt) { + var redraw = false; + if (!hash[name]) { + if (insertAt === undefined || insertAt < 0 || insertAt >= array.length) { + array.push(name); + } else { + var x = 0; + var n = []; + var len = array.length; + for (var i = 0; i < len; i++) { + if (x++ == insertAt) { + n.push(name); + } + n.push(array[i]); + } + array = undefined; + array = n; + n = undefined; + redraw = true; + } + } + hash[name] = val; + return redraw; + }; + vha.del = function(name) { + var r = false; + if (hash[name]) { + array = del_array(array, name); + delete hash[name]; + r = true; + } else { + console.error("can't del nonexistant key " + name); + } + return r; + }; + vha.get = function(name) { + return hash[name]; + }; + vha.order = function() { + return array; + }; + vha.hash = function() { + return hash; + }; + vha.indexOf = function(name) { + var len = array.length; + for (var i = 0; i < len; i++) { + if (array[i] == name) { + return i; + } + } + }; + vha.arrayLen = function() { + return array.length; + }; + vha.asArray = function() { + var r = []; + var len = array.length; + for (var i = 0; i < len; i++) { + var key = array[i]; + r.push(hash[key]); + } + return r; + }; + vha.each = function(cb) { + var len = array.length; + for (var i = 0; i < len; i++) { + cb(array[i], hash[array[i]]); + } + }; + vha.dump = function(html) { + var str = ""; + vha.each(function(name, val) { + str += "name: " + name + " val: " + JSON.stringify(val) + (html ? "
" : "\n"); + }); + return str; + }; + }; + $.verto.liveArray = function(verto, context, name, config) { + var la = this; + var lastSerno = 0; + var binding = null; + var user_obj = config.userObj; + var local = false; + hashArray.call(la); + la._add = la.add; + la._del = la.del; + la._reorder = la.reorder; + la._clear = la.clear; + la.context = context; + la.name = name; + la.user_obj = user_obj; + la.verto = verto; + la.broadcast = function(channel, obj) { + verto.broadcast(channel, obj); + }; + la.errs = 0; + la.clear = function() { + la._clear(); + lastSerno = 0; + if (la.onChange) { + la.onChange(la, { + action: "clear" + }); + } + }; + la.checkSerno = function(serno) { + if (serno < 0) { + return true; + } + if (lastSerno > 0 && serno != (lastSerno + 1)) { + if (la.onErr) { + la.onErr(la, { + lastSerno: lastSerno, + serno: serno + }); + } + la.errs++; + console.debug(la.errs); + if (la.errs < 3) { + la.bootstrap(la.user_obj); + } + return false; + } else { + lastSerno = serno; + return true; + } + }; + la.reorder = function(serno, a) { + if (la.checkSerno(serno)) { + la._reorder(a); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "reorder" + }); + } + } + }; + la.init = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "init", + index: index, + key: key, + data: val + }); + } + } + }; + la.bootObj = function(serno, val) { + if (la.checkSerno(serno)) { + for (var i in val) { + la._add(val[i][0], val[i][1]); + } + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "bootObj", + data: val, + redraw: true + }); + } + } + }; + la.add = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + var redraw = la._add(key, val, index); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "add", + index: index, + key: key, + data: val, + redraw: redraw + }); + } + } + }; + la.modify = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + la._add(key, val, index); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "modify", + key: key, + data: val, + index: index + }); + } + } + }; + la.del = function(serno, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + if (index === null || index < 0 || index === undefined) { + index = la.indexOf(key); + } + var ok = la._del(key); + if (ok && la.onChange) { + la.onChange(la, { + serno: serno, + action: "del", + key: key, + index: index + }); + } + } + }; + var eventHandler = function(v, e, la) { + var packet = e.data; + if (packet.name != la.name) { + return; + } + switch (packet.action) { + case "init": + la.init(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + break; + case "bootObj": + la.bootObj(packet.wireSerno, packet.data); + break; + case "add": + la.add(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + break; + case "modify": + if (!(packet.arrIndex || packet.hashKey)) { + console.error("Invalid Packet", packet); + } else { + la.modify(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + } + break; + case "del": + if (!(packet.arrIndex || packet.hashKey)) { + console.error("Invalid Packet", packet); + } else { + la.del(packet.wireSerno, packet.hashKey, packet.arrIndex); + } + break; + case "clear": + la.clear(); + break; + case "reorder": + la.reorder(packet.wireSerno, packet.order); + break; + default: + if (la.checkSerno(packet.wireSerno)) { + if (la.onChange) { + la.onChange(la, { + serno: packet.wireSerno, + action: packet.action, + data: packet.data + }); + } + } + break; + } + }; + if (la.context) { + binding = la.verto.subscribe(la.context, { + handler: eventHandler, + userData: la, + subParams: config.subParams + }); + } + la.destroy = function() { + la._clear(); + la.verto.unsubscribe(binding); + }; + la.sendCommand = function(cmd, obj) { + var self = la; + self.broadcast(self.context, { + liveArray: { + command: cmd, + context: self.context, + name: self.name, + obj: obj + } + }); + }; + la.bootstrap = function(obj) { + var self = la; + la.sendCommand("bootstrap", obj); + }; + la.changepage = function(obj) { + var self = la; + self.clear(); + self.broadcast(self.context, { + liveArray: { + command: "changepage", + context: la.context, + name: la.name, + obj: obj + } + }); + }; + la.heartbeat = function(obj) { + var self = la; + var callback = function() { + self.heartbeat.call(self, obj); + }; + self.broadcast(self.context, { + liveArray: { + command: "heartbeat", + context: self.context, + name: self.name, + obj: obj + } + }); + self.hb_pid = setTimeout(callback, 30000); + }; + la.bootstrap(la.user_obj); + }; + $.verto.liveTable = function(verto, context, name, jq, config) { + var dt; + var la = new $.verto.liveArray(verto, context, name, { + subParams: config.subParams + }); + var lt = this; + lt.liveArray = la; + lt.dataTable = dt; + lt.verto = verto; + lt.destroy = function() { + if (dt) { + dt.fnDestroy(); + } + if (la) { + la.destroy(); + } + dt = null; + la = null; + }; + la.onErr = function(obj, args) { + console.error("Error: ", obj, args); + }; + la.onChange = function(obj, args) { + var index = 0; + var iserr = 0; + if (!dt) { + if (!config.aoColumns) { + if (args.action != "init") { + return; + } + config.aoColumns = []; + for (var i in args.data) { + config.aoColumns.push({ + "sTitle": args.data[i] + }); + } + } + dt = jq.dataTable(config); + } + if (dt && (args.action == "del" || args.action == "modify")) { + index = args.index; + if (index === undefined && args.key) { + index = la.indexOf(args.key); + } + if (index === undefined) { + console.error("INVALID PACKET Missing INDEX\n", args); + return; + } + } + if (config.onChange) { + config.onChange(obj, args); + } + try { + switch (args.action) { + case "bootObj": + if (!args.data) { + console.error("missing data"); + return; + } + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + dt.fnAdjustColumnSizing(); + break; + case "add": + if (!args.data) { + console.error("missing data"); + return; + } + if (args.redraw > -1) { + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + } else { + dt.fnAddData(args.data); + } + dt.fnAdjustColumnSizing(); + break; + case "modify": + if (!args.data) { + return; + } + dt.fnUpdate(args.data, index); + dt.fnAdjustColumnSizing(); + break; + case "del": + dt.fnDeleteRow(index); + dt.fnAdjustColumnSizing(); + break; + case "clear": + dt.fnClearTable(); + break; + case "reorder": + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + break; + case "hide": + jq.hide(); + break; + case "show": + jq.show(); + break; + } + } catch (err) { + console.error("ERROR: " + err); + iserr++; + } + if (iserr) { + obj.errs++; + if (obj.errs < 3) { + obj.bootstrap(obj.user_obj); + } + } else { + obj.errs = 0; + } + }; + la.onChange(la, { + action: "init" + }); + }; + var CONFMAN_SERNO = 1; + $.verto.confMan = function(verto, params) { + var confMan = this; + confMan.params = $.extend({ + tableID: null, + statusID: null, + mainModID: null, + dialog: null, + hasVid: false, + laData: null, + onBroadcast: null, + onLaChange: null, + onLaRow: null + }, params); + confMan.verto = verto; + confMan.serno = CONFMAN_SERNO++; + + function genMainMod(jq) { + var play_id = "play_" + confMan.serno; + var stop_id = "stop_" + confMan.serno; + var recording_id = "recording_" + confMan.serno; + var snapshot_id = "snapshot_" + confMan.serno; + var rec_stop_id = "recording_stop" + confMan.serno; + var div_id = "confman_" + confMan.serno; + var html = "

" + "" + "" + "" + "" + + (confMan.params.hasVid ? "" : "") + "

"; + jq.html(html); + if (confMan.params.hasVid) { + var vlayout_id = "confman_vid_layout_" + confMan.serno; + var vlselect_id = "confman_vl_select_" + confMan.serno; + var vlhtml = "

" + "Video Layout " + "

"; + jq.append(vlhtml); + $("#" + vlselect_id).change(function() { + var val = $("#" + vlselect_id).find(":selected").val(); + if (val !== "none") { + confMan.modCommand("vid-layout", null, val); + } + }); + $("#" + snapshot_id).click(function() { + var file = prompt("Please enter file name", ""); + if (file) { + confMan.modCommand("vid-write-png", null, file); + } + }); + } + $("#" + play_id).click(function() { + var file = prompt("Please enter file name", ""); + if (file) { + confMan.modCommand("play", null, file); + } + }); + $("#" + stop_id).click(function() { + confMan.modCommand("stop", null, "all"); + }); + $("#" + recording_id).click(function() { + var file = prompt("Please enter file name", ""); + if (file) { + confMan.modCommand("recording", null, ["start", file]); + } + }); + $("#" + rec_stop_id).click(function() { + confMan.modCommand("recording", null, ["stop", "all"]); + }); + } + + function genControls(jq, rowid) { + var x = parseInt(rowid); + var kick_id = "kick_" + x; + var tmute_id = "tmute_" + x; + var tvmute_id = "tvmute_" + x; + var vbanner_id = "vbanner_" + x; + var tvpresenter_id = "tvpresenter_" + x; + var tvfloor_id = "tvfloor_" + x; + var box_id = "box_" + x; + var volup_id = "volume_in_up" + x; + var voldn_id = "volume_in_dn" + x; + var transfer_id = "transfer" + x; + var html = "
" + "" + "" + + (confMan.params.hasVid ? "" : "") + + (confMan.params.hasVid ? "" : "") + + (confMan.params.hasVid ? "" : "") + + (confMan.params.hasVid ? "" : "") + "" + "" + "" + "
"; + jq.html(html); + if (!jq.data("mouse")) { + $("#" + box_id).hide(); + } + jq.mouseover(function(e) { + jq.data({ + "mouse": true + }); + $("#" + box_id).show(); + }); + jq.mouseout(function(e) { + jq.data({ + "mouse": false + }); + $("#" + box_id).hide(); + }); + $("#" + transfer_id).click(function() { + var xten = prompt("Enter Extension"); + if (xten) { + confMan.modCommand("transfer", x, xten); + } + }); + $("#" + kick_id).click(function() { + confMan.modCommand("kick", x); + }); + $("#" + tmute_id).click(function() { + confMan.modCommand("tmute", x); + }); + if (confMan.params.hasVid) { + $("#" + tvmute_id).click(function() { + confMan.modCommand("tvmute", x); + }); + $("#" + tvpresenter_id).click(function() { + confMan.modCommand("vid-res-id", x, "presenter"); + }); + $("#" + tvfloor_id).click(function() { + confMan.modCommand("vid-floor", x, "force"); + }); + $("#" + vbanner_id).click(function() { + var text = prompt("Please enter text", ""); + if (text) { + confMan.modCommand("vid-banner", x, escape(text)); + } + }); + } + $("#" + volup_id).click(function() { + confMan.modCommand("volume_in", x, "up"); + }); + $("#" + voldn_id).click(function() { + confMan.modCommand("volume_in", x, "down"); + }); + return html; + } + var atitle = ""; + var awidth = 0; + if (confMan.params.laData.role === "moderator") { + atitle = "Action"; + awidth = 300; + if (confMan.params.mainModID) { + genMainMod($(confMan.params.mainModID)); + $(confMan.params.displayID).html("Moderator Controls Ready

"); + } else { + $(confMan.params.mainModID).html(""); + } + verto.subscribe(confMan.params.laData.modChannel, { + handler: function(v, e) { + if (confMan.params.onBroadcast) { + confMan.params.onBroadcast(verto, confMan, e.data); + } + if (e.data["conf-command"] === "list-videoLayouts") { + var vlselect_id = "#confman_vl_select_" + confMan.serno; + var vlayout_id = "#confman_vid_layout_" + confMan.serno; + var x = 0; + var options; + $(vlselect_id).selectmenu({}); + $(vlselect_id).selectmenu("enable"); + $(vlselect_id).empty(); + $(vlselect_id).append(new Option("Choose a Layout", "none")); + if (e.data.responseData) { + options = e.data.responseData.sort(); + for (var i in options) { + $(vlselect_id).append(new Option(options[i], options[i])); + x++; + } + } + if (x) { + $(vlselect_id).selectmenu('refresh', true); + } else { + $(vlayout_id).hide(); + } + } else { + if (!confMan.destroyed && confMan.params.displayID) { + $(confMan.params.displayID).html(e.data.response + "

"); + if (confMan.lastTimeout) { + clearTimeout(confMan.lastTimeout); + confMan.lastTimeout = 0; + } + confMan.lastTimeout = setTimeout(function() { + $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready

"); + }, 4000); + } + } + } + }); + if (confMan.params.hasVid) { + confMan.modCommand("list-videoLayouts", null, null); + } + } + var row_callback = null; + if (confMan.params.laData.role === "moderator") { + row_callback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { + if (!aData[5]) { + var $row = $('td:eq(5)', nRow); + genControls($row, aData); + if (confMan.params.onLaRow) { + confMan.params.onLaRow(verto, confMan, $row, aData); + } + } + }; + } + confMan.lt = new $.verto.liveTable(verto, confMan.params.laData.laChannel, confMan.params.laData.laName, $(confMan.params.tableID), { + subParams: { + callID: confMan.params.dialog ? confMan.params.dialog.callID : null + }, + "onChange": function(obj, args) { + $(confMan.params.statusID).text("Conference Members: " + " (" + obj.arrayLen() + " Total)"); + if (confMan.params.onLaChange) { + confMan.params.onLaChange(verto, confMan, $.verto.enum.confEvent.laChange, obj, args); + } + }, + "aaData": [], + "aoColumns": [{ + "sTitle": "ID" + }, { + "sTitle": "Number" + }, { + "sTitle": "Name" + }, { + "sTitle": "Codec" + }, { + "sTitle": "Status", + "sWidth": confMan.params.hasVid ? "200px" : "150px" + }, { + "sTitle": atitle, + "sWidth": awidth, + }], + "bAutoWidth": true, + "bDestroy": true, + "bSort": false, + "bInfo": false, + "bFilter": false, + "bLengthChange": false, + "bPaginate": false, + "iDisplayLength": 1000, + "oLanguage": { + "sEmptyTable": "The Conference is Empty....." + }, + "fnRowCallback": row_callback + }); + }; + $.verto.confMan.prototype.modCommand = function(cmd, id, value) { + var confMan = this; + confMan.verto.rpcClient.call("verto.broadcast", { + "eventChannel": confMan.params.laData.modChannel, + "data": { + "application": "conf-control", + "command": cmd, + "id": id, + "value": value + } + }); + }; + $.verto.confMan.prototype.destroy = function() { + var confMan = this; + confMan.destroyed = true; + if (confMan.lt) { + confMan.lt.destroy(); + } + if (confMan.params.laData.modChannel) { + confMan.verto.unsubscribe(confMan.params.laData.modChannel); + } + if (confMan.params.mainModID) { + $(confMan.params.mainModID).html(""); + } + }; + $.verto.dialog = function(direction, verto, params) { + var dialog = this; + dialog.params = $.extend({ + useVideo: verto.options.useVideo, + useStereo: verto.options.useStereo, + screenShare: false, + useCamera: "any", + useMic: "any", + tag: verto.options.tag, + localTag: verto.options.localTag, + login: verto.options.login, + videoParams: verto.options.videoParams + }, params); + dialog.verto = verto; + dialog.direction = direction; + dialog.lastState = null; + dialog.state = dialog.lastState = $.verto.enum.state.new; + dialog.callbacks = verto.callbacks; + dialog.answered = false; + dialog.attach = params.attach || false; + dialog.screenShare = params.screenShare || false; + dialog.useCamera = params.useCamera; + dialog.useMic = params.useMic; + if (dialog.params.callID) { + dialog.callID = dialog.params.callID; + } else { + dialog.callID = dialog.params.callID = generateGUID(); + } + if (dialog.params.tag) { + dialog.audioStream = document.getElementById(dialog.params.tag); + if (dialog.params.useVideo) { + dialog.videoStream = dialog.audioStream; + } + } + if (dialog.params.localTag) { + dialog.localVideo = document.getElementById(dialog.params.localTag); + } + dialog.verto.dialogs[dialog.callID] = dialog; + var RTCcallbacks = {}; + if (dialog.direction == $.verto.enum.direction.inbound) { + if (dialog.params.display_direction === "outbound") { + dialog.params.remote_caller_id_name = dialog.params.caller_id_name; + dialog.params.remote_caller_id_number = dialog.params.caller_id_number; + } else { + dialog.params.remote_caller_id_name = dialog.params.callee_id_name; + dialog.params.remote_caller_id_number = dialog.params.callee_id_number; + } + if (!dialog.params.remote_caller_id_name) { + dialog.params.remote_caller_id_name = "Nobody"; + } + 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) { + if (rtc.type == "offer") { + console.log("offer", rtc.mediaData.SDP); + 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.localVideo, + useVideo: dialog.videoStream, + 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 + }); + 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; + } + 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; + } + return false; + } + $.verto.dialog.prototype.setState = function(state) { + var dialog = this; + if (dialog.state == $.verto.enum.state.ringing) { + dialog.stopRinging(); + } + if (dialog.state == state || !checkStateChange(dialog.state, state)) { + console.error("Dialog " + dialog.callID + ": INVALID state change from " + dialog.state.name + " to " + state.name); + dialog.hangup(); + return false; + } + console.info("Dialog " + dialog.callID + ": state change from " + dialog.state.name + " to " + state.name); + dialog.lastState = dialog.state; + dialog.state = state; + if (!dialog.causeCode) { + dialog.causeCode = 16; + } + if (!dialog.cause) { + dialog.cause = "NORMAL CLEARING"; + } + if (dialog.callbacks.onDialogState) { + dialog.callbacks.onDialogState(this); + } + switch (dialog.state) { + case $.verto.enum.state.trying: + setTimeout(function() { + if (dialog.state == $.verto.enum.state.trying) { + dialog.setState($.verto.enum.state.hangup); + } + }, 30000); + break; + case $.verto.enum.state.purge: + dialog.setState($.verto.enum.state.destroy); + break; + case $.verto.enum.state.hangup: + if (dialog.lastState.val > $.verto.enum.state.requesting.val && dialog.lastState.val < $.verto.enum.state.hangup.val) { + dialog.sendMethod("verto.bye", {}); + } + dialog.setState($.verto.enum.state.destroy); + break; + case $.verto.enum.state.destroy: + delete dialog.verto.dialogs[dialog.callID]; + if (!dialog.params.screenShare) { + dialog.rtc.stop(); + } + break; + } + return true; + }; + $.verto.dialog.prototype.processReply = function(method, success, e) { + var dialog = this; + switch (method) { + case "verto.answer": + case "verto.attach": + if (success) { + dialog.setState($.verto.enum.state.active); + } else { + dialog.hangup(); + } + break; + case "verto.invite": + if (success) { + dialog.setState($.verto.enum.state.trying); + } else { + dialog.setState($.verto.enum.state.destroy); + } + break; + case "verto.bye": + dialog.hangup(); + break; + case "verto.modify": + if (e.holdState) { + if (e.holdState == "held") { + if (dialog.state != $.verto.enum.state.held) { + dialog.setState($.verto.enum.state.held); + } + } else if (e.holdState == "active") { + if (dialog.state != $.verto.enum.state.active) { + dialog.setState($.verto.enum.state.active); + } + } + } + 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(what) { + var dialog = this; + return dialog.rtc.getMute(what); + }; + $.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++; + } + 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 = {}; + } + params.sdp = dialog.params.sdp; + if (params) { + if (params.useVideo) { + dialog.useVideo(true); + } + dialog.params.callee_id_name = params.callee_id_name; + dialog.params.callee_id_number = params.callee_id_number; + } + 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 (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 + }, + 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 = []; + $(window).bind('beforeunload', function() { + for (var i in $.verto.saved) { + var verto = $.verto.saved[i]; + if (verto) { + verto.purge(); + verto.logout(); + } + } + return $.verto.warnOnUnload; + }); + $.verto.videoDevices = []; + $.verto.audioDevices = []; + var checkDevices = function(runtime) { + console.info("enumerating devices"); + var aud = [], + vid = []; + if (MediaStreamTrack.getSources) { + MediaStreamTrack.getSources(function(media_sources) { + for (var i = 0; i < media_sources.length; i++) { + console.log(media_sources[i]); + if (media_sources[i].kind == 'video') { + vid.push(media_sources[i]); + } else { + aud.push(media_sources[i]); + } + } + $.verto.videoDevices = vid; + $.verto.audioDevices = aud; + console.info("Audio Devices", $.verto.audioDevices); + console.info("Video Devices", $.verto.videoDevices); + runtime(); + }); + } else { + if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { + console.log("enumerateDevices() not supported."); + return; + } + 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 { + aud.push({ + id: device.deviceId, + kind: "audio", + label: device.label + }); + } + }); + $.verto.videoDevices = vid; + $.verto.audioDevices = aud; + console.info("Audio Devices", $.verto.audioDevices); + console.info("Video Devices", $.verto.videoDevices); + runtime(); + }).catch(function(err) { + console.log(err.name + ": " + error.message); + runtime(); + }); + } + }; + $.verto.init = function(obj, runtime) { + checkDevices(function() { + $.FSRTC.getValidRes(obj.camera, runtime); + }); + } +})(jQuery); \ No newline at end of file