Magnoliyan Video Chat PRO

Magnoliyan Video Chat

more video - more fun

Demos Download

Overview

Magnoliyan Video Chat PRO (mgVideoChat) is full featured video communication system with integrated text chat available directly within your web browser. You can consider it as online web based Skype, but without the requirement to install any additional software, plugin nor flash.

There is unlimited number of use cases: online live video chat support, private rooms, community chat rooms...

Compared to standard Video Chat, PRO version features: group (conference) video chat, file transfer, chat roulette mode

Unlike some other systems, Magnoliyan Video Chat PRO includes full featured server side "signaling" engine: you can see who is online, click to call, click to end call, send text messages. You can even mark certain users as operators which are able to receive calls while all others can just make calls.

There is special plugin system for authorization php classes but Magnoliyan Video Chat PRO comes with built in support for facebook login and wordpress accounts. It's even possible to use different authorization system per chat room.

Features

  • Pure HTML 5 RTC video chat system
  • Group (conference) video chat
  • Chat Roulette mode
  • PHP server side signaling system included
  • No additional software nor accounts needed
  • No DB needed
  • Mobile friendly responsive interface
  • Facebook authorization support
  • Wordpress authorization support
  • Extendable authorization system
  • Created with Bootstrap 3
  • Ability to define chat rooms
  • Ability to define callable operators
  • Desktop sharing2
  1. desktop sharing is available only for google chrome using an extension, over https, and in view-only mode

Requirements

This app uses the following Javascript libraries:

This app uses the following PHP library:

In order to run Magnoliyan Video Chat PRO server side you need:

  • https (ssl certificate). Since Chrome 47 getting a camera/mic access is allowed only over https. The server part of the system itself cannot run over https (wss for websockets), though there's possible 3rd party work-arounds described here. You should already make sure you will be able to apply one of them.
  • Dedicated or virtual server with *Nix platform
  • shell access on the server
  • PHP 5.3.9 (or higher) is required. PHP 5.4 is highly recommended for its performance improvements
  • Available port open on a firewall, for example 8080
  • Above average php5 and linux knowledge. You should be familiar with terms like linux shell, IP, domain, port, daemon, firewall to run this software.
  • Due to the direct media P2P communication limitations you might need to install and run your own TURN server. You can use this open source implementation here

In order to run Magnoliyan Video Chat PRO client side you need to:

  • host it on a domain (even local/private virtual domain can work for testing purposes)
  • for facebook authorization, create your own facebook login app pointing to that domain. Please read this tutorial for more information
  • newer modern browsers like Chrome or Firefox (excluding IE) which support HTML5 technologies: WebSocket, RTCPeerConnection, UserMedia
  • Average javascript knowledge. You should be familiar with browser's error console

Architecture

Deployment

Magnoliyan PHP chat server is websocket signaling central components. Magnoliayan jquery client script is HTML5 WebRTC app. Media (video/audio) communication is done directly (if possible) by the means of STUN servers. If direct traffic is not possible TURN servers are involved.

Quick Start Guide

Server side

Step 1: copy files

Copy source/server folder contents to your domain.

Step 2: install libraries

Login to your server using ssh (ssh tutorials), enter the copied folder and run

php ~/composer.phar install

If you don't have composer installed please read this tutorial for more information.

Step 3: run the server

php bin/chat-server.php

Please read more details about server configuration options in bin/config.php file

Client side

Step 1: copy files

Copy source/client folder contents to your domain's public folder.

Step 2: create html page

Create standard html which should contain at least a container element for the video chat, ex

<div id="mgVideoChat"></div>

Step 3: link file in a page

First we need to include files mgVideoChat depends on, and then mgVideoChat itself:

<!-- CSS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="mgVideoChat/mgVideoChat-1.14.0.css">

<!-- JS -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
<script src="mgVideoChat/mgVideoChat-1.14.0-min.js"></script>

Step 4: start mgVideoChat

All that is left is to initiate mgVideoChat plugin on the proper html element, when the document is ready:

$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.myserverdomain.com:8080?room=1' //domain:port and room id info
    });
});

Please read more details about client configuration options.

How to video

How to try

If you want to investigate if your existing hosting solution is capable of running chat server you can download this zip file.
It contains minimal version of both client and server part so that you can inspect if you will be able to deploy full featured Video Chat server on a hosting platform.

Here are short instructions how to use this tool:

  • Unpack and upload to your server
  • Make sure to update source/server/bin/config.php if you want to change server port - by default it runs on 8080
  • Start the server part of this tool using shell (recommender), ssh to your server and cd to source/server/bin. There execute php chat-server.php
  • After the server is up and running, navigate browser to index.html of this package
  • Enter domain and port where the started server is running and hit Test Connection and if all is fine you will get success message meaning that you will be able to run real chat server.

HTTPS, SSL, WSS

Since Chrome 47 a camera/mic access is allowed only over https. For that reason you will be forced to use HTTPS protocol only.
Further, if you use HTTPS for your website, browser will not allow any other non-secure communication. So websocket communication must be secure as well, it must use wss instead of ws protocol.

The server part of the system itself cannot run wss (ws over ssl) for websockets. But easy work-around is to enable proxy. There are a number of ways to do so. Depending on your server setup, one or another could be easier to configure.
Here are tutorials how to do so for ubuntu and centos

After you define proxy rule, it's important to include the same proxy path, e.g. /wss/ in wsURL parameter.

$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'wss://www.your_domain.com/wss/?room=1'
    });
});

Here we present three common proxy setups:

Apache proxy

If you are already using Apache, the easiest way might be to use it as a proxy. In order to achive this you can enable Apache's proxy_wstunnel.
For debian based systems run sudo a2enmod proxy_wstunnel.
For red hat based systems it should be enabled by default. Run httpd -M to check. If it's not enabled, create file /etc/httpd/conf.modules.d/00-proxy.conf with content:

# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so
LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

In your domain .conf file (the actual file might vary on different OS) you can add, usually next to where you ssl certificate is defined:

SSLProxyEngine On
ProxyPass /wss/ ws://www.your_domain.com:8080/

