### Python Example API Client Setup Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md Installs necessary Python packages (aiohttp, configparser, asyncio) and runs the main script for the Python Zello Channel API example. ```bash brew install python3 pip3 install aiohttp pip3 install configparser pip3 install asyncio cd py python3 main.py ``` -------------------------------- ### Node.js Example API Client Setup Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md Installs Node.js dependencies using npm and runs the index.js file for the Node.js Zello Channel API example. ```bash cd js npm install node index.js ``` -------------------------------- ### .NET Example API Client Setup Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md Builds and runs the .NET Core application for the Zello Channel API example. ```bash cd cs dotnet build dotnet run ``` -------------------------------- ### Install opus-tools on Linux Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md Installs the opus-tools utility on Debian-based Linux distributions using apt-get, necessary for Opus audio encoding. ```bash sudo apt-get install opus-tools ``` -------------------------------- ### Install opus-tools on Windows Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md Provides instructions to download and unpack precompiled binaries for opus-tools on Windows. ```powershell Download the precompiled [binaries](https://archive.mozilla.org/pub/opus/win32/opus-tools-0.2-opus-1.3.zip) and unpack. ``` -------------------------------- ### Zello Login and Application Start Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/09-zes-sample.html Handles user login by saving credentials to local storage and then starts the Zello application. It checks for the presence of necessary local storage items before proceeding. ```javascript function login() { window.localStorage.network = document.getElementById('network').value; window.localStorage.username = document.getElementById('username').value; window.localStorage.password = document.getElementById('password').value; window.localStorage.token = document.getElementById('token').value; window.localStorage.channel = document.getElementById('channel').value; start(); return false; } function start() { if (!window.localStorage || !window.localStorage.network || !window.localStorage.username || !window.localStorage.password || !window.localStorage.token || !window.localStorage.channel) { return; } connect( window.localStorage.network, window.localStorage.username, window.localStorage.password, window.localStorage.token, window.localStorage.channel ); document.getElementById('messages').innerHTML = ''; } ``` -------------------------------- ### Install opus-tools on macOS Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md Installs the opus-tools utility on macOS using Homebrew, which is required for encoding audio files with the Opus codec. ```bash brew install opus-tools ``` -------------------------------- ### Login and Initialization Logic Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/08-zellowork-sample.html Handles user login by storing network credentials and session tokens in local storage and then initiating the application's start sequence. It prevents the default form submission behavior. Dependencies include DOM elements for input fields and the `start()` function. ```javascript function login() { window.localStorage.network = document.getElementById('network').value; window.localStorage.username = document.getElementById('username').value; window.localStorage.password = document.getElementById('password').value; window.localStorage.token = document.getElementById('token').value; window.localStorage.channel = document.getElementById('channel').value; start(); return false; } ``` -------------------------------- ### Application Start and Local Storage Check Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/08-zellowork-sample.html Initializes the application by checking for the presence of necessary configuration data (network, username, password, token, channel) in local storage. If all required data is present, it proceeds to connect to the Zello network. Dependencies include local storage and the `connect()` function. ```javascript function start() { if ( !window.localStorage || !window.localStorage.network || !window.localStorage.username || !window.localStorage.password || !window.localStorage.token || !window.localStorage.channel ) { return; } connect( window.localStorage.network, window.localStorage.username, window.localStorage.password, window.localStorage.token, window.localStorage.channel ); document.getElementById('messages').innerHTML = ''; } ``` -------------------------------- ### Start a Voice Message Source: https://github.com/zelloptt/zello-channel-api/blob/master/docs/js/Session.html Explains how to start recording and sending a voice message, with examples for using default or custom recorder and encoder configurations. ```javascript // use default recorder and encoder var outgoingMessage = session.startVoiceMessage(); // use custom recorder var outgoingMessage = session.startVoiceMessage({ recorder: CustomRecorder }); // use custom recorder and encoder var outgoingMessage = session.startVoiceMessage({ recorder: CustomRecorder, encoder: CustomEncoder }); ``` -------------------------------- ### Build the SDK Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/README.md Installs project dependencies and builds the Zello Channels JavaScript SDK. ```bash npm install npm run build ``` -------------------------------- ### JavaScript Example: Fetching Channels Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/06-send-pre-recorded.html This JavaScript snippet demonstrates how to fetch a list of channels using the Zello Channel API. It utilizes the `fetch` API to make a GET request to the `/channels` endpoint. ```javascript async function getChannels() { try { const response = await fetch('/channels'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const channels = await response.json(); console.log('Channels:', channels); return channels; } catch (error) { console.error('Error fetching channels:', error); } } getChannels(); ``` -------------------------------- ### HTML Structure for Zello Channel Example Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/10-multichannel-player-recorder.html Defines the basic HTML structure for the Zello Channel API example, including elements for displaying channel status and buttons for connecting/disconnecting and push-to-talk. ```html
``` -------------------------------- ### Recorder Class Methods Source: https://github.com/zelloptt/zello-channel-api/blob/master/docs/js/recorder.js.html Provides methods for initializing, starting, and stopping audio recording. It handles audio context setup, source node connection, and data emission. The `init` method ensures the recorder is in an inactive state before starting, while `stop` disconnects audio nodes and signals the encoder. ```javascript class Recorder { init() { if (this.state !== "inactive") { return global.Promise.reject("Recording is not inactive"); } this.initAudioContext(); this.initAudioGraph(); return this.initSourceNode().then((sourceNode) => { this.state = "recording"; this.sourceNode = sourceNode; this.sourceNode.connect(this.monitorGainNode); this.sourceNode.connect(this.recordingGainNode); this.onready(); }); } stop() { if (this.state !== "inactive") { this.state = "inactive"; this.monitorGainNode.disconnect(); this.scriptProcessorNode.disconnect(); this.recordingGainNode.disconnect(); this.sourceNode.disconnect(); if (!this.options.leaveStreamOpen) { this.clearStream(); } // send to encoder this.encoder.postMessage({command: "done"}); } } start() {} /** * Emit recorded data portion to letOutgoingMessage instance get recorder data.
*
* @method Recorder#ondata
* @param {Float32Array} data pcm data portion
* */
ondata(data) {}
onready() {}
}
module.exports = Recorder;
```
--------------------------------
### Zello Channel API Initialization and Connection
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/10-multichannel-player-recorder.html
Initializes the Zello Channel SDK and establishes connections to Zello channels. It handles connection states, push-to-talk events, and error callbacks.
```javascript
function start() {
updateStatus(0, 'offline');
updateStatus(1, 'offline');
ZCC.Sdk.init({
player: true,
recorder: true,
encoder: true,
widget: false
}).then(function() {
var sessions = [
{
isConnected: false,
session: new ZCC.Session({
serverUrl: '',
channel: '',
authToken: '',
username: '',
password: ''
})
},
{
isConnected: false,
session: new ZCC.Session({
serverUrl: '',
channel: '',
authToken: '',
username: '',
password: ''
})
}
];
var connect_btn = document.getElementById('button_connect');
connect_btn.onclick = function() {
if (connectionState === 'connected') {
sessions.forEach((s, id) => {
s.isConnected = false;
s.session.disconnect();
updateStatus(id, 'offline');
});
connectionState = 'disconnected'
return;
}
connectionState = 'connecting';
connect_btn.innerHTML = "Connecting";
connect_btn.setAttribute('disabled', true);
sessions.forEach((s, id) => {
if (s.isConnected) {
return;
}
s.session.connect(function(err, result) {
if (err) {
updateStatus(id, 'offline');
s.isConnected = false;
return
}
connectionState = 'connected';
s.isConnected = true;
document.getElementById('button_ptt_' + id).onmousedown = function() {
outgoingMessage = s.session.startVoiceMessage();
};
document.getElementById('button_ptt_' + id).onmouseup = function() {
outgoingMessage.stop();
};
});
});
};
sessions.forEach((s, id) => {
s.session.on('status', status => updateStatus(id, status.status, status.users_online));
s.session.on('on_error', status => updateStatus(id, offline));
});
}).catch(function(err) {
console.trace(err);
})
}
```
--------------------------------
### Handling Incoming Voice Start and Stop Events
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/08-zellowork-sample.html
Logs messages when an incoming voice stream is about to start or has stopped. It associates the events with a specific message instance ID. Dependencies include the Zello SDK and a UI logging function.
```javascript
session.on('incoming_voice_will_start', function(incomingMessage) {
appendLog(`incoming_voice_will_start id: ${incomingMessage.instanceId}`, 'ok');
});
session.on('incoming_voice_did_stop', function(message) {
appendLog(`incoming_voice_did_stop: ${message.instanceId} stopped`, 'ok');
});
```
--------------------------------
### Zello UI Event Handlers Setup
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/09-zes-sample.html
Sets up event handlers for UI elements, including voice messages, text messages, and location sharing. These functions are called when the session status changes.
```javascript
function setUpImageHandlers() {
// Placeholder for image handler setup
}
function setUpVoiceHandler() {
document.getElementById('button').onmousedown = function() {
if (!document.getElementById('button').className.match(/disabled/)) {
var options = {};
var forUsername = document.getElementById('for').value;
if (forUsername) {
options.for = forUsername;
}
outgoingMessage = session.startVoiceMessage(options);
}
};
document.getElementById('button').onmouseup = function() {
outgoingMessage.stop();
};
document.getElementById('button').onclick = function() {
return false;
};
}
function setUpTextMessageHandler() {
// Placeholder for text message handler setup
}
function setUpLocationHandler() {
// Placeholder for location handler setup
}
```
--------------------------------
### Install Vendor Dependencies
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/README.md
Updates and initializes Git submodules, which are necessary for vendor dependencies.
```bash
git submodule update --init --recursive
```
--------------------------------
### Zello Channel API Authentication Guide
Source: https://github.com/zelloptt/zello-channel-api/blob/master/AUTH.md
This section outlines the process for generating production authentication tokens for the Zello Channel API. It requires using an Issuer and Private Key on a server to provision tokens for client applications. Detailed instructions and sample code in Go, Javascript, and PHP are available in the referenced 'Channel API Authentication guide'.
```APIDOC
Channel API Authentication Guide:
Refer to the 'Channel API Authentication guide' for detailed instructions and sample code using Go, Javascript, and PHP for generating production auth tokens.
```
--------------------------------
### Zello SDK Initialization and Session Management
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/09-zes-sample.html
Initializes the Zello SDK and establishes a session with the Zello network. It handles connection events, status updates, and errors.
```javascript
function connect(network, username, password, token, channel) {
document.getElementById('network').value = window.localStorage.network;
document.getElementById('username').value = window.localStorage.username;
document.getElementById('password').value = window.localStorage.password;
document.getElementById('token').value = window.localStorage.token;
document.getElementById('channel').value = window.localStorage.channel;
ZCC.Sdk.init({ player: true, widget: false }).then(function() {
session = new ZCC.Session({
serverUrl: network,
channel: channel,
authToken: token,
username: username,
password: password
});
session.on('session_start_connect', function() {
appendLog(`session_start_connect`);
});
session.connect().catch((err) => {
console.trace(err);
});
session.on('status', function(status) {
updateStatusActions(status);
appendLog(`status from ${status.channel} channel changed to: ${status.status} users online: ${status.users_online}`, 'ok');
setUpImageHandlers();
setUpVoiceHandler();
setUpTextMessageHandler();
setUpLocationHandler();
});
session.on('session_connect', function() {
appendLog(`session_connect`);
});
session.on('error', function(error) {
appendLog(`error: ${error}`, 'error');
});
session.on('session_fail_connect', function() {
appendLog(`session_fail_connect`, 'error');
});
session.on('session_disconnect', function() {
appendLog(`session_disconnect`, 'error');
});
session.on('session_connection_lost', function(error) {
appendLog(`session_connection_lost: ${error}`, 'error');
});
});
}
```
--------------------------------
### Zello Channel API - Status Styling
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/02-player-recorder.html
CSS rules for styling the status indicator and the connection button.
```css
.status { font-size: 50px; color: silver; }
.status.online { color: green; }
button {
width: 200px;
height: 200px;
border-radius: 100px;
outline: unset;
}
```
--------------------------------
### Connect to Zello Server
Source: https://github.com/zelloptt/zello-channel-api/blob/master/docs/js/Session.html
Shows how to connect to the Zello server using the Session's connect method, with examples for both promise-based and callback-based handling.
```javascript
// promise
session.connect()
.then(function(result) {
console.log('Session started: ', result)
})
.catch(function(err) {
console.trace(err);
});
// callback
session.connect(function(err, result) {
if (err) {
console.trace(err);
return;
}
console.log('session started:', result)
});
```
--------------------------------
### CSS for Status Display
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/10-multichannel-player-recorder.html
Provides CSS styling for the status display elements, defining default styles and specific styles for online and offline states.
```css
.status { font-size: 30px; font-weight: bolder; color: silver; }
.status.online { color: green; }
```
--------------------------------
### VoiceStreamState.STARTING
Source: https://github.com/zelloptt/zello-channel-api/blob/master/docs/Android/com.zello.channel.sdk/-voice-stream-state/-s-t-a-r-t-i-n-g.html
Represents the state where the voice stream is starting and waiting for the server or audio layer to become ready. This is a crucial initial state before audio transmission can begin.
```APIDOC
VoiceStreamState.STARTING
Description: Waiting for the server or audio layer to be ready.
Related States: [VoiceStreamState](../index.html)
```
--------------------------------
### Start Providing Audio
Source: https://github.com/zelloptt/zello-channel-api/blob/master/docs/Android/com.zello.channel.sdk/-voice-source/index.html
This abstract Kotlin function is called when an outgoing stream is ready to receive voice data. It requires a VoiceSink, sample rate, and an OutgoingVoiceStream.
```kotlin
abstract fun startProvidingAudio(sink: VoiceSink, sampleRate: Int, stream: OutgoingVoiceStream): Unit
```
--------------------------------
### Initialize and Connect to Zello Channel
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/07-widget-play.html
This snippet demonstrates how to initialize the Zello SDK, create a widget, establish a session, and connect to the Zello server. It handles the asynchronous nature of these operations using Promises.
```javascript
var session = null;
var widget = null;
function connect() {
ZCC.Sdk.init({
player: true,
recorder: false,
encoder: false,
widget: true
})
.then(function() {
widget = new ZCC.Widget({
headless: false,
element: document.getElementById('player')
});
session = new ZCC.Session({
serverUrl: 'wss://zello.io/ws/',
channel: '',
authToken: '',
listenOnly: true
});
widget.setSession(session);
return session.connect();
})
.then(function() {
// connected
})
.catch(function(err) {
console.warn(err);
});
}
```
--------------------------------
### Zello Channel API Initialization and Connection
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/02-player-recorder.html
Initializes the Zello Channel SDK and establishes a connection to a Zello server. It handles player, recorder, and encoder functionalities, and sets up event listeners for status updates and voice message interactions.
```javascript
function updateStatus(status, usersOnline) {
var el = document.getElementById('status');
el.className = 'status ' + status;
if (status === 'offline') {
el.innerHTML = '• offline';
} else {
el.innerHTML = '•' + usersOnline + ' users online';
document.getElementById('button').removeAttribute('disabled');
}
}
var outgoingMessage = null;
function connect() {
updateStatus('offline');
ZCC.Sdk.init({
player: true,
recorder: true,
encoder: true,
widget: false
}).then(function() {
var session = new ZCC.Session({
serverUrl: 'wss://zellowork.io/ws/',
channel: '',
authToken: '',
username: '',
password: ''
});
session.connect(function() {
document.getElementById('button').onmousedown = function() {
outgoingMessage = session.startVoiceMessage();
};
document.getElementById('button').onmouseup = function() {
outgoingMessage.stop();
};
}).catch(function(err) {
console.trace(err);
});
session.on('status', function(status) {
updateStatus(status.status, status.users_online);
});
}).catch(function(err) {
console.trace(err);
});
}
```
--------------------------------
### Zello Voice Message Lifecycle Events
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/09-zes-sample.html
Logs events related to the lifecycle of incoming voice messages, including when a voice message is about to start and when it has stopped.
```javascript
session.on('incoming_voice_will_start', function(incomingMessage) {
appendLog(`incoming_voice_will_start id: ${incomingMessage.instanceId}`, 'ok');
});
session.on('incoming_voice_did_stop', function(message) {
appendLog(`incoming_voice_did_stop: ${message.instanceId} stopped`, 'ok');
});
```
--------------------------------
### Configure C# Zello Ogg Parser
Source: https://github.com/zelloptt/zello-channel-api/blob/master/examples/README.md
Instructions to switch the Ogg parser in the .NET project from Concentus to Zello's native parser by modifying thecsproj file and rebuilding.
```bash
cd cs
rm -rf bin obj
dotnet build
```
--------------------------------
### Connect to Zello Channel and Handle Events
Source: https://github.com/zelloptt/zello-channel-api/blob/master/sdks/js/examples/01-player.html
Initializes the Zello SDK, establishes a session connection to the Zello server, and sets up event listeners for various session states and incoming voice data. This function demonstrates how to manage connection lifecycle and process real-time audio.
```javascript
function connect() {
ZCC.Sdk.init({
player: true,
recorder: false,
encoder: false,
widget: false
}).then(function() {
var session = new ZCC.Session({
serverUrl: 'wss://zello.io/ws/',
channel: '',
authToken: '',
listenOnly: true
});
session.connect().catch((err) => {
console.trace(err);
});
session.on(ZCC.Constants.EVENT_SESSION_START_CONNECT, function() {
console.warn('EVENT_SESSION_START_CONNECT');
});
session.on(ZCC.Constants.EVENT_SESSION_CONNECT, function() {
console.warn('EVENT_SESSION_CONNECT');
});
session.on(ZCC.Constants.EVENT_SESSION_FAIL_CONNECT, function(err) {
console.warn('EVENT_SESSION_FAIL_CONNECT', err);
});
session.on(ZCC.Constants.EVENT_SESSION_DISCONNECT, function() {
console.warn('EVENT_SESSION_DISCONNECT');
});
session.on(ZCC.Constants.EVENT_SESSION_CONNECTION_LOST, function(err) {
console.warn('EVENT_SESSION_CONNECTION_LOST', err);
});
session.on(ZCC.Constants.EVENT_STATUS, function(status) {
console.warn('EVENT_STATUS', status);
});
session.on(ZCC.Constants.EVENT_INCOMING_VOICE_DATA, function(incomingMessageData) {
console.warn('EVENT_INCOMING_VOICE_DATA', 'from session', incomingMessageData);
});
session.on(ZCC.Constants.EVENT_INCOMING_VOICE_DATA_DECODED, function(pcmData, incomingMessage) {
console.warn('EVENT_INCOMING_VOICE_DATA_DECODED', 'from session', pcmData.length, incomingMessage);
});
session.on(ZCC.Constants.EVENT_INCOMING_VOICE_WILL_START, function(incomingMessage) {
console.warn('EVENT_INCOMING_VOICE_WILL_START', incomingMessage);
incomingMessage.on(ZCC.Constants.EVENT_INCOMING_VOICE_DATA, function(incomingMessageData) {
console.warn('EVENT_INCOMING_VOICE_DATA', 'from message', incomingMessageData);
});
incomingMessage.on(ZCC.Constants.EVENT_INCOMING_VOICE_DATA_DECODED, function(pcmData) {
console.warn('EVENT_INCOMING_VOICE_DATA_DECODED', 'from message', pcmData.length, incomingMessage);
});
incomingMessage.on(ZCC.Constants.EVENT_INCOMING_VOICE_DID_STOP, function() {
console.warn('Done with message');
});
});
}).catch(function(err) {
console.trace(err);
});
}
```
--------------------------------
### Sdk Class Documentation
Source: https://github.com/zelloptt/zello-channel-api/blob/master/docs/js/Sdk.html
Documentation for the Sdk class in the Zello Channel API. It outlines the static init method for SDK initialization.
```APIDOC
Class: Sdk
SDK functions support both callbacks with `(err, result)` arguments and also return promises that resolve with `result` argument or fail with `err` argument.
##### Example
### Methods
#### (static) init(optionsopt, userCallbackopt) → {promise}
Initialize SDK parts and components. Loads required parts Default recorder will fail to load on http:// pages, it requires https://
##### Parameters:
Name
Type
Attributes
Default
Description
`options`
object
(err, result) arguments
* and also return promises that resolve with result argument or fail with err argument.
*
* @example
*
*
*
*
*
*
**/
class Sdk {
/**
* @description Initialize SDK parts and components.
* Loads required parts
*
* Default recorder will fail to load on http:// pages, it requires https://
*
* @param {object} [options] List of components to be loaded (see example).
* Set to false to skip loading of a specific component,
* or provide class function to be used as a custom player, decoder, recorder or encoder
* (see examples).
*
* @param {function} [userCallback] User callback to fire when sdk parts required by this init call are loaded
* @return {promise} Promise that resolves when sdk parts required by this init call are loaded
*
* @example
*
// callback
ZCC.Sdk.init({
player: true, // true by default
decoder: true, // true by default
recorder: true, // true by default
encoder: true, // true by default
}, function(err) {
if (err) {
console.trace(err);
return;
}
console.log('zcc sdk parts loaded')
})
// promise
ZCC.Sdk.init({
player: true,
decoder: true,
recorder: true,
encoder: true
})
.then(function() {
console.log('zcc sdk parts loaded')
}).catch(function(err) {
console.trace(err);
})
**/
static init(options = {}, userCallback = null) {
Sdk.checkBrowserCompatibility();
let dfd = Promise.defer();
let url = Sdk.getMyUrl();
Sdk.initOptions = Object.assign({
player: true,
decoder: true,
recorder: true,
encoder: true,
widget: false
}, options);
let scriptsToLoad = [
url + 'zcc.session.js',
url + 'zcc.constants.js',
url + 'zcc.incomingimage.js',
url + 'zcc.outgoingimage.js',
url + 'zcc.incomingmessage.js',
url + 'zcc.outgoingmessage.js'
];
let shouldInitDefaultPlayer = false;
if (Sdk.initOptions.player && !Utils.isFunction(Sdk.initOptions.player)) {
scriptsToLoad.push(url + 'zcc.player.js');
shouldInitDefaultPlayer = true;
}
if (Sdk.initOptions.decoder && !Utils.isFunction(Sdk.initOptions.decoder)) {
scriptsToLoad.push(url + 'zcc.decoder.js');
}
if (Sdk.initOptions.recorder && !Utils.isFunction(Sdk.initOptions.recorder)) {
scriptsToLoad.push(url + 'zcc.recorder.js');
}
if (Sdk.initOptions.encoder && !Utils.isFunction(Sdk.initOptions.encoder)) {
scriptsToLoad.push(url + 'zcc.encoder.js');
}
if (Sdk.initOptions.widget) {
scriptsToLoad.push(url + 'zcc.widget.js');
}
$script(scriptsToLoad, 'bundle');
$script.ready('bundle', () => {
if (typeof userCallback === 'function') {
userCallback.apply(userCallback);
}
if (shouldInitDefaultPlayer) {
Sdk.initDefaultPlayer();
}
dfd.resolve();
});
return dfd.promise;
}
static initDefaultPlayer() {
let library = Utils.getLoadedLibrary();
library.IncomingMessage.PersistentPlayer = new library.Player({
encoding: '32bitFloat',
sampleRate: 48000
});
}
static getMyUrl() {
if (myUrl) {
return myUrl;
}
const scripts = document.getElementsByTagName('script');
for (let i = 0; i < scripts.length; i++) {
let script = scripts[i];
let src = script.getAttribute('src');
if (src && src.match(/zcc.sdk\.js$/)) {
myUrl = src.replace(/zcc.sdk.js$/, '');
return myUrl;
}
}
return false;
}
static isHttps() {
return window.location.protocol.match(/https/);
}
}
```