# ![Vidyo](http://www.vidyo.com/images/logo.png) 1. [Overview](#Overview) 2. [Getting Started](#GettingStarted) 3. [Concepts](#Concepts) 5. [Device Management](#DeviceManagement) 4. [Examples](#Examples) <a name="Overview"></a> ## Overview Vidyo's client library enables the developer to add real-time communication capabilities to their applications using a simple API that spans multiple platforms (Windows/Mac/Linux/iOS/Android) and languages (C/Objective-C/Java/JavaScript). <a name="GettingStarted"></a> ## Getting Started There are many possible ways to use the library depending on the application requirements. #### Desktop application Use the platform specific VidyoClient library (Windows/Mac/Linux) and interface using C/C# binding. #### Web Browser application with Plugin Use our NPAPI plugin and interface using our JavaScript binding (VidyoClient.js) #### Web Browser application without Plugin Use our Native Web-RTC version of VidyoClient.js and interface using our JavaScript binding. #### iOS application Use our iOS library and interface using Objective-C binding. #### Android Application Use our Android library and interface using Java binding. Once you load our library by adding it to your project or installing the NPAPI plugin, you can call VidyoClient funcitons. <a name="Concepts"></a> ## Concepts There is a hierarchy of object relationships in VidyoClient. **Endpoint** > **User** > **Room** > **Participant** It is a one-to-many relationship where multiple users can be instantiated on the endpoint and multiple rooms on the user. In order to create a **User** object, you need an existing **Endpoint** and to create a **Room** object you need a **User**. In addition to being referenced, these objects provide asynchronous responses through Feedbacks which need to be registered at the time of object creation. ```javascript /* JavaScript Example: */ /* When calling VidyoUserLogin, the response will come asynchronously through loginComplete feedback.*/ var vidyoEndpointFeedback = new vidyoClient.VidyoEndpointFeedback( { /* Endpoint feedbacks are not implemented for this sample */ }); var vidyoUserFeedback = new vidyoClient.VidyoUserFeedback( { loginComplete: function(vidyoUserFeedback, vidyoUser, result) { switch(result) { case("VIDYO_USERLOGINRESULT_OK"): /* Login complete */ break; default: break; } } /* Other User feedbacks not implemented for this sample */ }); var endpoint, user; /* assume initialization of vidyoClient */ endpoint = new vidyoClient.VidyoEndpoint({feedback:vidyoEndpointFeedback, consoleLogFilter: "", fileLogFilter: "", fileLogName: ""}); user = new vidyoClient.VidyoUser({endpoint: endpoint, feedback: vidyoUserFeedback}); user.Login({username: "exampleUser@example.com", password: "examplePassword", host: "example.com"}); ``` ### Initializing ```javascript /* JavaScript Example: */ /* Initialization */ /* add VidyoClient.js to the <Script> section of your page */ /* videoRenderingWindow is the div ID of the element where we will load the plugin and insert our video rendering window */ var vidyoClient = new VidyoClient("videoRenderingWindow", function(connectionStatus) { /* handle connection events */ switch(connectionStatus.status) { case("CONNECTED"): /* Connection to the client library is established through the transport such as PlugIn or WebRTC */ var version = vidyoClient.GetVersion(); break; case("INVALID"): /* Transport received invalid data from the client library. The instance should be reloaded. */ case("DISCONNECTED"): /* Connection has been broken after unsuccessful retries. The instance should be reloaded. */ case("RETRYING"): /* Connection has been interrupted, retrying */ } }); ``` > Languages other then JavaScript require ``VidyoClientInitialize()/VidyoClientUninitialize()`` instead of ``new VidyoClient()`` ### Endpoint Endpoint represents your physical machine. It handles Logging, Location Services, sources such as Cameras/Microphones/ and sinks such as Speakers/Renderers. See [Device Management](#DeviceManagement) section for more details on simple and advanced device management. ```javascript /* JavaScript Example: */ /* Creating a new endpoint object and listening for log feedbacks.*/ var vidyoEndpointFeedback = new vidyoClient.VidyoEndpointFeedback( { log: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLogRecord) { console.log(vidyoLogRecord.name + ": " + vidyoLogRecord.message); }, localCameraAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalCamera) { }, localCameraRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalCamera) { } /* Other Endpoint feedbacks not implemented for this sample */ }); var endpoint; /* Assume initialization of vidyoClient */ endpoint = new vidyoClient.VidyoEndpoint({feedback: vidyoEndpointFeedback, consoleLogFilter: "warning debug@VidyoClient", fileLogFilter: "info debug@VidyoClient", fileLogName: "/tmp/exampleLog.txt"}); endpoint.StartDeviceDetection(); endpoint.StartLocationDetection(); ``` ### User User represents a person with an account on the Vidyo system. It handles Login, Roster, User/Room Search and acts as a factory for finding or creating new Room objects. ```javascript /* JavaScript Example: */ /* Login and create a room. */ var vidyoUserFeedback = new vidyoClient.VidyoUserFeedback( { loginComplete: function(vidyoUserFeedback, vidyoUser, result) { switch(result) { case("VIDYO_USERLOGINRESULT_OK"): /* Login complete, create a new room */ user.CreateTopicRoom({name: "Example Room Name", description: "Room Description", feedback: vidyoRoomFeedback, createToken: "ANY STRING TOKEN"}); break; default: break; } }, loggedOut: function(vidyoUserFeedback, vidyoUser, result) { switch(result) { case("VIDYO_USERLOGOUTREASON_LoggedOut"): /* Logout complete */ break; default: break; } }, roomCreated: function(vidyoUserFeedback, vidyoUser, vidyoRoom, result, token) { switch(result) { case("VIDYO_USERROOMCREATERESULT_OK"): /* Room created, enter the room */ room = vidyoRoom; room.Enter(); break; default: break; } } /* Other User feedbacks not implemented for this sample */ }); var vidyoRoomFeedback = new vidyoClient.VidyoRoomFeedback( { /* Room feedbacks are not implemented for this sample */ }); var user, room; /* Assume initialization of vidyoClient and endpoint creation */ user = new vidyoClient.VidyoUser({endpoint: endpoint, feedback: vidyoUserFeedback}); user.Login({username: "exampleUser@example.com", password: "examplePassword", host: "example.com"}); ``` ### Room Room represents a conversation thread between users. It keeps a history of chat messages and media events as well roles, affiliations and other management properties. There are two types of room profiles at the moment, Conversation and Topic. * **Conversation** This is a restricted type of room where the list of owners is immutible and guest access is not possible. Most of the uses of this room would center around a casual conversation similar to SMS but with the ability to have more then two participants. For example: there can only be one Conversation room with Bob and Alice so that when the user.GetConversationRoom() API is called for [Bob, Alice] it always returns the same room. * **Topic** This is an room where participants are free to join/leave and the restrictions are implsed by the owner using the RoomProfile. It is usualy discoved through user.SearchRooms() API and can be joined once the Room ID is discovered. ```javascript /* JavaScript Example: */ /* Create Topic and Conversation Rooms. */ var vidyoUserFeedback = new vidyoClient.VidyoUserFeedback( { roomCreated: function(vidyoUserFeedback, vidyoUser, vidyoRoom, result, token) { switch(result) { case("VIDYO_USERROOMCREATERESULT_OK"): if (vidyoRoom.type == "VIDYO_ROOM_CONVERSATION") { /* Created room for Bob and Alice */ conversationRoom = vidyoRoom; } else if (vidyoRoom.type == "VIDYO_ROOM_TOPIC") { /* Created a new Topic room */ topicRoom = vidyoRoom; /* Invite alice */ topicRoom.Invite({userId: alice, message: "Hey, come to this room"}); /* Unlike conversation room, others can be invited to topic rooms */ } break; default: break; } }, roomSearchResults: function(vidyoUserFeedback, vidyoUser, searchText, result, roomInfo, numberOfRecords) { switch(result) { case("VIDYO_USERSEARCHRESULT_OK"): /* received search results */ firstSearchedRoom = roomInfo[0].id; break; default: break; } } /* Other User feedbacks not implemented for this sample */ }); var vidyoRoomFeedback = new vidyoClient.VidyoRoomFeedback( { /* Room feedbacks are not implemented for this sample */ }); var userBob, topicRoom, conversationRoom, firstSearchedRoom; var bob = "bob@example.com"; var alice = "alice@example.com"; /* Assume initialization of vidyoClient, endpoint and user creation */ /* Get a topic room for Bob and Alice. The user Bob has logged in and is represented by userBob */ userBob.GetConversationRoom({userIds: [alice], feedback: vidyoRoomFeedback, createToken: "CONVERSATION TOKEN"}); /* Alternatively to the Conversation room, we can create a new topic room and invite Alice */ userBob.CreateTopicRoom({name: "Example Room Name", description: "Room Description", feedback: vidyoRoomFeedback, createToken: "TOPIC TOKEN"}); /* Find an existing room, results will be in roomSearchResults feedback */ var startIndex = 0; var pageSize = 10; userBob.SearchRoomsWithName({searchText: "Example", index: startIndex, pageSize: pageSize}); ``` Once a valid room object is created, room history can be retrieved and management tasks performed. ```javascript /* JavaScript Example: */ /* Enter and manage a room. */ var vidyoRoomFeedback = new vidyoClient.VidyoRoomFeedback( { entered: function(vidyoRoomFeedback, vidyoRoom, result) { switch(result) { case("VIDYO_ROOMENTERRESULT_OK"): /* Room Entered */ /* Get 20 previous messages*/ room.GetHistory({numMessages: 20}); /* Send a message */ room.SendMessage({message: "Example Message"}); /* Start Audio/Video */ room.EnableMedia(); break; default: break; } }, exited: function(vidyoRoomFeedback, vidyoRoom, reason) { }, participantAdded: function(vidyoRoomFeedback, vidyoRoom, vidyoParticipant) { /* Notified for every participant in the room */ }, participantRemoved: function(vidyoRoomFeedback, vidyoRoom, vidyoParticipant) { /* Notified for every participant in the room */ }, messageReceived: function(vidyoRoomFeedback, vidyoRoom, vidyoParticipant, vidyoChatMessage) { /* Notified for every message received in the room */ }, getHistory: function(vidyoRoomFeedback, vidyoRoom, records, historySize, result) { /* result of room.GetHistory(); */ } /* Other Endpoint feedbacks not implemented for this sample */ }); /* Assume initialization of vidyoClient, endpoint, user and room creation */ /* Enter a room to participate in the conversation */ room.enter(); ``` ### Participant Participant represents the other users in the room. Once the room is entered, the participantAdded feedback will be triggered for every current participant in the room and every time a new participant enters. <a name="DeviceManagement"></a> ## Device Management There are two modes of managing the devices, Simple and Advanced. ### Simple This API on the Endpoint allows the devices be to easily selected. Once the device is selected, it will be used in every room when the media is started and no other API has to be called. ### Advanced This API allows fine grain control of devices through the concept of Source/Sink Type | Source | Sink ----- | ------------------------- | ------------ Audio | Microphone(local/remote) | Speaker (local/remote) Video | Camera (local/remote) <br/> WindowShare (local/remote) </br> Monitor (local) | Renderer (local/remote) Each Source can be added to and removed from the sync. This many to many relationship can create complicated layouts and interactions but requires a lot of state and logic in the application. ```javascript /* JavaScript Example: */ /* Advanced Device Management. */ /* Application needs to maintain state and make sure sinks such as vidyoLocalRenderer, etc are valid */ /* Sources such as (cameras, microphones) can be added to multiple local and remote sinks (renderers, speakers) to be displayed on many screens, rooms, speakers etc. */ var vidyoEndpointFeedback = new vidyoClient.VidyoEndpointFeedback( { localCameraAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalCamera) { /* To render a preview add to local renderer */ vidyoLocalCamera.AddToLocalRenderer(vidyoLocalRenderer); /* To select your camera and send it into the room, it has to be added to Remote renderer */ /* vidyoRemoteRenderer represents a sink in the VidyoRoom */ vidyoLocalCamera.AddToRemoteRenderer(vidyoRemoteRenderer); }, localCameraRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalCamera) { vidyoLocalCamera.RemoveFromLocalRenderer(vidyoLocalRenderer); vidyoLocalCamera.RemoveFromRemoteRenderer(vidyoRemoteRenderer); }, localCameraUpdated: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalCamera, state) { }, remoteCameraAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteCamera, vidyoUser, vidyoCall, vidyoRoom, vidyoParticipant) { /* This will be called when the remote participant adds the camera to the room */ /* To see the remote participant's camera it has to be added to local renderer */ vidyoRemoteCamera.AddToLocalRenderer(vidyoLocalRenderer); }, remoteCameraRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteCamera, vidyoUser, vidyoCall, vidyoRoom, vidyoParticipant) { vidyoRemoteCamera.RemoveFromLocalRenderer(vidyoLocalRenderer); }, localMicrophoneAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalMicrophone) { /* To select your microphone and send it into the room, it has to be added to Remote speaker */ /* vidyoRemoteSpeaker represents a sink in the VidyoRoom */ vidyoLocalMicrophone.AddToRemoteSpeaker(vidyoRemoteSpeaker); }, localMicrophoneRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalMicrophone) { vidyoLocalMicrophone.RemoveFromRemoteSpeaker(vidyoRemoteSpeaker); }, localMicrophoneUpdated: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalMicrophone, state) { }, remoteMicrophoneAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteMicrophone, vidyoUser, vidyoCall, vidyoRoom, vidyoParticipant) { /* This will be called when the remote participant adds the microphone to the room */ /* To see the remote participant's microphone it has to be added to local speaker */ vidyoRemoteMicrophone.AddToLocalSpeaker(vidyoLocalSpeaker); }, remoteMicrophoneRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteMicrophone, vidyoUser, vidyoCall, vidyoRoom, vidyoParticipant) { vidyoRemoteMicrophone.RemoveFromLocalSpeaker(vidyoLocalSpeaker); }, localSpeakerAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalSpeaker) { /* Application needs to keep track of the sinks to make sure they're valid when sources are added to them */ }, localSpeakerRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalSpeaker) { }, localSpeakerUpdated: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalSpeaker, state) { }, remoteSpeakerAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteSpeaker, vidyoUser, vidyoCall, vidyoRoom) { /* vidyoRemoteSpeaker represents a sink in the VidyoRoom */ }, remoteSpeakerRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteSpeaker, vidyoUser, vidyoCall, vidyoRoom) { }, localRendererAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalRenderer) { /* Application needs to keep track of the sinks to make sure they're valid when sources are added to them */ }, localRendererRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalRenderer) { }, remoteRendererAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteRenderer, vidyoUser, vidyoCall, vidyoRoom) { /* vidyoRemoteRenderer represents a sink in the VidyoRoom */ }, remoteRendererRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteRenderer, vidyoUser, vidyoCall, vidyoRoom) { }, localWindowShareAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalWindowShare) { /* To render a preview of the local window share it needs to be added to local renderer */ vidyoLocalWindowShare.AddToLocalRenderer(vidyoLocalRenderer); /* To share the window in the room it needs to be added to remote renderer */ /* vidyoRemoteRenderer represents a sink in the VidyoRoom */ vidyoLocalWindowShare.AddToRemoteRenderer(vidyoRemoteRenderer); }, localWindowShareRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalWindowShare) { vidyoLocalWindowShare.RemoveFromLocalRenderer(vidyoLocalRenderer); vidyoLocalWindowShare.RemoveFromRemoteRenderer(vidyoRemoteRenderer); }, localWindowShareUpdated: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalWindowShare, state) { }, remoteWindowShareAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteWindowShare, vidyoUser, vidyoCall, vidyoRoom, vidyoParticipant) { /* To render a remote window share it needs to be added to local renderer */ vidyoRemoteWindowShare.AddToLocalRenderer(vidyoLocalRenderer); }, remoteWindowShareRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoRemoteWindowShare, vidyoUser, vidyoCall, vidyoRoom, vidyoParticipant) { vidyoRemoteWindowShare.RemoveFromLocalRenderer(vidyoLocalRenderer); }, localMonitorAdded: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalMonitor) { /* Shares the entire monitor instead of a window */ }, localMonitorRemoved: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalMonitor) { }, localMonitorUpdated: function(vidyoEndpointFeedback, vidyoEndpoint, vidyoLocalMonitor, state) { } /* Other Endpoint feedbacks not implemented for this sample */ }); /* Assume initialization of vidyoClient and endpoint creation */ endpoint.StartDeviceDetection(); ``` <a name="Examples"></a> ## Examples ### Login -> Enter Room -> Start Media ```javascript /* JavaScript Example: */ /* Add VidyoClient.js to the <Script> section of your page */ /* videoRenderingWindow is the div ID of the element where we will load the plugin and insert our video rendering window */ var vidyoEndpointFeedback = new vidyoClient.VidyoEndpointFeedback( { }); var vidyoUserFeedback = new vidyoClient.VidyoUserFeedback( { loginComplete: function(vidyoUserFeedback, vidyoUser, result) { switch(result) { case("VIDYO_USERLOGINRESULT_OK"): /* Login complete, create a new room */ user = vidyoUser; user.CreateTopicRoom({name: "Test Room Name", description: "Room Description", feedback: vidyoRoomFeedback, createToken: "TEST TOKEN"}); break; default: break; } }, loggedOut: function(vidyoUserFeedback, vidyoUser, result) { switch(result) { case("VIDYO_USERLOGOUTREASON_LoggedOut"): /* Logout complete, end of demo */ break; default: break; } }, roomCreated: function(vidyoUserFeedback, vidyoUser, vidyoRoom, result, token) { switch(result) { case("VIDYO_USERROOMCREATERESULT_OK"): /* Room created, enter the room */ room = vidyoRoom; room.Enter(); break; default: break; } } }); var vidyoRoomFeedback = new vidyoClient.VidyoRoomFeedback( { entered: function(vidyoRoomFeedback, vidyoRoom, result) { switch(result) { case("VIDYO_ROOMENTERRESULT_OK"): /* Room Entered */ /* Send a test message */ room.SendMessage({message: "Test Message"}); /* Start Audio/Video */ room.EnableMedia(); /* Wait 5 sec and leave the call */ setTimeout(function () { room.DisableMedia(); room.Leave(); }, 5000); break; default: break; } }, exited: function(vidyoRoomFeedback, vidyoRoom, reason) { /* Room Left, logout */ user.Logout(); }, participantAdded: function(vidyoRoomFeedback, vidyoRoom, vidyoParticipant) { /* Notified for every participant in the room */ }, participantRemoved: function(vidyoRoomFeedback, vidyoRoom, vidyoParticipant) { /* Notified for every participant in the room */ }, messageReceived: function(vidyoRoomFeedback, vidyoRoom, vidyoParticipant, vidyoChatMessage) { /* Notified for every message received in the room */ } }); var endpoint, user, room; var vidyoClient = new VidyoClient("videoRenderingWindow"); endpoint = new vidyoClient.VidyoEndpoint({feedback:vidyoEndpointFeedback, consoleLogFilter: "warning", fileLogFilter: "info", fileLogName: "/tmp/exampleLog.txt"}); user = new vidyoClient.VidyoUser({endpoint: endpoint, feedback: vidyoUserFeedback}); user.Login({username: "exampleUser@example.com", password: "examplePassword", host: "example.com"}); ```