Make sure to reload/restart apache, debian sudo service apache2 reload, red hat sudo service httpd restart

Nginx proxy

Alternatively, for nginx things are similar, in the domain config you should add:

location /wss/ {
    proxy_pass http://www.your_domain.com:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;
}

Stunnel proxy

Alternatively, with stunnel configuration snippet should be something like this:

[websocket]
accept = www.your_domain.com:8443
connect = www.your_domain.com:8080

Server Management

Video chat PRO server part is not conventional php page, but service which should run all the time in the background. So it's not triggered by web request, executed, killed but instead runs in the background as a process (service, daemon). In order to run it you need to execute command from the linux shell. Not all web developers are comfortable working with shell. For those I suggest reading tutorials like http://www.siteground.com/tutorials/ssh/ or similar. Here are a few topics which can help managing Video Chat PRO server side process.

Basics

In order to run the process you have to enter folder source/server/bin. To start the process in there just type and hit enter:

php chat-server.php

Start/Stop script

In order to simplify starting and stopping of the process we provided run.sh shell script in the same folder. To start the process execute:

./run.sh start

to stop:

./run.sh stop

Run in the background

Usually you need to have the process running after you logout from the shell. Here's the command to help

nohup php chat-server.php &

Log the output

If you want to have log file here's the way

nohup php chat-server.php > app.log &

You might want to store more info with config option debug set as true

Get process ID

To check if th process is running and get its id (pid) execute:

ps aux | grep [c]hat-server

The number in the second column should be process id (pid).

Stop (kill) the process

After obtaining the process id you can execute

kill -9 pid

Where pid should be replaced with actual value.

Options

Client

jQuery plugin options array.

option description default possible values
wsURL Websocket URL to your server in format ws://domain:port?room=roomNumber ws://localhost:8080?room=1 string
debug Log messages to JS console false boolean
login function called on Login button - ex. custom popup, redirect to login page, etc. null function
tplMain URL to the main template relative to the running page /tpls/main.html string
tplConnections URL to the connections template relative to the running page /tpls/connections.html string
tplConnection URL to the single connection template relative to the running page /tpls/connection.html string
tplChat URL to the chat template relative to the running page /tpls/chat.html string
tplChatInput URL to the chat input box template relative to the running page /tpls/chat_input.html string
tplFile URL to the file progress template relative to the running page /tpls/file.html string
fileMaxSize Maximum size in bytes for a file to be transfered 512000 integer
sound.mp3 URL to the mp3 ring sound file relative to the running page /sounds/ring.mp3 string
sound.ogg URL to the ogg ring sound file relative to the running page /sounds/ring.ogg string
enableNotifications Enable desktop notifications when page is hidden true boolean
rtc Webrtc related options
For mediaConstraints check specs
For pcConfig check specs
For offerConstraints check specs
{
pcConfig:{
    iceServers:[
        {url: "stun:stun.l.google.com:19302"}
    ]
},
offerConstraints: {
    offerToReceiveAudio: 1,
    offerToReceiveVideo: 1
},
mediaConstraints: {
    audio: true,
    video: true
},
audio_receive_codec: "opus/48000"
}
object

Events

Attach custom event handler to an event:

$('#mgVideoChat').mgVideoChat('on','connections',function(connections){
    console.log('[mgVideoChat.connections]fired',connections);
});
event name description parameters
connections fired each time new connection (peer) is added or removed connections: Object
object with all connections objects as sub-keys
call_status fired each time a call status with a peer changes connectionId: int, status: string
statuses: idle, call_inviting, call_invited, call_accepting, call_accepted, sdp_offering, sdp_offered, sdp_answering, sdp_answered, call
chat_message fired each time a new text message received data: object
Object containing {connectionId: int, message: string}
logged fired when current user is logged in

Scripting

If you want to customize client side while reusing built-in functionality of jquery plugin you can leverage advanced javascript scripting api. Here are a few basic initial steps. For more details please inspect source code of mgVideoChat-1.14.0-min.js and its classes.

//global instaces of chat objects
var rtc, mgChat;

$(document).ready(function(){
    //init plugin
    mgChat = $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://' + wsDomain + ':' + wsPort + '?room=1'
    });
    //attach to plugin events
    //on call status change
    $('#mgVideoChat').mgVideoChat('on','call_status',function(connectionId, status){
        console.log('[mgVideoChat.call_status] fired',connectionId, status);
    });
    //on chat message
    $('#mgVideoChat').mgVideoChat('on','chat_message',function(data){
        console.log('[mgVideoChat.chat_message] fired', data);
    });
    //on logged in
    $('#mgVideoChat').mgVideoChat('on','logged',function(){
        console.log('[mgVideoChat.logged] fired');
    });                
    //get low level rtc object
    rtc = mgChat.getRtc();
    //attach to rtc object low level events
    rtc.on('chat_message', function(data) {
        console.log('[mgRtc.chat_message] fired', data);
    });

    $("#customSendMessage").click(function(){
        //log peer connections
        console.log(rtc.connections);
        var message = prompt("Enter message text", "Message");
        var connectionId = prompt("Enter destination connection id");
        if(message && connectionId){
            //use rtc object to send a message to a connection
            rtc.chatMessage(connectionId, message);
        }
    });

});

RTC object methods

method name description parameters
on attach event listener eventName: string,
callback: function

accept accept call connectionId: int,
opt: Object

invite initiate call connectionId: int,
opt: Object

busy send busy signal connectionId: int
drop drop call connectionId: int,
leaveConnection: bool,
leaveStream: bool

chatMessage send text message connectionId: int,
messageText: string

Server

PHP config.php options array.

option description default possible values
port Websocket server port 8080 integer
debug Echo debug messages to the output false boolean
allowedOrigins Array of domain names allowed to access your server. null allows all, but for production only your own domain should be allowed. null array
IpBlackList Array of black-listed IP addresses not allowed to connect to the server. null array
authAdapter Authorization adapter class name. Built-in classes are: MgRTC\Session\AuthSimple, MgRTC\Session\AuthFacebook2, MgRTC\Session\AuthWordpress
If custom authorization class is needed it can be easily developed. The class has to implement interface MgRTC\Session\AuthInterface and has to implement single function:
/**
 * @param ConnectionInterface $conn
 * @param array $cookies
 * @return array
 */
