Sunday, September 13, 2015

Power of Web RTC - Simple example NodeJS + WebRTC

What is Web RTC ?


WebRTC is a free, open project that provides browsers and mobile applications with Real-Time
Communications (RTC) capabilities via simple APIs. The WebRTC components have been optimized to best serve this purpose.

As of 2014 December, WebRTC is still a new and untamed beast. As such, I found that there is a lack of simple and easy to understand examples for someone getting started with WebRTC. My goal was to create my own, as simple as possible, proof of concept WebRTC video conference page that achieved the following goals.

  1. Peer to peer data transfer with fair bandwidth to such as video chat.
  2. No external libraries needed. Only browser support for Web RTC.
  3. Works on many popular browsers now. (http://iswebrtcreadyyet.com/)

Before getting into the actual WebRTC APIs, it’s best to understand a simple signaling server. For those unaware, WebRTC requires that peers exchange information on how to connect to one another before the actual connection can be begin. However, this exact method is left up to the developer. It could be anything from a very complicated server to peers emailing one another. For my purpose, I chose to write a short and sweet Node.js server that communicates with clients via websockets.


Let’s take a look at the server. It uses the ws module which can installed with: npm install ws.




And that’s the whole server. For the finer details of the syntax it’s best to refer to the ws documentation, but let’s go over what’s going on here at a high level.

First we create a WebSocketServer on port 3434 (chosen completely arbitrarily) and then create a function that given a message will broadcast said message to all connected clients as such:



Lastly, whenever we recieve a message from a client, we simply broadcast the message to all other clients (including itself. And that’s all there is to it. Like I said, keeping it super simple.

Now for the client side (where things get more complicated unforunately). That said, rather than dumping a whole mess of code, let’s go through it piece by piece. It’s a good idea to reference the WebRTC documentation while reading. I’ve found that the MDN documentation is the most complete.

The HTML is short and sweet. Take note of the two video element’s IDs.


Now for the Javascript. First up, we create a few globals.


  • localVideo will refer to the video and audio stream from the local computer.
  • remoteVideo will refer to the video and audio stream from the remote computer.
  • peerConnection will be the WebRTC connection between the local and remote computers.
  • peerConnectionConfig is a dictionary of configuration options for the peerConnection object. In this case, we only specify the public STUN servers operated by Mozilla and Google. More on this later.

Because WebRTC is still new, many of the class names are prefixed. Many examples will use adapter.js which accounts for these prefixes. Given that there’s only one function and three classes we need for this example, I opted to not use adapter.js as it eliminates a dependency. That said:


With those at the top of the file, we don’t have to worry about those prefixes anymore.

Finally time for something fun! Next, we need to get our local video and audio stream. This is accomplished with the getUserMedia function. When the page is ready, we’ll call a function aptly named pageReady which will connect to our signaling server and request a stream from the user’s webcam and microphone.


Let’s talk about the getUserMedia callbacks first. On success, we assign the given video stream to the global localStream variable we created. Then we attach that stream to the localVideo video element. This will display the video stream from the webcam in the video element. Note that the local video element has the muted attribute set in the HTML. For local video we don’t want to output our local audio stream, otherwise this will cause echos and feedback. On error just log it to the console.


Note: If you plan to open a local file in Chrome you’ll need to start Chrome with the --allow-file-access-from-files flag in order to use the getUserMedia() call.

Now for the really fun part: WebRTC.

The way this demo is structured is that both participants load the page and then one clicks the Start button. The reason for this is that after clicking the button, we’re going to start firing off messages to the signaling server in order to connect to the other client. If the other client isn’t already connected to the server, these messages will never reach their destination. Of course, there are methods that allow for participants to “drop-in” to a WebRTC connection, but that’s more complicated so we’ll skip it here.

The first action we need to perform is to create an RTCPeerConnection object. RTCPeerConnection is the primary class used in WebRTC connections. For our purposes, we only have a single RTCPeerConnection since we’re only connecting to one other client.

Next, we’re going to assign some callback functions. So what’s an ICE candidate? An ICE candidate is essentially a description of how to connect to a client. In order for anyone to connect to us, we need to share our ICE candidates with the other client. Once an RTCPeerConnection object is created, it will start gathering ICE candidates. As you can imagine, it doesn’t take much time for the browser to determine how another client on the same LAN can connect to it, but determining how to traverse a NAT can take a little bit longer. Thus, we have an onicecandidate callback that will be called whenever the browser finds a new ICE candidate. At this point, we send the candidate to our signaling server so it can sent to the other client. A NULL candidate denotes that the browser is finished gathering candidates.

onaddstream is relatively straightforward. It will be called whenever we get a stream from the other client. This is excellent because it means that our connection succeeded! Upon getting a remote stream, we attach it to the remote video element.

Lastly, if we’re the caller (we clicked the start button), we create an offer which tells the other client how to interact with us once the network connection is established. This includes info about ourselves such as video and audio formats. The formal name for this called Session Description Protocol or SDP; hence the callback gotDescription. Once we have an offer (gotDescription was called), we set the local description to it and then send it to the signaling server to be sent to the other client.


We handled the client doing the calling, but what about the answering client?

Whenever we get a message from the server, we first check if the RTCPeerConnection object has been created yet. If not, call the start function, but not as the caller since we need to answer the incoming offer, not create a new offer.

Next we determine if the message is a description or an ICE candidate. If a description, we set it as the remote description on our RTCPeerConnection object and then create an answer. Note that we are sending the answer back through the signaling server. After all this work, we’re ready to let the browser directly connect to the other client.

If the message is an ICE candidate, all we need to do is add the candidate to the RTCPeerConnection object. If we have created an answer already, but haven’t successfully connected to the caller, the browser will continue trying candidates until a connection is made or it runs out of candidates.


At this point, we’ve set everything up so we let the WebRTC internals take over and if everything went well, the onaddstream callback will be called and we’ll get our remote stream. If you’ve been putting this together piece by piece, go ahead and fire it up. If you want a full example already ready to go, see below.

That’s the essentials of WebRTC. Of course, this was a very basic example, but it can be extended to allow for “drop-in” calls, a more sophisticated signaling server, handling multiple clients, and whatever other use you find for it.


Thursday, January 15, 2015

Useful and Lesser know Linux commands.


Linux command line is attractive and fascinating, and there exists a flock of Linux user who are
addictive to command Line. Linux command line can be funny and amusing. If you really get used to it and become expertise on it, you can control and almost anything in your Linux system. By referring this article, you use Google no longer to search for suitable Linux commands to complete a particular task.





Basics
cal - get calendar
date - get date
df - get disk space
free - get free space
cd - - changes working dir to previous
ll - list all including hidden files


File handling
ls
-a - list all
-t - sort by time
-s - sort by size
-r - reverse order
-d - details of current directory


file - determine files type
less - print file content
stat - print file statistics
touch - create a file
cp, mv, rm
cp dir1/* dir2 - copy all in dir1 to dir2
-i - interactive
-u - update
-v - verbose
-f - force
-r - recursive


Input Output
ln dir/file link
wc - print line, word, byte count
man
alias name=”command”
; - use to execute multiple commands at once
> - write to a file
>> - append to a file
less - show file content in editor
cat - print file content in std output
| - pipeline
sort - sort lines
unique - get unique lines


Cursor movements
ctrl + A - move to beginning
ctrl + E - move to end of the line
alt + F - one word forward
alt + B - one word backword
history -  see command history (history | grep )


file permission
id -  find out about identity
chmod - change mode
chown - change owner
chgrp - change group
chown
octal parameters - 755, 777
u, g, a, o - user types
r, w, x - operation type


Processes
ps - list snapshot of the processes
top - list updating table of processes
\ps x - show all processes
& - allows us to open a program without terminal instance
fg % - allows us to view job or program name and assign the terminal to it
kill <1> xlogo - kill a process
killall - kill all instances of a program
pstree - show process tree


Environment
printenv - print environment variables
set - shows env vars and functions
env vars
echo $USER - print username
~/.profile - this file should contain all the custom variables
source .bashrc - adding new changes done to the file to the terminal session


VI Editro
vi - open text file to edit
i - enter insert mode
esc - enter command mode
: - enter save mode
:wq - write and quit
:q! - quit without writing
h, j, k, l- move cursor left and right
x - delete character
dd - delete new line
o - get a new line and start writing
/ - search for a particular word
:$s/line/line/g -search and replace


Package Management
apt-get update
apt-cache search
apt-get install
dpkg --install - install/update from file
apt-get remove - remove a particular package
dpkg --list - listing installed package
dpkg --status - check package installed
apt-cache show - show more details about the package
dpkg --search - which package is responsible for the file name


Mounting and Unmounting
mount - show all the mounted media
df -h - shows storage details of disks in mb
fdisk - show details of disks and format them
sudo fdisk -l - show connected devices
umount - unmount from mount point


Networking
ping - send packet to particular host
tracerout
--ftp--
ftp - file transfer protocol
ftp - connect to file server
cd - change directory in file server
lcd - change directory in local server
get - download file to local directory


wget


--ssh--
ssh - connect to ssh host
scp - download a file
sudo lsof -i :5432 - port binded process


Searching for files
locate /etc/bin | grep data - locate all pathe matching the string
find -type f -name “*.png” -delete - find and delete matching files


Archiving files
gzip -tv - archive file in zip format
tar -xvf - archive file to a specific directory


Grep
grep -i ‘regexp’ - search file by ignorecase