javascript logo

JavaScript VoIP developers 101

Part 4: Video call between two webbrowsers

Study the following article to get more information about doing basic tasks in the Ozeki Phone System by using your JavaScript application. This guide presents how to make a video call from a webbrowser to a webbrowser.

1. What you need

  • A text editor (for example Notepad++)
  • Ozeki Phone System installed on your PC (Download now)

2. Get started

  • Create a Webphone outside line in Ozeki Phone System
  • Get IP address and port of your PBX (e.g. http://ozekixepbx.ip:7777/)
  • Create a html document
  • Add reference to WebphoneAPI
    (e.g. <script type="text/javascript" src="http://ozekixepbx.ip:7777/WebphoneAPI"></script>)

User manual

The Ozeki Phone System makes it possible to connect the customers and the appropriate extensions together through a fully customisable WebPhone. It can be done by using your PBX and the configurable dial plan rules. For this purpose you only need to install a Webphone outside line in the Ozeki Phone Sytem XE and add the required routing rule. If the default dial plan rule has been added there is no need to specify the called number before making a call. In addition, it is also possible to dial a previously installed extension or an outside line number directly by entering its telephone number. In our videocall example we will call a webclient. Webclients have outside line numbers. They are connected to the webphone outside line. Everytime a webclient connects to a webphone outside line it gets a new number. How to setup a Webphone outside line

For using WebPhoneAPI a webserver is essentially needed on which your written code will be executable. Any webserver can be used, just select one and download it. In this example Wampserver and Apache was used. After installing WampServer, you need to modify the 'Listen 80' value in the httpd.conf file belonging to Apache in order to avoid port collision. Rewrite it to 'Listen 8080' (or to any other number that is not used by other applications). Do the modification then restart the service. After that, open the folder where you have installed Wamp then select the 'www' folder. Here create a 'videocall(browser-browser).html' file and put the following content in it:

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript">

	</script>
</head>
<body>
	<button onclick="hangUpCall()">Hang up</button>
	<h1 id="header"></h1> 
	<table>
	<tr>
		<td><p align="center"><b>Incoming feed</b></p></td>
		<td><p align="center"><b>Your camera</b></p></td>
	</tr>
	<tr>
		<td id="incomingCam"></td>
		<td id="yourCam"></td>
	</tr>
	</table>
</body>
</html>

Code example 1 - Basic html structure

The JavaScript code which you will write needs to be placed between <script> </script> tags.

Implementation

Before developing JavaScript, reference the WebphoneAPI JavaScript file into your source. Place the following row directly after the opening <head> tag:

<script type="text/javascript" 
src="http://ozekixepbx.ip:PBX_ServerPort/WebphoneAPI"></script>

Code example 2 - <script> nodes after the <head> tag

In this script the 'ozekixepbx.ip' and the 'PBX_ServerPort' needs to be the server address and port number of Ozeki Phone System configured previously. The default port number is 7777.

3. Create a JavaScript code calling up webbrowser from a webbrowser

You need to start this code in two webbrowsers so one of them could make the call and the other one could accept it. A random generator determines which party will make the call and which will accept it. Both party choses a number and the party with the lower number makes the call.

  1. Declare the variables
  2. Connect to the webphone outside line
  3. Create the call or
  4. Accept the call
  5. Set up the video feed

Declare the variables

MyCall will get a call object as a value. We will be able to control the call through this object. MyCam will get an OzCamera object as a value. You can refer to the camera and control it though this object. The value of randomnumber is a randomly generated integer number from 0 to 200, this determines the time in milliseconds what the webclient will wait to make a call. If the webclient already accepted a call from the other party, then it won't make a call when the time passes. The clientinfo variable will get the value of an object. The most important attributes of this object is phoneNumber and status, these are details of the other party. This is essential to determine which number to dial.

var MyCall = null;
var MyCam = null;
var randomnumber = Math.floor(Math.random()*201);
var clientinfo;

Code example 3 - Variables

Connect to the webphone outside line

After declaring the attributes we wait a short period of time, for example 0.2 seconds till the page is loaded then we call the begin() function. This function registers to the onConnectionStateChanged event and tries to connect to the webphone outside line.

The onConnectionStateChanged event occurs when the state of the connection changes.
have 4 states:
"ACCESS_GRANTED", "ACCESS_DENIED", "CONNECTION_FAILED", "CONNECTION_CLOSED".
It is vital to notice when the webclient has connected to the webphone outside line. You can connect to the webphone outside line by using the connect method . As a parameter of this method you need to provide the IP address of the Ozeki Phone System you use and the name of the webphone outside line (Code Example 4).

setTimeout('begin()', 200); //wait 0.2 seconds

function begin() {
	OzWebClient.onConnectionStateChanged(connectionStateChanged);
    OzWebClient.connect("192.168.115.131", "Webphone1");
}

Code example 4 - Connecting to the webphone outside line

Create the call

When an onConnectionStateChanged event occurs the parameter of the event is called, which is in our case the connectionStateChanged function. This function gets the current connectionstate in its state parameter. If this state parameter equals the "ACCESS_GRANTED" string then the webclient has been successfully connected. Now its time to register to the onClientStateChanged and onIncomingCall events. The onClientStateChanged event occurs when an other client connects to the webphone outside line, the onIncomingCall event occurs when the webclient receives an incoming call. In our example it will receive an incoming call from another webclient.

It is time to set up the camera. We make a MyCam object with the OzCamera.getCameraByName() constructor, which connects the default camera to the object. Then we set the resolution and FPS of the camera with the setMode method. We created previously a table in HTML. The cell with the "yourCam" ID will show the picture of the webclients camera with the setDisplay method.

We start a time counter when the other webclient connects. Both of the webclients will start the counter at the same time and the client with the fastest count will create the call. When creating a call it uses the phone number of the other client (clientinfo.phoneNumber) as a parameter in the createCall method. This method makes a call object called MyCall. Then the start method will run on this object to call the other webclient. Then it will register on the onCallStateChanged event with the callStateChanged function.

If you check the callStateChanged function, you can see that if the call is not in "RINGING", "IN_CALL" or "HOLD" state then the call will be hung up and the webclient will be disconnected from the webphone outside line. The hangUPCall function also occurs when the 'Hang up' button is pressed, so both parties can terminate the call. If the call changes to "IN_CALL" state you can set up the camera feed. The setUpVideoFeed() function will be discussed later. (Code Example 4).

function connectionStateChanged(info) {
    console.log(info.State);
    if (info.State == ConnectionState.ACCESS_GRANTED) {
        OzWebClient.onClientStateChanged(clientstatechanged);
        OzWebClient.onIncomingCall(incoming);
        MyCam = OzCamera.getCameraByName();
        MyCam.setMode(320,240,15);
        MyCam.setDisplay("yourCam");
    }
}

		
function clientstatechanged(client){
	clientinfo = client;
	setTimeout(startcall, randomnumber);//starts call after a random time
}
		
function startcall() {
	if(clientinfo.status == "ONLINE" && MyCall == null){
		MyCall = OzWebClient.createCall(clientinfo.phoneNumber);
		MyCall.start();
		MyCall.onCallStateChanged(callStateChanged);
		console.log("calling " + MyCall.getOtherParty() + "...");
	}
}
		
function callStateChanged(state) {
	console.log(state);
    if (state != "RINGING" && state != "IN_CALL" && state != "HOLD") {
    	setTimeout(hangUpCall, 1000);
    }
	if (state == "IN_CALL") {
		setUpVideoFeed(); //sets up the camera feed
	}
}	

function hangUpCall() {
	if (MyCall) {
    	MyCall.hangUp();
		console.log("The call is hung up.");
		document.getElementById("header").innerHTML = "The call is hung up.";
        MyCall = null;
    }
	OzWebClient.disconnect();
}

Code example 5 - Create the call, check its callstate, hang up the call

Accept the call

The following function occurs when a webclient receives an incoming call. Its input parameter is a call object. Its content will only run if no call is in progress that is why we check if MyCall is equal to null. It accepts the incoming call and registers on the onCallStateChanged event, registering on this event is crucial to know when the other party hangs up the call and to know when to set up the feed of the camera (Code Example 6).

function incoming(call) {
	if(MyCall == null){
		MyCall = call;
		console.log("accepting call...");
		MyCall.accept();
		MyCall.onCallStateChanged(callStateChanged);
	}
}

Code example 6 - Accepts incoming call

Set up the video feed

You can attach the webclients camera to the call with the attachCamera method. This method gets the OzCamera object as an input. After the camera is attached the other party gets the feed. You can show the incoming camera feed with the setRemoteDisplay method on the table created previously. It will be shown on the cell with the "incomingCam" ID (Code Example 7).

function setUpVideoFeed(){
	MyCall.attachCamera(MyCam);
	MyCall.setRemoteDisplay("incomingCam");
}

Code example 7 - Setting up the video feed

4. Create a more advanced project

The Ozeki Phone System offers a lot more options for JavaScript developers. You can interact with existing calls, control and configure the PBX, you can introduce new communication techniques and media formats.
For a complete list of JavaScript commands, check out: JavaScript API reference book

If you have any questions or need assistance, please contact us at  info@ozekiphone.com

More information