Embedding a browser-based SIP phone to a web page
To embed a browser phone to a website or project, we need the simple HTML code and special dependence scripts that provide connection to Web Call Server and operation of the microphone
Use these instructions for quick installation and configuration of the server. In addition to that, you can connect to our demo server demo.flashphoner.com via the Websockets protocol to perform the tests
Step-by-step instructions for embedding a browser-based SIP phone in a web page
SIP browser phone is available in two options – with video call support and without video call support. Below we consider in detail the two options for the embedding process.
Option 1. SIP phone for audio-only call (without video)
To embed a SIP phone without video call capability to your web page, create two empty files phone-min.html and phone-min.js. These files will contain the minimum code.
Let’s analyze the contents of the files
HTML
Let’s place the necessary elements in phone-min.html:
1. Import the main API script
<script type="text/javascript" src="https://flashphoner.com/downloads/builds/flashphoner_client/wcs_api-2.0/current/flashphoner.js"></script>
2. Import the SIP phone script
<script type="text/javascript" src="phone-min.js"></script>
3. Initialize the API on page load
<body onload="init_page()">
4. Add the field to enter the SIP number of the subscriber to be called
<input id="callee" type="text" placeholder="Callee SIP username"/>
5. Add the button “Call” to make an outgoing SIP call
<button type="button" onclick="call()">Call</button>
6. Add the div element for an incoming call notification
<div id="status"></div>
7. Add the button to answer the incoming call and the end call button
<button id="answerBtn" type="button">Answer</button> <button id="hangupBtn" type="button">Hangup</button>
8. Add two div elements for playing audio
<div id="localAudio"></div> <div id="remoteAudio"></div>
The full HTML code of the page looks like this:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <script type="text/javascript" src="https://flashphoner.com/downloads/builds/flashphoner_client/wcs_api-2.0/current/flashphoner.js"></script> <script type="text/javascript" src="phone-min.js"></script> </head> <body onload="init_page()"> <input id="callee" type="text" placeholder="Callee SIP username"/> <button type="button" onclick="call()">Call</button> <br> <div id="status"></div> <button id="answerBtn" type="button">Answer</button> <button id="hangupBtn" type="button">Hangup</button> <div id="localAudio"></div> <div id="remoteAudio"></div> </body> </html>
JavaScript
1. Create a constant for the status of the work WCS and call operation status
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var CALL_STATUS = Flashphoner.constants.CALL_STATUS;
2. Create global variables for audio stream and current call
var localAudio; var remoteAudio; var currentCall;
3. When you load an HTML page, initialize the API, get div elements for playing audio and invoke the function “connect()”, which provides connection to the WCS and SIP servers and allows receiving an incoming call
function init_page() { Flashphoner.init({}); localAudio = document.getElementById("localAudio"); remoteAudio = document.getElementById("remoteAudio"); connect(); }
4. The function “connect()” declares variables for the connection settings to the WCS and SIP servers. For correct work, you should replace the values on your own. URL – the URL of your WCS, sipOptions – data to connect to your SIP server. After declaring the variables, the function starts a new connection with the WCS and SIP servers
function connect() { var url = "wss://demo.flashphoner.com:8443" var registerRequired = true; var sipOptions = { login: "10001", authenticationName: "10001", password: "Pass123", domain: "your_sip_server.com", outboundProxy: "your_sip_server.com", port: "5060", registerRequired: registerRequired }; var connectionOptions = { urlServer: url, sipOptions: sipOptions }; //create session console.log("Create new session with url " + url); Flashphoner.createSession(connectionOptions).on(SESSION_STATUS.ESTABLISHED, function(session) { console.log(SESSION_STATUS.ESTABLISHED); }).on(SESSION_STATUS.REGISTERED, function(session) { console.log(SESSION_STATUS.REGISTERED); }).on(SESSION_STATUS.INCOMING_CALL, function(call) { call.on(CALL_STATUS.RING, function() { document.getElementById("status").textContent = (CALL_STATUS.RING); }).on(CALL_STATUS.ESTABLISHED, function() { document.getElementById("status").textContent = (CALL_STATUS.ESTABLISHED); }).on(CALL_STATUS.FINISH, function() { document.getElementById("status").textContent = (" "); console.log(CALL_STATUS.FINISH); currentCall = null; }); onIncomingCall(call); }); }
5. The function “call()” provides the capability to place an outgoing call
function call() { var session = Flashphoner.getSessions()[0]; var constraints = getConstraints(); var callee = document.getElementById("callee").value; var outCall = session.createCall({ callee: callee, remoteVideoDisplay: remoteAudio, localVideoDisplay: localAudio, constraints: constraints, stripCodecs: "SILK" }); outCall.call(); currentCall = outCall; hangupBtn.onclick = function() { outCall.hangup(); currentCall = null; } }
6. The function “onIncomingCall(inCall)” provides the capability to answer an incoming call
function onIncomingCall(inCall) { currentCall = inCall; var constraints = getConstraints(); answerBtn.onclick = function() { inCall.answer({ localVideoDisplay: localAudio, remoteVideoDisplay: remoteAudio, constraints: constraints, stripCodecs: "SILK" }); }; hangupBtn.onclick = function() { inCall.hangup(); currentCall = null; } }
7. The function “getConstraints()” sets the stream parameters. In our current example, the browser-based SIP phone will not have video call capability, so for the “video” parameter, set the value to “false”
function getConstraints() { var constraints = { audio: true, video: false, }; return constraints; }
The full JavaScript code looks like this:
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var CALL_STATUS = Flashphoner.constants.CALL_STATUS; var localAudio; var remoteAudio; var currentCall; function init_page() { Flashphoner.init({}); localAudio = document.getElementById("localAudio"); remoteAudio = document.getElementById("remoteAudio"); connect(); } function connect() { var url = "wss://demo.flashphoner.com:8443" var registerRequired = true; var sipOptions = { login: "10001", authenticationName: "10001", password: "Pass123", domain: "your_sip_server.com", outboundProxy: "your_sip_server.com", port: "5060", registerRequired: registerRequired }; var connectionOptions = { urlServer: url, sipOptions: sipOptions }; //create session console.log("Create new session with url " + url); Flashphoner.createSession(connectionOptions).on(SESSION_STATUS.ESTABLISHED, function(session) { console.log(SESSION_STATUS.ESTABLISHED); }).on(SESSION_STATUS.REGISTERED, function(session) { console.log(SESSION_STATUS.REGISTERED); }).on(SESSION_STATUS.INCOMING_CALL, function(call) { call.on(CALL_STATUS.RING, function() { document.getElementById("status").textContent = (CALL_STATUS.RING); }).on(CALL_STATUS.ESTABLISHED, function() { document.getElementById("status").textContent = (CALL_STATUS.ESTABLISHED); }).on(CALL_STATUS.FINISH, function() { document.getElementById("status").textContent = (" "); console.log(CALL_STATUS.FINISH); currentCall = null; }); onIncomingCall(call); }); } function call() { var session = Flashphoner.getSessions()[0]; var constraints = getConstraints(); var callee = document.getElementById("callee").value; var outCall = session.createCall({ callee: callee, remoteVideoDisplay: remoteAudio, localVideoDisplay: localAudio, constraints: constraints, stripCodecs: "SILK" }); outCall.call(); currentCall = outCall; hangupBtn.onclick = function() { outCall.hangup(); currentCall = null; } } function onIncomingCall(inCall) { currentCall = inCall; var constraints = getConstraints(); answerBtn.onclick = function() { inCall.answer({ localVideoDisplay: localAudio, remoteVideoDisplay: remoteAudio, constraints: constraints, stripCodecs: "SILK" }); }; hangupBtn.onclick = function() { inCall.hangup(); currentCall = null; } } function getConstraints() { var constraints = { audio: true, video: false, }; return constraints; }
SIP phone screenshot for an incoming call
SIP phone screenshot for an outgoing call
Option 2. SIP phone with video call capability
To embed a SIP phone with video call support on your web page, create two empty files phone-video-min.html and phone-video-min.js. These files will contain the minimum code.
Let’s analyze the contents of the files
HTML
Let’s place the necessary elements in phone-video-min.html:
1. Import the main API script
<script type="text/javascript" src="https://flashphoner.com/downloads/builds/flashphoner_client/wcs_api-2.0/current/flashphoner.js"></script>
2. Import the SIP phone script
<script type="text/javascript" src="phone-video-min.js"></script>
3. Specify styles for the “display” class. This is necessary for the further correct display of video in div elements
<style> .display { width: 100%; height: 100%; display: inline-block; } .display > video, object { width: 100%; height: 100%; } </style>
4. Initialize the API on page load
<body onload="init_page()">
5. We add two div elements in which the incoming and outgoing video streams will be played
<div id="localVideo" class="display" style="width:160px;height:120px;border: solid 1px"></div> <div id="remoteVideo" class="display" style="width:640px;height:480px;border: solid 1px"></div>
6. Add the field to enter the SIP number to be called
<input id="callee" type="text" placeholder="Callee SIP username"/>
7. Add the Call button to make an outgoing SIP call
<button type="button" onclick="call()">Call</button>
8. Add the div element for an incoming call notification
<div id="status"></div>
9. Add the button to answer an incoming call and the end call button
<button id="answerBtn" type="button">Answer</button> <button id="hangupBtn" type="button">Hangup</button>
The full HTML code of the page looks like this:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <script type="text/javascript" src="https://flashphoner.com/downloads/builds/flashphoner_client/wcs_api-2.0/current/flashphoner.js"></script> <script type="text/javascript" src="phone-video-min.js"></script> <style> .display { width: 100%; height: 100%; display: inline-block; } .display > video, object { width: 100%; height: 100%; } </style> </head > <body onload="init_page()"> <div id="localVideo" class="display" style="width:160px;height:120px;border: solid 1px"></div> <br> <div id="remoteVideo" class="display" style="width:640px;height:480px;border: solid 1px"></div> <br> <input id="callee" type="text" placeholder="Callee SIP username"/> <button type="button" onclick="call()">Call</button> <br> <div id="status"></div> <button id="answerBtn" type="button" >Answer</button> <button id="hangupBtn" type="button" >Hangup</button> </body> </html>
JavaScript
1. Create a constant for the status of the work WCS and call operation status
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var CALL_STATUS = Flashphoner.constants.CALL_STATUS;
2. Create global variables for audio stream and current call
var localVideo; var remoteVideo; var currentCall;
3. When you load an HTML page, initialize the API, get the div elements for playing audio and invoke the function “connect()”, which provides connection to the WCS and SIP servers and allows receiving an incoming call
function init_page() { Flashphoner.init({}); localVideo = document.getElementById("localVideo"); remoteVideo = document.getElementById("remoteVideo"); connect(); }
4. The function “connect()” declares variables for the connection settings to the WCS and SIP servers. For correct work, you should replace the values on your own. URL – the URL of your WCS, sipOptions – data to connect to your SIP server. After declaring the variables, the function starts a new connection with WCS and SIP servers
function connect() { var url = "wss://demo.flashphoner.com:8443" var registerRequired = true; var sipOptions = { login: "10001", authenticationName: "10001", password: "Pass123", domain: "your_sip_server.com", outboundProxy: "your_sip_server.com", port: "5060", registerRequired: registerRequired }; var connectionOptions = { urlServer: url, sipOptions: sipOptions }; //create session console.log("Create new session with url " + url); Flashphoner.createSession(connectionOptions).on(SESSION_STATUS.ESTABLISHED, function(session) { console.log(SESSION_STATUS.ESTABLISHED); }).on(SESSION_STATUS.REGISTERED, function(session) { console.log(SESSION_STATUS.REGISTERED); }).on(SESSION_STATUS.INCOMING_CALL, function(call) { call.on(CALL_STATUS.RING, function() { document.getElementById("status").textContent = (CALL_STATUS.RING); }).on(CALL_STATUS.ESTABLISHED, function() { document.getElementById("status").textContent = (CALL_STATUS.ESTABLISHED); }).on(CALL_STATUS.FINISH, function() { document.getElementById("status").textContent = (" "); console.log(CALL_STATUS.FINISH); currentCall = null; }); onIncomingCall(call); }); }
5. The function “call ()” provides the capability to place an outgoing call
function call() { var session = Flashphoner.getSessions()[0]; var constraints = getConstraints(); var callee = document.getElementById("callee").value; var outCall = session.createCall({ callee: callee, remoteVideoDisplay: remoteVideo, localVideoDisplay: localVideo, constraints: constraints, stripCodecs: "SILK" }); outCall.call(); currentCall = outCall; hangupBtn.onclick = function() { outCall.hangup(); currentCall = null; } }
6. The function “onIncomingCall(inCall)” provides the capability to answer an incoming call
function onIncomingCall(inCall) { currentCall = inCall; var constraints = getConstraints(); answerBtn.onclick = function() { inCall.answer({ localVideoDisplay: localVideo, remoteVideoDisplay: remoteVideo, constraints: constraints, stripCodecs: "SILK" }); }; hangupBtn.onclick = function() { inCall.hangup(); currentCall = null; } }
7. The function “getConstraints()” sets the stream parameters. In this example, the browser-based SIP phone supports video calls, so for the “audio” and “video” parameters, set the value to “true”
function getConstraints() { var constraints = { audio: true, video: true, }; return constraints; }
The full JavaScript code looks like this:
var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS; var CALL_STATUS = Flashphoner.constants.CALL_STATUS; var localVideo; var remoteVideo; var currentCall; function init_page() { Flashphoner.init({}); localVideo = document.getElementById("localVideo"); remoteVideo = document.getElementById("remoteVideo"); connect(); } function connect() { var url = "wss://demo.flashphoner.com:8443" var registerRequired = true; var sipOptions = { login: "10001", authenticationName: "10001", password: "Pass123", domain: "your_sip_server.com", outboundProxy: "your_sip_server.com.com", port: "5060", registerRequired: registerRequired }; var connectionOptions = { urlServer: url, sipOptions: sipOptions }; //create session console.log("Create new session with url " + url); Flashphoner.createSession(connectionOptions).on(SESSION_STATUS.ESTABLISHED, function(session) { console.log(SESSION_STATUS.ESTABLISHED); }).on(SESSION_STATUS.REGISTERED, function(session) { console.log(SESSION_STATUS.REGISTERED); }).on(SESSION_STATUS.INCOMING_CALL, function(call) { call.on(CALL_STATUS.RING, function() { document.getElementById("status").textContent = (CALL_STATUS.RING); }).on(CALL_STATUS.ESTABLISHED, function() { document.getElementById("status").textContent = (CALL_STATUS.ESTABLISHED); }).on(CALL_STATUS.FINISH, function() { document.getElementById("status").textContent = (" "); console.log(CALL_STATUS.FINISH); currentCall = null; }); onIncomingCall(call); }); } function call() { var session = Flashphoner.getSessions()[0]; var constraints = getConstraints(); var callee = document.getElementById("callee").value; var outCall = session.createCall({ callee: callee, remoteVideoDisplay: remoteVideo, localVideoDisplay: localVideo, constraints: constraints, stripCodecs: "SILK" }); outCall.call(); currentCall = outCall; hangupBtn.onclick = function() { outCall.hangup(); currentCall = null; } } function onIncomingCall(inCall) { currentCall = inCall; var constraints = getConstraints(); answerBtn.onclick = function() { inCall.answer({ localVideoDisplay: localVideo, remoteVideoDisplay: remoteVideo, constraints: constraints, stripCodecs: "SILK" }); }; hangupBtn.onclick = function() { inCall.hangup(); currentCall = null; } } function getConstraints() { var constraints = { audio: true, video: true, }; return constraints; }
An example of a SIP phone with an incoming video call. In the screenshot below, the incoming call has already been accepted and the exchange of video streams has begun
Thus, you can embed the SIP telephone with or without video call support into your web page.
Download Web Call Server 5
System requirements: Linux x86_64, 1 core CPU, 2 Gb RAM, Java
Installation:
- wget https://flashphoner.com/download-wcs5.2-server.tar.gz
- Unpack and install using 'install.sh'
- Launch server using command 'service webcallserver start'
- Open the web interface https://host:8444 and activate your license
If you are using Amazon EC2, you don't need to download anything.