function authUser(ConnectionInterface $conn, array $cookies);
Built-in classes can serve as examples. Basically you should read $cookies to look for authorization info (sesson cookies). Also $conn->Config can be used to access global configuration settings if needed.
If an user is notg authorized function should return null. Otherwise, return array with user info:
return array(
    'provider'      => 'wordpress',
    'id'            => $userInfo->ID,
    'email'         => $userInfo->user_email,
    'name'          => $userInfo->display_name
);
It should contain at least: provider name, user id, email, display name.
MgRTC\
Session\
AuthSimple
string
friendlistAdapter Friend-list adapter class name. This class is in charge to answer if one user is able to call/see other.
For example, even when two users are connected in the same room your custom class could decide if they are able to see/chat with each other. The class has to implement interface MgRTC\Friendlist\CallableInterface and has to implement single function:
/**
 * If caller sees and can call callee
 * 
 * @param array $caller
 * @param array $callee
 * @return boolean
 */
function canCall(array $caller, array $callee);
Built-in CallableOperator can serve as example. Basically, based on users data you should be able to return true or false if one sees the other.
MgRTC\
Friendlist\
CallableOperator
string
operators Optionally here you can define array of user ids which are allowed to receive call, ex. technical support operators. Note that you can also define operators on a room level. null array
allowDuplicates Allow users with the same id to login from different locations at the same time true boolean
disableVideo Disable video calls (allow just audio) false boolean
disableAudio Disable audio calls (allow just video) false boolean
disableVideoNonOperator Disable video calls for non operators, eg. only operators will be prompted to share video false boolean
disableAudioNonOperator Disable audio calls for non operators, eg. only operators will be prompted to share audio false boolean
limit Maximum number of logged in user per room. Leave empty for unlimited. This option can be specified for particular room in room's configuration options. null integer
file Allow file transfer between peers. This option can be specified for particular room in room's configuration options. false boolean
group Activate conference or group mode for the chat. This option can be specified for particular room in room's configuration options. false boolean
roulette Activate chat roulette mode. This option can be specified for particular room in room's configuration options. false boolean
desktopShare Activate desktop sharing option (available only for chrome using an extension over https in view-only mode). This option can be specified for particular room in room's configuration options. false boolean
rooms Array of chat room numbers with defined custom authorization adapters per room:
array(
    1   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple'
    ),
    2   => array(
        'authAdapter'   => 'MgRTC\Session\AuthFacebook2'
    ),
    3   => array(
        'authAdapter'   => 'MgRTC\Session\AuthWordpress'
    ),
    4   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        'operators'     => array(11)
    ),
    'test%'   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        //...
    )
)
Room ID keys can even take pattern form, ex. 'test%' which means that all rooms which ID begins with test will have defined options.
null array
wordpress If MgRTC\Session\AuthWordpress active then this is required. Defines directory path to the wordpress installation:
array(
    'dir'           => '/path-to-wordpress'
)
null array
facebook If MgRTC\Session\AuthFacebook2 active then this is required. Defines facebook app information of a custom app on Facebook platform. Please read this tutorial about how to create custom facebook login app.
array(
    'appId'         => 'your-app-id',
    'secret'        => 'your-app-secret'
)
null array
simple If MgRTC\Session\AuthSimple active you can define here list of authorized members
array(
    'allowAnonim'   => true,
    'members'       => array(
        array('id' => 11, 'username' => 'operator1', 'password' => 'operator1', 'name'   => 'Tech Support')
    )
)
When allowAnonim is true no username/password is required to login
null array
routes array of http endpoints routes, eg.
array(
    [
        'path' => '/web',
        'server_class' => 'MgRTC\Web'
    ],
)
Read more here
[] array

Custom Authorization

If you need to implement custom login (authorization) mechanism, ex. in order to connect Video Chat to your custom CMS, you will need to develop custom authorization plugin and activate it in config.php authAdapter. All your class has to do is implement interface AuthInterface which has single method:

function authUser(ConnectionInterface $conn, array $cookies);

The function should inspect $cookies array and conclude if an user is logged in and if yes return array with user info:

return array(
    'provider'      => 'your cmsname',
    'id'            => 'user unique id',
    'email'         => 'user email',
    'name'          => 'user name'
);

If an user is not logged in, the function should return null

If you need to access settings from config.php you can do that via:

$conn->Config

As examples or templates you can use classes: AuthSimple, AuthFacebook2 or AuthWordpress

On the client side you can also customize login functionality. Take a look at login parameter in the client options. For example, if you customize this function you can integrate your own login dialog. Inside examples section, check Tech. support operator code for a custom login dialog example.

How to video

Read PHP Session

If you need to read php session from websocket server there are a few important things you need to understand.
First of all, the websocket server app is not standard php web script, but rather CLI app. Hence globals $_SESSION and $_COOKIES are not available. You should not read nor write those from the server script.
In order to read available cookies in function authUser there's $cookies array provided. If you need to get your php session, assuming that session cookie name is PHPSESSID you can get session id as:

$sessionId = $cookies['PHPSESSID'];
Then you should read session data, but since $_SESSION is not available, you must do that directly. If sessions are stored in a session file (this is default php setup), here's demo snippet to help:
function unserializeSession($session_data, $start_index = 0, &$dict = null) {
   isset($dict) or $dict = array();
   $name_end = strpos($session_data, '|', $start_index);
   if ($name_end !== FALSE) {
       $name = substr($session_data, $start_index, $name_end - $start_index);
       $rest = substr($session_data, $name_end + 1);
       $value = unserialize($rest);
       $dict[$name] = $value;
       return unserializeSession($session_data, $name_end + 1 + strlen(serialize($value)), $dict);
   }
   return $dict;
}

$sessionArr = unserializeSession(file_get_contents(session_save_path() . '/sess_' . $cookies['PHPSESSID']));
print_r($sessionArr);

