Voximplant. Blog

Audio conferencing

Audio Conference

Audio conferencing functionality offered by VoxImplant is one of the most advanced and flexible audio conferencing implementations you can find. Developers have full control of every call connected to the conference via VoxEngine. For example, it’s possible to record particular calls connected to the conference or the whole conference, developers can record only one audio stream that goes to the conference (if you need to get the audio from particular participant). It’s possible to play audio file (or TTS) into the conference or to particular participant (call connected to the conference), mute/unmute participants, and even join different conferences together. Our Web SDK lets developers create web client applications for the conference in minutes (WebRTC will be used Chrome/Firefox/Opera or Flash in IE/Safari), same with Mobile SDKs. It’s possible to implement convenient conference controls using messaging functionality (inside the call). In addition, SIP software and devices can be connected to the conference. It’s hard to imagine audio conferencing service you can’t build using VoxImplant. There are only few things we haven’t finished yet – wideband audio support and voice activity detection (both are being developed by our brilliant engineering team, so they should become available soon).

Overview

There are two types of conferences that can be created, let’s call them Local and Standalone. The main difference between them is in the type of calls that can be connected to the conference.

Local conference exists only inside the VoxEngine session, it means you can make some call (session will be created together with the call) then create conference inside the session and connect additional outbound calls (up to 10 calls per session) initiated from the session to the conference. You won’t be able to connect new incoming calls to Local conference. It’s useful for scenarios when you need to add additional participants on-the-fly during the call (for example, for call whisper in contact center).

Standalone conference also exists inside its own VoxEngine session, so you have full control of the conference on VoxEngine level, but in this case the call limit per session is 100 and you can forward incoming calls to the conference (of course, you can make outbound calls from the same session and join them to the conference like with Local conference). VoxEngine sessions don’t exist more than 1 minute without any active calls inside, so this type of conference can be started either by specific HTTP request, or by incoming call.

We have created this image to help understand the difference between two types of conferences:
Conference Types

The Details

As you can see on the scheme there are two ways of starting the VoxEngine session with Local conference – by making a call or by making StartScenarios request to HTTP API. To create the conference after the session start use the following code:

require(Modules.Conference);
var conf = VoxEngine.createConference();

The following example shows VoxEngine scenario where conference created after the session was started by call:

  1. require(Modules.Conference);
  2. var call, conf;
  3.  
  4. VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) {
  5. call = e.call;
  6. call.answer(); // answer on the call
  7. call.addEventListener(CallEvents.Connected, handleCallConnected);
  8. conf = VoxEngine.createConference(); // create conference
  9. });
  10.  
  11. function handleCallConnected(e) {
  12. // Connect media between call and conference (two-way audio)
  13. VoxEngine.sendMediaBetween(conf, e.call);
  14. /**
  15.   * If we want to send audio only in one direction
  16.   * conf.sendMediaTo(e.call); // from conference to the call
  17.   * e.call.sendMediaTo(conf); // from call to the conference
  18.   */
  19. }
  20.  
  21. // Make new call and connect it to the conference
  22. function addCallToConference() {
  23. var new_call = VoxEngine.callPSTN('somephonenumber');
  24. new_call.addEventListener(CallEvents.Connected, handleCallConnected);
  25. }
  26.  
  27. addCallToConference();

And another example where conference created after the session was started by HTTP request:

  1. require(Modules.Conference);
  2. var call1, call2, conf;
  3.  
  4. // We are assuming that session started with HTTP request
  5. VoxEngine.addEventListener(AppEvents.Started, function(e) {
  6. // create conference
  7. conf = VoxEngine.createConference();
  8. // call 2 phone numbers and join them to the conference
  9. // (you can make up to 10 calls for Local conference)
  10. call1 = VoxEngine.callPSTN('number1');
  11. call2 = VoxEngine.callPSTN('number2');
  12. call1.addEventListener(CallEvents.Connected, handleCallConnected);
  13. call2.addEventListener(CallEvents.Connected, handleCallConnected);
  14. });
  15.  
  16. function handleCallConnected(e) {
  17. // Connect media between call and conference (two-way audio)
  18. VoxEngine.sendMediaBetween(conf, e.call);
  19. }

Developers have full control of all calls in the conference. For example, if we need to mute one of the participants

