// We import the settings.js file to know which address we should contact // to talk to Janus, and optionally which STUN/TURN servers should be // used as well. Specifically, that file defines the "server" and // "iceServers" properties we'll pass when creating the Janus session. /* global Janus:readonly, server:readonly */ var janus = null; var echotest = null; var opaqueId = "echotest-" + Janus.randomString(12); var remoteTracks = {}; var bitrateTimer = null; // Web Audio context and filters var audioContext = new (window.AudioContext || window.webkitAudioContext)(); var compressor = null, analyser = null; // Canvas and visualizer data var canvasContext = null, dataArray = null; // By default we talk to the "regular" EchoTest plugin var echotestPluginBackend = "janus.plugin.echotest"; // We can use query string arguments to talk to the Lua or Duktape EchoTest // demo scripts instead. Notice that this assumes that the Lua or Duktape // plugins are configured to run the sample scripts that comes with the repo if (getQueryStringValue("plugin") === "lua") echotestPluginBackend = "janus.plugin.echolua"; else if (getQueryStringValue("plugin") === "duktape") echotestPluginBackend = "janus.plugin.echojs"; $(document).ready(function () { // Initialize the library (all console debuggers enabled) Janus.init({ debug: "all", callback: function () { // Use a button to start the demo $("#start").one("click", function () { $(this).attr("disabled", true).unbind("click"); // Make sure the browser supports WebRTC if (!Janus.isWebrtcSupported()) { bootbox.alert("No WebRTC support... "); return; } // Create session janus = new Janus({ server: server, // No "iceServers" is provided, meaning janus.js will use a default STUN server // Here are some examples of how an iceServers field may look like to support TURN // iceServers: [{urls: "turn:yourturnserver.com:3478", username: "janususer", credential: "januspwd"}], // iceServers: [{urls: "turn:yourturnserver.com:443?transport=tcp", username: "janususer", credential: "januspwd"}], // iceServers: [{urls: "turns:yourturnserver.com:443?transport=tcp", username: "janususer", credential: "januspwd"}], // Should the Janus API require authentication, you can specify either the API secret or user token here too // token: "mytoken", // or // apisecret: "serversecret", success: function () { // Attach to EchoTest plugin janus.attach({ plugin: echotestPluginBackend, opaqueId: opaqueId, success: function (pluginHandle) { $("#details").remove(); echotest = pluginHandle; Janus.log( "Plugin attached! (" + echotest.getPlugin() + ", id=" + echotest.getId() + ")" ); // Capture the webcam and create the Web Audio processors setupWebAudioDemo(); // Done $("#demo").removeClass("hide"); $("#start") .removeAttr("disabled") .html("Stop") .click(function () { $(this).attr("disabled", true); if (bitrateTimer) clearInterval(bitrateTimer); bitrateTimer = null; janus.destroy(); }); }, error: function (error) { console.error(" -- Error attaching plugin...", error); bootbox.alert("Error attaching plugin... " + error); }, consentDialog: function (on) { Janus.debug( "Consent dialog should be " + (on ? "on" : "off") + " now" ); if (on) { // Darken screen and show hint $.blockUI({ message: '
', baseZ: 3001, css: { border: "none", padding: "15px", backgroundColor: "transparent", color: "#aaa", top: "10px", left: "100px", }, }); } else { // Restore screen $.unblockUI(); } }, iceState: function (state) { Janus.log("ICE state changed to " + state); }, mediaState: function (medium, on, mid) { Janus.log( "Janus " + (on ? "started" : "stopped") + " receiving our " + medium + " (mid=" + mid + ")" ); }, webrtcState: function (on) { Janus.log( "Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now" ); $("#videoleft").parent().unblock(); }, slowLink: function (uplink, lost, mid) { Janus.warn( "Janus reports problems " + (uplink ? "sending" : "receiving") + " packets on mid " + mid + " (" + lost + " lost packets)" ); }, onmessage: function (msg, jsep) { Janus.debug(" ::: Got a message :::", msg); if (jsep) { Janus.debug("Handling SDP as well...", jsep); echotest.handleRemoteJsep({ jsep: jsep }); } let result = msg["result"]; if (result) { if (result === "done") { // The plugin closed the echo test bootbox.alert("The test is over"); return; } // Any loss? let status = result["status"]; if (status === "slow_link") { toastr.warning( "Janus apparently missed many packets we sent, maybe we should reduce the bitrate", "Packet loss?", { timeOut: 2000 } ); } } }, onlocaltrack: function (track, on) { Janus.debug( "Local track " + (on ? "added" : "removed") + ":", track ); // We don't do anything here, since we captured the stream ourselves }, onremotetrack: function (track, mid, on, metadata) { Janus.debug( "Remote track (mid=" + mid + ") " + (on ? "added" : "removed") + (metadata ? " (" + metadata.reason + ") " : "") + ":", track ); // Now that we're aware of the remote stream, we process it to visualize it if (!on) { // Track removed, get rid of the stream and the rendering $("#peeraudio" + mid).remove(); delete remoteTracks[mid]; return; } // If we're here, a new track was added $("#spinner").remove(); if (track.kind === "audio") { // New audio track: create a stream out of it, and use a hidden