Custom HTTP routes and endpoints

Sometimes you need to develop custom page or ajax/api endpoint which is to provide data from chat system internals. Eg. list available rooms, read current number of users per room etc.
One way could be to develop your own custom websocket message type, then in your custom html page make websocket connection and read and/or write messages of your new custom message types.
But sometimes this could be an overkill. An easier way might be to develop http endpoints inside chat server which could return html or json using standard http, thus can be access as standard web page or ajax call.

Firstly, you need to create and http endpoint php class, eg.

namespace MgRTC;

use Guzzle\Http\Message\RequestInterface;
use Guzzle\Http\Message\Response;
use Ratchet\ConnectionInterface;
use Ratchet\Http\HttpServerInterface;

class Web implements HttpServerInterface {

    /**
     *
     * @var Chat
     */
    protected $app;
    
    public function __construct(Chat $app)
    {
        $this->app = $app;
    }

    public function onOpen( ConnectionInterface $conn, RequestInterface $request = null )
    {
        $response = new Response( 200, ['Content-Type' => 'text/html; charset=utf-8'] );
        $clients = $this->app->getClients();
        $response->setBody("Hello!
We have " . count($clients[1]) . " clients in the room #1."); $conn->send($response); $conn->close(); } public function onClose(ConnectionInterface $conn){} public function onError(ConnectionInterface $conn, \Exception $e){} public function onMessage(ConnectionInterface $from, $msg){} }

Then, you need to update your config.php file to add new route, append:

    //...
    'routes' => [
        ['path' => '/web', 'server_class' => 'MgRTC\Web'],
    ],

Note that this page will be available at the port where websocket server works, not your web server pages:
http://www.your_domain.com:8080/web

This sample endpoint returns nothing more than dummy html content, but you could easily transform it into full-featured json api.
An important thing to learn from this example is how we can access and use underlying Chat app object inside as property $this->app.

Media Issues

If you are having problems with audio and/or video between some peers, the problem is probably related to NATs/firewalls in between. Webrtc leverages technology STUN/TURN to help peers find the shortest path for media channel. While STUN servers enable direct p2p communication, TURN is there to help even if that fails and it's included in media traffic. Longer initialization snippet of jquery plugin can solve the problem since it involves more STUN/TURN options:

$('#mgVideoChat').mgVideoChat({
    wsURL: 'ws://yourdomain:your_port?room=your_room',
    rtc: {
        // Holds the STUN server to use for PeerConnections.
        pcConfig: {
            iceServers: [
                {"url": "stun:stun.l.google.com:19302"},
                {"url": "stun:stun.anyfirewall.com:3478"},
                {
                    url: 'turn:turn.bistri.com:80',
                    credential: 'homeo',
                    username: 'homeo'
                },
                {
                    url: 'turn:turn.anyfirewall.com:443?transport=tcp',
                    credential: 'webrtc',
                    username: 'webrtc'
                }
            ]
        },
        mediaConstraints: {"audio": true, "video": true}
    }
});

basically just add rtc options to your existing setup.

For hosted turn servers please check https://xirsys.com/ or similar

If needed you can run your own STUN/TURN servers, just go for this open-source project and check this description

Installing COTURN server

coturn is open-source TURN/STUN solution available at https://github.com/coturn/coturn. We recommend installing and running this server as explained here.

For authorization we recommend using configuration options use-auth-secret, static-auth-secret, realm.
In our source code you can find implementation for Turn REST API in folder source/turn-rest-api which can be used as temporary credentials provider.
Please update config.php with relevant settings.

$ip = 'your server ip';
return array(
    'allowNoOrigin'         => true, //allow access when client does not provide origin header
    'secret'                => 'your_secret', //the same as "static-auth-secret" from /etc/turnserver.conf
    'users'                 => array('your_username'), //usernames
    'origins'               => array('http://www.yourserver.com', 'https://www.yourserver.com'), //allowed origins
    'uris'                  => array("turn:$ip:3478?transport=tcp", "turn:$ip:3478?transport=udp"), //turn/stun uris
    'ttl'                   => 86400 //time to live in secs for provided temporary credentials
);

The client side should first make ajax call to obtain list of TURN uris and then initiate Magnoliyan Chat Client.
This is general principal working with any TURN provider. Please take a look at provided example.

Examples

Simple Authorization

VIEW DEMO

This authorization is for demonstration purposes only. It should not be used in production. It features simple popup dialog which saves identity to a cookie which is read and validated by Simple authorization server side adapter.

<script src="mgVideoChat/mgVideoChat-1.14.0-min.js"></script>
<script>
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080?room=1'
    });
});
</script>

Facebook Authorization

VIEW DEMO

In order to provide facebook login you need to create facebook app related to your domain. Please read this tutorial about how to create custom facebook login app.
Obviously server side has to have MgRTC\Session\AuthFacebook2 enabled (check the warning below) in config.php file.
Make sure to update also facebook app parameters in config.php in facebook subkey.
Restart server script to apply updates.

<script src="mgVideoChat/mgVideoChat-1.14.0-min.js"></script>
<script>
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080?room=2',
        facebook: {
            appId      : 'your_app_id', // App ID - update this!
            channelUrl : '//magnoliyan.com/demos/facebook/channel.html', // Channel File
            status     : true, // check login status
            cookie     : true, // enable cookies to allow the server to access the session
            xfbml      : true  // parse XFBML
        }
    });
});
</script>

Wordpress Authorization

VIEW DEMO

For this demo we have standard wordpress installation with additional plugins:

  • User Access Manager used to protect page with video chat for members only
  • Raw HTML used to allow raw html/javascript in a page with video chat included

The following html/javascript code is activating the jquery plugin and connects video chat to a proper room defined with wordpress authorization class at the server side

<!--raw-->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="/video-chat-pro/source/client/mgVideoChat/mgVideoChat-1.14.0.css" rel="stylesheet" />

<div id="mgVideoChat"></div>

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript" src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
<!-- Video Chat -->
<script type="text/javascript" src="/video-chat-pro/source/client/mgVideoChat/mgVideoChat-1.14.0-min.js"></script>