call.stopMediaTo(conf);

or if we want to play some audio file to the participant

call.startPlayback("http://somewebservice/file.mp3");

If we need to play audio to all conference participants we will need something like that:

  1. require(Modules.Player);
  2. var player = VoxEngine.createURLPlayer("http://somewebservice/file.mp3");
  3. player.sendMediaTo(conf);
  4. player.addEventListener(PlayerEvents.PlaybackFinished, function(e) {
  5. // check e.error to see if something went wrong
  6. });

Of course, there is a way to record the conference (or particular calls):

  1. require(Modules.Recorder);
  2. var recorder = VoxEngine.createRecorder();
  3. conf.sendMediaTo(recorder);
  4. // you can stop recording using recorder.stop();

Let’s see how Standalone conference can be created. It can be done either by StartConference request to HTTP API, where you have to specify the name of the conference or by forwarding call to the conference using VoxEngine.callConference. In both cases the conference will be created in a new session (if the conference doesn’t exist) where all calls can be processed on VoxEngine scenario level. We will need to create two scenarios for the conference – Conference Gatekeeper (to forward calls to the conference) and Conference Manager (where inbound calls from the gatekeeper can be processed and connected to the conference, and where outbound calls can be initiated and connected to the conference). In addition to the scenarios we will need to create appropriate VoxImplant application rules that will be used to launch required scenarios.

Conference Gatekeeper example:

  1. // Handle incoming call from PSTN/SIP/SDK
  2. VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) {
  3. /**
  4.   * conferenceId will be used in the application rule to forward the call
  5.   * to Conference Manager scenario
  6.   */
  7. var conf_call = VoxEngine.callConference('conferenceId');
  8. VoxEngine.easyProcess(e.call, conf_call);
  9. });

It’s pretty straightforward – we just forward an incoming call to our conference. We will need to create special Rule in the application rules for that, where conferenceId will be specified in the Rule Pattern and Conference Manager scenario will be assigned.

Conference Manager scenario example:

  1. require(Modules.Conference);
  2. require(Modules.Player);
  3. var conf = null,
  4. calls = []; // calls array
  5.  
  6. // Handle incoming call from the gatekeeper
  7. VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
  8. // create conference if it hasn't been created yet
  9. if (conf == null) {
  10. conf = VoxEngine.createConference();
  11. }
  12. // we can store all calls in array to control them
  13. calls.push(e.call);
  14. e.call.answer();
  15. e.call.addEventListener(CallEvents.Connected, handleCallConnected);
  16. e.call.addEventListener(CallEvents.Disconnected, handleCallDisconnected);
  17. });
  18.  
  19. function handleCallConnected(e) {
  20. // Notify the conference about new participant
  21. var player = VoxEngine.createTTSPlayer("New participant has joined the conference.");
  22. player.sendMediaTo(conf);
  23. player.addEventListener(PlayerEvents.PlaybackFinished, function (ee) {
  24. // Start sending audio between the call and the conference
  25. VoxEngine.sendMediaBetween(e.call, conf);
  26. });
  27. }
  28.  
  29. function handleCallDisconnected(e) {
  30. // Let the conference know that one of the participants has left the conference
  31. var player = VoxEngine.createTTSPlayer("Participant has left the conference.");
  32. player.sendMediaTo(conf);
  33. }

That’s it. This scenarios can be modified according to developer needs. For example, to create and join outbound call to the conference remotely, we could use media_session_access_url and make a call to the existing conference session:

  1. VoxEngine.addEventListener(AppEvents.HttpRequest, function (e) {
  2. // we can pass number in the request path if required
  3. // var number = getNumberFromPath(e.path);
  4. var new_call = VoxEngine.callPSTN('number');
  5. new_call.addEventListener(CallEvents.Connected, function (ee) {
  6. VoxEngine.sendMediaBetween(ee.call, conf);
  7. });
  8. });

Adding different standard conferencing features is easy – write some JS code to add access code and passcode check, authorization by Caller ID, or web management interface. Check our GitHub page to get ready-to-use audio conferencing service scenarios and interfaces https://github.com/voximplant/conference

P.S. We will write about web-based conference client built using VoxImplant Web SDK in the near future. Stay tuned!

Comments