<script type="text/javascript">
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080/video-chat-pro/source/client/demos/wordpress/?room=3'
    });
});
</script>
<!--/raw-->

Please check wsURL parameter. The part /video-chat-pro/source/client/demos/wordpress/ is path of our wp installation, so you will need to adopt it to your case. If your wp is installed directly in domain root, then just have /

How to video

Wordpress HTTPS

Unfortunatelly, only text chat will work over http, you will need to setup https installation. We still suggest making all work as http then upgrade to https.
Please read here general HTTPS instructions and then continue with the rest here specific for wordpress.

Unfortunatelly, things are even more complicated for WP. You will need to alter wsURL parameter to be something like:

wsURL: 'wss://www.magnoliyan.com/video-chat-pro/source/client/demos/wordpress/wss/?room=3'

Again, mind the path! It's your wp installation root url path with appended /wss/

Then in your apache's domain config file you need additional proxy rule (if you wp is installed in the domain directly then you don't need this additional rule):

ProxyPass /video-chat-pro/source/client/demos/wordpress/wss/ ws://www.magnoliyan.com:8080/
# in some apache versions have to use wss://

and reload or restart apache!

Private rooms

VIEW DEMO

This demo explains how you can create room numbers on the fly so nobody else but visitors could know the room number.

//get query string param
function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
    results = regex.exec(location.search);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
//update query strung parameter
function updateQueryStringParameter(uri, key, value) {
    var re = new RegExp("([?|&])" + key + "=.*?(&|$)", "i");
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";
    if (uri.match(re)) {
        return uri.replace(re, '$1' + key + "=" + value + '$2');
    }
    else {
        return uri + separator + key + "=" + value;
    }
}
//get random number
function getRandomInt (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

$(document).ready(function(){
    //read chat room
    var room = getParameterByName('room');
    //no private chat room?
    if(!room){
        //get one
        room = getRandomInt(1000, 100000);
        //redirect to chat room url
        window.location.href = updateQueryStringParameter(window.location.href,'room',room);
    }
    $('#privateUrl').text(window.location.href);
    //init video chat
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080?room=' + room
    });
});

Tech Support

This demo explains how you operators configuration option to make tech. support page where visitors do not have to login and operators have to provide user/pass.
Here operators should login from here
and using different browsers you can login other users from here

Here's operators page code:

<div class="container">
    <div class="page-header">
        <h1>Magnoliyan Video Chat <small>Tech Support</small></h1>
        <p>User operator1/operator1 for demo login</p>
    </div>
    <div id="mgVideoChat"></div>
</div>
<div id="operatorLoginDialog" class="modal fade" data-focus-on="input:first" style="display: none">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title">Login</h4>
            </div>
            <div class="modal-body">
                <label class="sr-only" for="userName">Username</label>
                <input id="userName" class="form-control" type="text" data-tabindex="1" placeholder="Username">
                <label class="sr-only" for="userName">Password</label>
                <input id="password" class="form-control" type="password" data-tabindex="2" placeholder="Password">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary login">Login</button>
            </div>
        </div>
    </div>
</div>
//set cookie via javascript
function setCookie( cookieName, cookieValue, days, domain){
    var domainString = domain ? ("; domain=" + domain) : '';
    document.cookie = cookieName + "=" + encodeURIComponent(cookieValue) + "; max-age=" + (60 * 60 * 24 * days) + "; path=/" + domainString;
};

$(document).ready(function(){
    //focus username in dialog
    $('#operatorLoginDialog').on('shown.bs.modal',function(){
        $('#operatorLoginDialog').find('#userName').focus();
    });
    //execute on login
    var onLogin = function(){
        if($('#operatorLoginDialog').find('#userName').val()){
            //set cookies for the server
            setCookie('mgVideoChatSimpleUser', $('#operatorLoginDialog').find('#userName').val(), 30, window.location.host);
            setCookie('mgVideoChatSimplePass', $('#operatorLoginDialog').find('#password').val(), 30, window.location.host);
            $('#operatorLoginDialog').modal('hide');
            //reload to use new cookies
            window.location.reload();
        }
    };
    //submit on enter key
    $('#operatorLoginDialog').find('#userName,#password').keypress(function(e){
        if (e.keyCode === 13) {
            onLogin();
            return false;
        }
    })
    $('#operatorLoginDialog').find('button.login').click(onLogin);
});

//init video chat
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080?room=4',
        login: function(callback){
            $('#operatorLoginDialog').modal('show');
        }
    });
});

Visitor's page is identical simple demo, just enters room 4.

And here's the server side relevant config:

'simple'            => array(
    'allowAnonim'   => true,
    'members'       => array(
        array('id' => 11, 'username' => 'operator1', 'password' => 'operator1', 'name'   => 'Tech Support')
    )
),
'rooms'             => array(
    4   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        'operators'     => array(11)
    )
)

Group chat

VIEW DEMO

This demo explains how you can activate group or conference mode for a room.
You should probably limit the number of user per chat room in this case since the network bandwidth per peer is limited and will not be able to handle too many video/audio connections.
This server side configuration snippet activates group mode:

'rooms'             => array(
    //...
    5   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        'group'         => true,
        'limit'         => 3
    )

and client side:

//init video chat
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080?room=5'
    });
});

Group private chat

VIEW DEMO

This example is special "combination" of private and group features from previous examples.
Room IDs are created on the fly and server side configuration defines options for room IDs which match defined pattern. This means that all dynamically generated ids which match room ID pattern will have these options This server side configuration snippet:

'rooms'             => array(
    //...
    'group_%'   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        'group'         => true,
        'limit'         => 3
    )
Note that pattern group_% will match all group ids beginning with group_.

Client side:

$(document).ready(function(){
    //read chat room
    var room = getParameterByName('room');
    //no private chat room?
    if(!room){
        //get one
        room = 'group_' + getRandomInt(1000, 100000);
        //redirect to chat room url
        window.location.href = updateQueryStringParameter(window.location.href,'room',room);
    }
    $('#privateUrl').text(window.location.href);
    //init video chat
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://' + wsDomain + ':' + wsPort + '?room=' + room
    });
});

Invite group/private chat

VIEW DEMO

This demo demonstrates scripting capabilites of mg jquery plugin.
There's independent button which an user can use to invite some of other connected visitors to join his group/private chat.
Group/private rooms share the same configuration as previous example.

But the main part is done on the client side. If query parameter room is not provided, we use default value 1 and we show regular chat.
Invate group triggers dialog which let you choose friends to join your private group chat.
They will receive link to the same page, but now with dynamically generated room parameter.

var rtc, mgChat, allFriends = [];

//render friends select options
function renderFriends(){
    $('#friends').html('');
    for (var connectionId in allFriends) {   
         $('#friends')
             .append($("<option></option>")
             .attr("value",connectionId)
             .text(allFriends[connectionId]['data']['userData']['name'])); 
    };
}

//get query string param
function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
    results = regex.exec(location.search);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

//update query strung parameter
function updateQueryStringParameter(uri, key, value) {
    var re = new RegExp("([?|&])" + key + "=.*?(&|$)", "i");
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";
    if (uri.match(re)) {
        return uri.replace(re, '$1' + key + "=" + value + '$2');
    }
    else {
        return uri + separator + key + "=" + value;
    }
}

function getInviteUrl(){
    return updateQueryStringParameter(window.location.href, 'room', generateRoomId());
}

//get random number
function getRandomInt (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}            

function generateRoomId(){
    return 'group_' + getRandomInt(1000, 100000);
}

$(document).ready(function(){

    //read chat room
    var room = getParameterByName('room');
    if(!room){
        room = '1';
    } else {
        $('#inviteDialogBtn').remove();
    }                
    //chat object itself
    mgChat = $('#mgVideoChat').mgVideoChat({
        wsURL: wsUrlDefault + '?room=' + room
    });

    //store connections in global variable
    $('#mgVideoChat').mgVideoChat('on','connections',function(connections){
        allFriends = connections;
        //console.log('connections event', allFriends);
    });

    //invite dialog
    $('#inviteDialogBtn').click(function(){
        renderFriends();
        $('#inviteDialog').modal('show');
    });

    //chosen plugin for multiselect
    $('#inviteDialog').on('shown.bs.modal', function () {
        //rebuild it on dialog popup
        $('#friends').chosen('destroy').chosen();
    });                               

    $('#inviteBtn').click(function(){
        var url = getInviteUrl();
        var message = $("#invitationText").val() + ' ' + url;
        if($('#friends').find(":selected").length == 0){
            swal({title:"Error", text: "You have to select a friend!", type: "error" });
            return;
        }
        $('#friends').find(":selected").each(function(){
            mgChat.getRtc().chatMessage($(this).attr('value'), message);
        });
        swal({
            title:"Invited",
            text: 'Your friends are invited to join you at ' + url + '',
            type: "success",
            html: true,
            showCancelButton: false,
            confirmButtonText: "Join them now",
            closeOnConfirm: true
        }, function(){
            window.open(url,'_blank');
        });
        $('#inviteDialog').modal('hide');
    });
});

Roulette chat

VIEW DEMO

This demo explains how you can activate roulette mode for a room.
In this mode peers randomly connect with each other by clicking NEXT button.
This server side configuration snippet activates roulette mode:

'rooms'             => array(
    //...
    6   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        'roulette'         => true
    )

and client side:

//init video chat
$('#mgVideoChat').mgVideoChat({
    wsURL: 'ws://www.magnoliyan.com:8080?room=6'
});

File transfer

VIEW DEMO

This demo explains how you can activate file transfer.
In this mode peers are able to send small files p2p if both sides use the same browser.
This server side configuration snippet activates file transfer:

'rooms'             => array(
    //...
    7   => array(
        'authAdapter'   => 'MgRTC\Session\AuthSimple',
        'file'         => true
    )

and client side:

//init video chat
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://www.magnoliyan.com:8080?room=7',
        fileMaxSize: 512000 //500KB max file size
    });
});

Events API

VIEW DEMO

This example demonstrates how to leverage mgVideoChat javascript events api to customize the interface.

The key is to attach custom event handler on existing mgVideoChat plugin:

$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'ws://' + wsDomain + ':' + wsPort + '?room=1'
    });
});
//on connections change
$('#mgVideoChat').mgVideoChat('on','connections',function(connections){
    console.log('[mgVideoChat.connections]fired',connections);
    if(!$.isEmptyObject(connections)){
        $("#supportWrapper .panel-title a").text("Support online");
    }else{
        $("#supportWrapper .panel-title a").text("Support offline");
    }
});

Please take a look at example's source code for more details.

Internationalization (I18N)

VIEW DEMO

This example demonstrates how to customize labels, messages etc. for wanted language.

All you have to do is update values of the key/value pairs in the global variable:

$.fn.mgVideoChat.translate = {    
    'Your browser does not support websocket.':  'Ihr Browser unterstützt keine WebSocket.',
    'Your browser does not support PeerConnections.':  'Ihr Browser unterstützt keine PeerConnections.',
    'Your browser does not support user media.':  'Ihr Browser unterstützt keine Benutzermedien.',
//...
}

You could do that inline, in the same file where you use mgVideoChat object, or in external script, but do it before the plugin is rendered.

All available translation keys you can find in the file

TURN server

VIEW DEMO

This example demonstrates how to integrate with third party SAAS provider https://xirsys.com in order to overcome media transport issue through NAT and firewalls.

Make sure to open account with xirsys.com first and obtain token key and setup your domains.

$(document).ready(function() {
    // This callback function will give us the iceServers:
    $.get("https://service.xirsys.com/ice",{
        ident: "your username",
        secret: "your secret token",
        domain: "your domain",
        application: "default",
        room: "default",
        secure: 1
    },
    function(data) {
        $('#mgVideoChat').mgVideoChat({
            wsURL: wsUrlDefault + '?room=1',
            rtc: {
                pcConfig: {
                    iceServers: data.d.iceServers
                },
                mediaConstraints: {"audio": true, "video": true}
            }                        
        });                    
    });
});

Please take a look at example's source code for more details.

Local TURN (coturn) server

VIEW DEMO

This example demonstrates how to integrate with your local coturn in order to overcome media transport issue through NAT and firewalls.

Please read first how to install and run coturn server.

// This callback function will give us the iceServers:
$.ajax({
    url: 'url_to_turn_rest_api/turn.php?username=defined_username',
    xhrFields: {
        withCredentials: false
    },
    success: function(data){
        console.log(data);
        //always add google's stun server
        var iceServers = [{'url':'stun:stun.l.google.com:19302'}];
        for(var i in data.uris){
            iceServers.push({
                'url': data.uris[i],
                'username': data.username,
                'credential': data.password
            });
        };
        console.log(iceServers);
        $('#mgVideoChat').mgVideoChat({
            wsURL: 'youWssUrl',
            rtc: {
                pcConfig: {
                    'iceServers': iceServers
                },
                mediaConstraints: {"audio": true, "video": true},
                audio_receive_codec: 'opus/48000'
            }                        
        });                        
    }
});

Please take a look at example's source code for more details.

Desktop sharing

VIEW DEMO

This example demonstrates ability to share your desktop with a peer. Desktop sharing comes with some limitations:

  • Sharing party must run Google Chrome
  • Sharing is available only via custom Google Chrome extension (source code included)
  • Sharing is allowed only via secure https
  • Sharing is available only in view-only mode
$(document).ready(function(){
    $('#mgVideoChat').mgVideoChat({
        wsURL: 'wss://' + wsDomain + '/wss/?room=1',
        chromeExtensionId: 'jfepeciommhoefhfacjdpcmnclekenag'
    });
});

Note that server must run over wss protocol. In order to achive this we enabled Apache's proxy_wstunnel. In our domain .conf we added:

SSLProxyEngine On
ProxyPass /wss/ ws://www.magnoliyan.com:8080/ #or wss://www.magnoliyan.com:8080/

It's important to include the same proxy path, e.g. /wss/ in wsURL parameter.

At the server since of our script we need to enable dekstop sharing for this room in config.php:

1   => array(
    //...
    'desktopShare'  => true
)

Google Chrome Extension

In order to make this work you will have to publish your custom branded Google Extension. A sharer is obliged to install this extension. The source code for the extension is provided at source/chrome-ext. You should update file manifest.json and icon.png with your custom info.
Make sure to update content_scripts/matches with a domain of your website where the script will be hosted.
After all is updated create zip file of all extension files and publish at Chrome WebStore Developer Dashboard. Learn more here.
Don't forget to update chromeExtensionId in javascript setup.

Please take a look at example's source code for more details.

FAQ

  1. I installed the script but I see just blank page?

    Please check if source paths to video chat .css and .js files are correct.

    Make sure you have in your html div or other element on which you attached plugin. Eg. demo scripts need <div id="mgVideoChat"></div>

    If the problem persits, please check your browser's error/debuger console (F12) and check if any errors present.
    Maybe you need to resolve some other conflicts or errors not directly related to mg video chat.

  2. All's installed as instructed, but I get Websocket closed, please try reloading page later?
    Please check if php websocket server is running properly. Login to shell console to the server and execute:
    ps aux | grep [c]hat-server
    
    If there's an output line, the script is running, if not please run the server.
  3. PHP Websocket server is running, but I still get Websocket closed, please try reloading page later?
    Please check if domain and port is correct in your javascript initialization?
    Also, you migth need to update firewall settings in order to make websocket server available.
    Check if port is not occupied, if you are already running a standard webserver on port 80 or 8080 you must choose some other port of video chat server.

    To check if websocket server is accessible and not blocked by firewall you can use online port scanners, ex. http://www.ipfingerprints.com/portscan.php Enter your domain or ip and port number (same start/end) and it should reply as open

    If the problem exists over https, first make sure all works regularly over http and then read here how to upgrade the system to https.
    Log, log, log, log ... make sure to inspect your webserver's access and error log files. Nothing speaks truth like log files!
  4. I cannot start the server or it stops as soon as I run it?
    Please if your hosting meets server requirements.
    Inspect your php CLI error log.
    Inspect server application log (the app output redirected to a file)
    php chat-server.php > app.log
    
    For more debug info you can enable debug mode in server's config.php.
  5. Cannot start the server using Webcommander.
    Webcommander is not supported any more, please install as required using shell and composer.
  6. When I start the websocket server I get syntax error?
    Your server probably has older php version installed which does not meet the requirements. Investigate your php cli version by running php -v
  7. I can run the server, but it shuts down after I log off or after some time?
    Basically, you should run websocket server in the background. Please check here how.
    Also, it might be good idea to run this service under supervision.
  8. How can I investigate if my hosting solution is good enough to run the server side?
    First of all, you cannot use shared hosting! You must be in full control of your server management.
    Make sure to read requirements and then you can try this tool.
  9. Text chat works but not audio and video?
    You are probably dealing with NAT/Firewall issues, you can try to update client side settings as described here
    It is estimated that 90% of webrtc traffic media is transferred as direct traffic. Unfortunately, in some cases it's not possible, there we need help of TURN servers and these are scarce.
    In a production environment you might need to pay for TURN cloud service (twillio, xirsys, etc.) or setup your own TURN and STUN server. Please read this section.

    In order to better understand, troubleshoot and debug media issues please read this great article.
  10. How can I use custom login mechanism to connect Video Chat to my own CMS?
    You will have to develop additional authorization plugin class as described here
  11. Why Video Chat does not provide registration feature?
    The purpose of Video chat is not to provide registrations - this would actually be a limitation, but to be able to integrate with any existing CMS, Forum, Social network which are in charge to support registration/login/auth.
    All you have to do then is write a small custom authentication code for your own custom membership system as described here
  12. I'm not able to login. After I submit login form, I still get Login button.
    In order for the client login mechanism to work with the server side, it needs to store a cookie which websocket server is able to read. For that reason, they must run on the same domain. So you must run your web page on the same domain as you run server side of this script (websocket server).
  13. When I run PHP Websocket server I get an error Could not bind to tcp://0.0.0.0:8080: Address already in use?
    Clearly, the port you defined is in use by some other service. You should either stop that service, or choose other port (free not blocked by firewall) and define it in config.php for your websocket php server and try to start the service again. Then update your client code to access WS service over that new port.
  14. How can I access PHP Websocket server from a browser to check if it works?
    Simply, you cannot and should not. PHP Websocket server is not a conventional php page, but rather a service (aka daemon), which you run once and it stays running in the background, similar like apache does. It cannot be accessed from a browser, but from websocket javascript client code like Video Chat jquery plugin.
    If you want to know if websocket is properly running, execute from command line ps aux | grep [c]hat-server.

    To check if websocket server is accessible and not blocked by firewall you can use online port scanners, ex. http://www.ipfingerprints.com/portscan.php Enter your domain or ip and port number (same start/end) and it should reply as open
  15. I bought some time ago Video Chat. I would like to buy the pro version. Can I upgrade the license or I should buy the pro version as a new product?
    Magnoliyan is CodeCanyon's exclusive author which means that CodeCanyon is the only one in charge for processing payments. We asked them if they support license upgrade and charging just price difference and here's the answer:
    We don't have any easy automated internal system process for item upgrades.
    However, we will work with buyers in special circumstances, like this, and work out an exchange.
    Thus, please contact CodeCanyon's support and we hope they'll be able to help.
  16. How many people can be on chat at one time?
    Probably it's impossible to answer with exact number. Though, there are a few of important facts to be aware.
    For media communication (video, audio) server is not a bottle neck (except for TURN server if needed) since peers communicate directly (P2P) not via server.
    On the other hand, server is in charge to do signaling communications and the number of logged in users in all chat rooms is not unlimited and depend on server's performance and resources. Again, it's hard to provide a formula, but the number should be measured in hundreds.
    Regarding conference sessions, once again, the server is not limiting issue, but end-user's bandwidth, and should not be expected to have more than a few peers per conference with fair quality.
  17. Does this work on mobile devices?
    Basically Magnoliyan Video Chat works on webrtc enabled browsers (Chrome and Firefox for now) independent of a device.
    Unfortunately, iOS devices are excluded even with Chrome running.
    Also in order to run it on a mobile device, descent hardware is required, so low-end devices are not recommended.
    We suggest you to test our demos from your android phone or tablet.
  18. How can I enable group feature in private chat rooms?
    Please check demo for both Group private chat.
  19. I get error Error getting local media stream: PermissionDeniedError or Could not connect stream with error

    This means that browser is not able to access your webcam or mic. There can be a few reasons for this:

    • The system must run over secure https connections, which implies secure wss for websocket communication. Please check here for more details.
    • Initially, there should be a confirmation dialog, but if you deny access to the camera you will get this error. Also, next time browser might automatically block access without asking. In Chrome you have to click on the camera icon right in the address bar and allow access.
    • Maybe other instance of the same or other browser is blocking access if accessing camera as well, so please close other instances.
    • Check if webcam drivers are working properly. Many windows webcams are not supported in Linux
  20. Is this system optimized for broadcasting, webinars or similar use cases involving high number of viewers?

    Unfortunately not. Webrtc technology is still not suited for many peers. Since it's a p2p setup, it means each peer has to connect to each and every other peer in the network which is not optimal for the throughput nor processing resources. Standard server centered architectures and better suited for this purpose.

  21. How can I set configuration options for private rooms?

    All configuration options defined at the top level in config.php array are applied to the dynamically created private rooms. If you still want to overwrite this you can define pattern based room names, e.g. 'test%' which are applied to any room which name starts with test. Please check server config options.

  22. Can you customize for me ...?

    Unfortunately not, we don't provide customization services.

  23. Can you install this for me?

    Unfortunately not, we don't provide installation services, but we can recommend.

  24. How can I customize ...?

    All needed documentation is provided at http://www.magnoliyan.com/video-chat-pro. By purchasing the scripts at codecanyon you get the full source code. It's fair to say that you should be advanced php developer to be able to customize server side of the system and advanced javascript developer for the client side. Examples included in the package can serve as a starting point.

  25. How can I record a video call?

    Unfortunately, you cannot. Webrtc is p2p communication, thus in general video/audio traffic flows directly and cannot be "caught" on server side for recording. Recording on a client side is not reliable, nor standardized.

  26. Can I run the system over HTTPS and how?

    Actually, you have to run the system over HTTPS since camera/mic access is disabled for insecure http connections.
    Please check here for more details.

  27. What is the price? What kind of licence do I get?

    We sell exclusively via envato's market Codecanyon. Thus the price, the terms and licenses are defined by them. You can check out price details on our page. And general licence policies here.

  28. The system does not work over HTTPS!?

    Please read carefully these instructions. Each word is important. In general you must setup reverse proxy from wss to chat service running on custom port.

    Please note that unlike non-secure WS version, with WSS the wsURL does NOT contain custom port. That is because proxy already maps default port to your custom port (eg. 8080).

    On some Apache's versions proxy rule should be wss instead of ws.

    Investigate apache's (or other webserver) error and access log. Logs are always way to go for any troubleshooting.

  29. It's not working, please help me!

    We guess you are developer as we are. How do you feel when your client asks this question?
    It describes your frustration, but does not describe your problem. There is so much more to do in order to describe the problem, and even help yourself.
    First of all, your are at the right place. Please read all these FAQ.
    Log, log, log ...log ... check your browser javascript console, check chat server log, apache error and access logs...for sure the answer is there.
    Then, if all these does not help, gather all info and send us...we're just developers, we can solve only described and explained problems.
    For media issues please read this article.

How to videos

Install over shell

How to install Magnoliyan Video Chat PRO over shell from windows

Integrate in Wordpress

How to integrate Magnoliyan Video Chat PRO in Wordpress, using simple stand-alone authorization or wordpress users