Showing posts with label WebSockets. Show all posts
Showing posts with label WebSockets. Show all posts

Thursday, January 7, 2016

Platform Latency of WebSocket and WebRTC

These are some notes about latency in my tilt-and-pan system.

The tilt-and-pan WebRTC Streaming system (link) relies on an underlying Network Architecture (link) which makes it all work over the internet.

There are two main network elements:

  • WebSockets (routed from Pi through intermediate host to PC)
  • WebRTC (direct from Pi to PC)

Architecture

Excerpted from a prior post is this diagram of the network setup:

Basic Premise

When moving the Cardboard viewer, orientation data in the phone is sent via WebSockets to the Pi, which operates motors which control the direction of the camera.

The camera video is constantly being streamed back to the phone.

There is latency between the actual movement of the phone and the corresponding video image appearing to move.

Scenarios to Investigate

To narrow down where there is latency, I decided to take measurements in two deployments:

  • LAN
  • Internet


The LAN deployment runs the RDVP Server on the Pi, and all comms are local LAN.  The idea being to eliminate public internet uncertainty from measurements.

The Internet deployment is more "real-world" use case for future projects.

In all cases the Pi remains on the LAN.

A note about the LAN

During testing, it became clear that the LAN should be further split into wired and wireless.

That is, connections to the local LAN can be on Ethernet or WiFi.

Ethernet does not have to contest with wireless congestion.  WiFi does.

For the tests below, the Pi is always on Ethernet, and the Laptop is tested on both Ethernet and 2.4GHz WiFi.  And the WiFi is congested as a result of many apartments nearby.


A note about the Internet

The RDVP Server lives on the internet.  But not just anywhere.

My apartment is located in NJ.  The RDVP Server is running in Canada right near Montreal.

So traffic via the internet will have to travel approx 320 miles in each direction (as the crow flies).  This will likely be a fair amount longer in actual network links.

Areas to Investigate

Network Latency - Ping times and general RTT
WebSocket Latency - WebSocket messaging over given Networks
WebRTC Latency - Attempt to measure video latency over given Networks


For the WebSocket Latency, I am measuring the RTT from a message sent from my Laptop to the Pi and back again to the Laptop.


For the WebRTC Latency, I'm pointing the webcam at a high-res clock on the computer and then comparing the received video image to the clock.


LAN - Network Latency

Here I am pinging from the Laptop to the PI on the local LAN.


Pi Ethernet
Laptop Ethernet
sub-ms
Laptop WiFi (2.4GHz)
32ms

(highs in hundreds and high hundreds)

Internet - Network Latency

Here I am simply pinging the intermediate RDVP Server.  Cannot ping the Pi directly of course.



RDVP Server
Laptop Ethernet
22ms
Laptop WiFi (2.4GHz)
36ms



LAN - WebSocket Latency


Pi Ethernet
Laptop Ethernet
12ms
Laptop WiFi (2.4GHz)
14ms

Internet - WebSocket Latency


RDVP Server
Pi Ethernet
via RDVP
Laptop Ethernet
27ms
53ms
Laptop WiFi (2.4GHz)
38ms
65ms
Laptop LTE Phone Tether (cable)
65ms
99ms



LAN - WebRTC Latency


Pi Ethernet
Laptop Ethernet
516ms
527ms

Internet - WebRTC Latency


Pi Ethernet
Laptop LTE Phone Tether (cable)
466ms
430ms






Observations

Firstly, WiFi congestion has a pretty dramatic effect.  It makes for extremely erratic RTT on ping and WebSocket traffic, and hugely increases the average latency.

Otherwise, if you consider 1/2 RTT to be the time the Pi receives a command, then the following tables show the latency there isn't so bad.

LAN - WebSocket Comms


Ethernet
WiFi
RTT
12ms
14ms
½ RTT
6ms
7ms

Internet - WebSocket Comms

Ethernet
WiFi
Cellular
RTT
27ms
38ms
99ms
½ RTT
14ms
19ms
50ms


The rest of the visual latency is due to the WebRTC Stream.


Observations about WebRTC

In short, I think the framerate is part of the root problem.  The other part is possibly software (UV4L) queuing on the Pi side.

The video stream, when looking at Chrome's internal WebRTC monitoring system (chrome://webrtc-internals), shows many stats about the connection.

Here is one of the stats about frame rate over time.  It's very low.  I've been able to up this number with various tweaks to upwards of 10 frames/sec.  Not much higher.



At 10 frames/sec, the duration between each frame is 100ms.

That is still well short of the total visual latency of the approx 500ms latency seen. This could be software queuing, as it doesn't appear to be bandwidth limitations or CPU issues on the Laptop side.

A future release (link) of UV4L claims to vastly improve the framerate and nearly eliminate latency. It will be worth measuring again once that is released.


Sunday, December 13, 2015

Google Cardboard Controlling Raspberry Pi Streaming Tilt-and-Pan Streaming Video

Background

In a prior post (link), I demonstrated a setup which:

  • A Raspberry Pi streams WebRTC video to anywhere on the internet.
  • Can pan horizontally using an additional WebSocket control channel, controlled by a Chrome page which works on Desktop and Mobile.

I have extended that setup so that now:

  • I can both tilt and pan (X and Y axis, using a different WebSocket for each)
  • Uses a phone's orientation data to dictate the angle each axis should rotate to.
  • Exposes a fullscreen WebRTC video which still relays the orientation data.
  • Exposes a fullscreen Google Cardboard display mode which also still relays orientation data.

The basic network and communication setup didn't change, and and really only required an additional servo for the Y axis, as well as the incorporation of client-side javascript libraries.  The client in this case is Chrome for mobile (Android in my case).


Videos

External view:


Internal view:



Screenshots

Below I have a few pictures of the setup, some video of the setup in action, and an explanation of how I extended Client-side functionality.

My home-brew tilt-and-pan rig.  Just two servos control it, one for X, one for Y.


A close-up shot of the Y-axis servo.  Only the highest quality rubber bands and cardboard will do.



Here is a screenshot of the webpage control.  This happens to be on Desktop for screenshotting.
It's a prototyping page, and so a number of controls are exposed:

  • The top is some interactive controls to connect and disconnect my WebRTC, and the two WebSocket control channels.
  • The video below it is the WebRTC video stream applied to a <video> tag.
  • The "Camera Control" box below it lets me switch between manual servo control and Orientation Sensor mode.  Full-screen when touched.
  • The Cardboard View is another element (more on this later) which displays the split screen view required for viewing the video in Google Cardboard.  Full-screen when touched.



Here is the Cardboard View element full-screen on Chrome on my phone.  It's displaying the WebRTC video feed in a split-screen.
















And that view now in my Google Cardboard viewer (ViewMaster).


And a close-up of the Google Cardboard viewer once closed up and ready to look at.


Client-side functionality

There are a few client-side enhancements that needed to be made to make this possible:

  • Reading the Orientation Sensor data
  • Creating the Cardboard view


Reading the Orientation Sensor data

I had played with the Orientation API (link)  as seen around on the web in the past, but found it confusing.  Maybe I'm just not understanding it correctly.

The reason I found it confusing is because the Orientation API is returning Euler Angles (link), which don't directly give me the data I want.  And what it does give me I found difficult to turn into what I want.

What I really want is to get some readings which are more like what a person would intuitively think of as orientation.

That is, if I'm standing up, and I rotate in-place to the right, that could be expressed as a rotation in positive degrees.  Negative if I turn left.  Let's say that's the X axis.

If I look upward, or downward, that could also be expressed in terms of positive and negative degrees.  Let's say that's the Y axis.

In both cases, I have mapped the Orientation Sensor data to X and Y axis rotations to positive and negative degrees, ranging from 90 to -90 in either direction.  Useful since that's 180 degrees total, which is basically the range of a servo.

The software running on the Pi is a very simple program which expects to be told a number in the range 90 to -90, and map that to the appropriate PWM calls to move the servo to that location.

Getting the Orientation mapping to work was a challenging task for me and involved actually having to leverage some graphics libraries (Three.js) for some conversion away from Euler Angles (which are apparently used in graphics) and subsequently do some trig.  I'm probably doing it wrong.

Creating the Cardboard view

The Google Cardboard viewer requires a split-screen display with each image aligned to the center of the lens for each eye.

To accomplish this, I additionally use Three.js and its StereoEffect plugin.

The basic application in javascript is:

  • Create a Three scene
  • Create a Three renderer (WebGL)
  • Wrap the renderer in the StereoEffect effect
  • Create a HTML canvas element
  • Create a Three texture from the canvas
  • Create a 2d plane and apply a Three Mesh to it which has the canvas-backed texture mapped onto it
  • When animating
    • Get the current video frame from the WebRTC-backed <video> tag, and paint it onto the canvas.
    • Indicate to the Three texture that the canvas data has changed.

This leads to a split-screen render where there is a 2D plane which appears to be a video playing in front of each eye.


Final Notes

There are several areas which need to be improved about the whole setup.

Latency

There is a bit of delay (sub-second) in movement of the Cardboard viewer and the actual perceived movement of the image in the video.

This is going to be a combination of several factors, such as:

  • Pure network latency.  I'm in NJ, the Pi is in NJ, and I communicate to it via Montreal when using the Internet (as opposed to LAN-only).  That's a one-way 720 mile journey.
    • On the other hand, even on the LAN the latency isn't much better.
  • Latency on the Python program running on the Pi of actually processing messages and moving the servo.
  • Latency of the video streaming software (UV4L) pushing out new frames and subsequently being received and displayed on the browser.
I will investigate this in a future post.  Latency is not a concern in this prototype but it'd be nice to see where it's all coming from.


The actual tilt-and-pan rig

It's pretty make-shift at the moment.  A co-worker pointed me at a properly-built tilt-and-pan rig for less than $9 on Deal Extreme (link).  I put in an order and will wait to see how it works.

Not a huge priority actually but probably more stable.  Plus the rig comes with two servos so not bad.


Friday, December 4, 2015

Pi Internet-controlled Rotating and Streaming Video Prototype!

After lots of work, the prototype has been successfully operated in all desired configurations.

This post is a wrap-up of all that went into completing this milestone.

Premise

I wanted to see if I could make a remote control movable real-time video streamer out of the Pi, a Webcam, and a Servo.

Bonus points added if it works over the Internet with no onerous setup.
Bonus points added if I don't have to program anything to do with video encode/decode/transcode.

The gist of how I wanted to do it:
  • Get a Raspberry Pi
  • Put a Webcam on top of a Servo
  • Have the Pi operate the Webcam (USB)
  • Have the Pi operate the Servo (GPIO)
  • Run some Pi software which can read from the Webcam and stream via WebRTC
  • Write some Pi software to operate the Servo
  • Write some software to expose both the WebRTC and Servo control exposed on the internet
  • Write some software to make use of the two interfaces and combine them into a single interface

Defined so broadly, it's hard to see how this wouldn't work.  Challenges came from the details at each stage.

I will cover each point below in varying degrees of detail.


Get a Raspberry Pi

I went with a Raspberry Pi 2.  This turned out to be a good choice since the software for WebRTC only works for Raspberry Pi 2.

Also got a WiFi dongle.


Put a Webcam on top of a Servo

Ha, just use some twist-ties and rubber bands.



Have the Pi operate the Webcam (USB)

The statement is vague, but the basic meaning is to let the Linux distro support the details of interaction with the USB Webcam.

USB isn't a prerequisite per-se, but it's common and what I had on hand.

I happened to be using a Logitech QuickCam Pro 9000, which worked well for this purpose.

I'm not super familiar with Linux Kernel support for video devices, but I've come to understand there is a class of video devices which adhere to the UVC standard, which stands for "USB Video Class."



Anyway, plug that into the Pi and you'll see that it's recognized straight away.  Here is the /var/log/messages entry.

Dec  3 19:12:49 raspberrypi kernel: [348152.387472] usb 1-1.4: new high-speed USB device number 5 using dwc_otg
Dec  3 19:12:49 raspberrypi kernel: [348152.614881] usb 1-1.4: New USB device found, idVendor=046d, idProduct=0990
Dec  3 19:12:49 raspberrypi kernel: [348152.614907] usb 1-1.4: New USB device strings: Mfr=0, Product=0, SerialNumber=2
Dec  3 19:12:49 raspberrypi kernel: [348152.614925] usb 1-1.4: SerialNumber: 4BA96858
Dec  3 19:12:49 raspberrypi kernel: [348152.853207] media: Linux media interface: v0.10
Dec  3 19:12:49 raspberrypi kernel: [348152.881669] Linux video capture interface: v2.00
Dec  3 19:12:50 raspberrypi kernel: [348153.320477] usb 1-1.4: Warning! Unlikely big volume range (=3072), cval->res is probably wrong.
Dec  3 19:12:50 raspberrypi kernel: [348153.320512] usb 1-1.4: [5] FU [Mic Capture Volume] ch = 1, val = 4608/7680/1
Dec  3 19:12:50 raspberrypi kernel: [348153.321508] usbcore: registered new interface driver snd-usb-audio
Dec  3 19:12:50 raspberrypi kernel: [348153.327973] usbcore: registered new interface driver uvcvideo
Dec  3 19:12:50 raspberrypi kernel: [348153.328001] USB Video Class driver (1.1.1)

I hadn't known at the time, but my webcam shows up on the list of UVC supported devices which can be found here:  http://www.ideasonboard.org/uvc/


Have the Pi operate the Servo (GPIO)

There is so much written about how to make a servo move online it's not useful to re-write it here.

I did make a post about some issues I ran into early on since I'm an amateur regarding this kind of thing.  Post here: (link).

Basically, watch out for power and feedback issues.

Run some Pi software which can read from the Webcam and stream via WebRTC

This was actually one of the first things I researched when starting on this project.  I posted some thoughts on it at the time here (link).

All told, UV4L (Userspace Video 4 Linux) is what I went with, and some early successes in my work on this demonstrated it had a high likelihood of working in all desired configurations.

I cared a lot about this part since working with video is likely very difficult, and definitely something I don't know how to do.  Nor do I want to do it.

Most of the majorly-difficult issues are solved if there is something can do this task.

Specifically, UV4L solves the difficulties in:

  • Reading video from the webcam and doing anything whatsoever with it.
  • Encoding the video stream to something appropriate for the end-consumer.
  • NAT traversal.
  • Transmitting video while adapting to congestion, latency, buffering, etc.

The first point is the specific implementation relating to UV4L, which does support the UVC driver for webcams, thankfully.

The last three points are attributes of whatever can 'do' WebRTC, which UV4L can.


Notably, the UV4L process supports Signaling via websockets and JSON-formatted message passing.

However, due to the purposefully-undefined Signaling requirement for setting up WebRTC, I was forced to sniff out the specific message structures defined by UV4L.

In short, I hid the details of UV4L behind a translating proxy I wrote such that I could replace UV4L for something else if I want to later.  And other reasons related to the RDVP Server which I talk about later.

Also I wasn't 100% happy with the interface presented by UV4L anyway so bye bye to that also.


You can find lots of details about UV4L starting with the announcement about WebRTC support on their site (link).

Note that their site says only Raspberry Pi 2 is supported for now.  Perhaps this will change.




Write some Pi software to operate the Servo

I basically wrote a piece of software which accepts commands to move a servo.  And then it does it.

The software has no idea there is a webcam strapped to the top of the servo.

I had a post about this here: (link)



Write some software to expose both the WebRTC and Servo control exposed on the internet

From a prior post (link) I noted the high-level architecture of the overall setup I was aiming for.

It mostly discussed the function of what I called the Rendez-vous Point (RDVP) Server.

The RDVP Server is a central place where different services and clients can register themselves for the purpose of having a connection set up between them.

This satisfies most of the "control from the internet" requirement.  Since both the controller and controlee will "connect out" to a place on the internet, NAT issues are basically eliminated.

In the diagram below:
  • The left-hand-side is the Raspberry Pi.
  • The upper-right-hand-side is the RDVP Server, which needs to be anywhere accessible to both the Pi and the Controller.  If you want internet control, it had better be on the internet.
  • The lower-right-hand-side is the Client (controller).  It's a Browser in this diagram, but could be anything really.

The "translating proxy" I discussed in the UV4L section is labeled as the WSBridge, which also acts as a male-to-male proxy.

Meaning I can ensure it reaches out to the RDVP server to make itself known.  Once connected, it can relay messages back to UV4L for the purposes of setting up a WebRTC session.



Write some software to make use of the two interfaces and combine them into a single interface

As noted in a prior post (link), I chose WebSockets as the mechanism for communication between server-side processes.

I did this with the forethought that I'd ultimately have a Browser involved in the action, and browsers speak WebSockets well, so why not be uniform.

A security dimension of WebSockets on Browsers is that at the time of writing, Browsers only want to open WebSockets to the host which served up the page you're on.

So, that means the RDVP Server needs to also serve up a web site which contains the code to connect back to the RDVP Server to control the Servo and UV4L.

Not so hard.  In fact, the WebSockets library I used was Tornado for Python, which has lots of code already written for serving up webpages.

So, I wrote some simple HTML/Javascript to serve up from my RDVP server, changed the Server to serve it up, and pointed a Browser at it.


The moment of success

Pressing the 'connect' button leads to javascript connecting two WebSockets to the RDVP server.

Speaking RDVP language, they asked their messages to be relayed to the endpoints on the Pi servicing the UV4L and Servo controllers.

From there, the webpage sets up a WebRTC session with nearly no interaction from the user other than to accept that the camera is about to be used.  Once the remote video stream is acquired, it is dropped into a video tag on the page and the rest is handled by the Browser.

Additionally, the buttons 0, 10, 20, ..., 100 become active.  Click them, and a message is sent to the Servo controller indicating that it should move to that percent of its range-of-motion.

This is a screenshot from the laptop I was working at.





A few notes on network conditions relating to WebRTC and NATs

Key in getting video to stream properly is NAT traversal.  So I wanted to be sure that wherever the Pi was, I'd be able to run the Browser somewhere else.

The NAT traversal is handled by WebRTC libs I never have to touch, but can configure.  I instruct those libs to use the google STUN servers to identify both endpoints' locations for WebRTC handshaking.

TURN (TCP relaying of traffic) is never used.  It is always peer-to-peer by constraint.

With that said, I note that the moment-of-success was:
  • Run a RDVP Server on the Internet
  • Run the Pi in my apt on the LAN WiFi
  • Run my laptop tethered against my cell phone (so outside the network of both other systems)
  • Created a peer-to-peer (non TURN) WebRTC connection between the Pi and my external laptop.

I wanted to try several configurations for where the Pi and Browser were in relation to one another's networks.

Always keeping the RDVP Server on the internet, I have subsequently placed the Pi and Browser:
  • On the same LAN (in my apt)
  • Apt LAN and Internet (Browser tethered to cell phone, maybe no NATing going on)
  • Apt LAN to different LAN over the internet (so two computers in different LANs having to do NAT traversal)

Issues:

  • Framerate is slow.  I think it may be a combination of:
    • Congested 2.4GHz WiFi.
    • UV4L CPU utilization.
    • No attempt yet made to configure the Webcam to operate differently.
  • The servo jerks around a lot, I think due to the GPIO pins being software-based, and the PWM not hitting its timing targets.  Seems much worse than normal, I think it's being affected by UV4L.
    • I'd like to solve this with RPIO, but that's not supported for Raspberry Pi 2 (yet).  Perhaps another lib will work for the time being.
  • The webcam on top of the servo is not particularly stable and keeps tipping over!

Monday, November 30, 2015

Network Control Architecture

The first prototype of the Rendez-vous Point (RDVP) Server and Client was completed today.

This is a network communication scheme that aims to answer some of the basic questions that come up about communication between different devices.  Namely how do they find one another and communicate?

Objectives include:

  • Minimal or no configuration
  • Maximize discovery of services and capabilities
  • Common protocol
  • Easily extensible
  • Interface available to wide variety of devices
  • Agnostic as to whether operating on local network or internet

Some of the first uses intended include:
  • Discovery mechanism for purposes of WebRTC
  • Signalling mechanism for purposes of WebRTC
  • Remote control of Pi locally or over internet

The basic principles are:
  • There is a centralized server (the RDVP Server)
    • Everything connects to it
    • Password protected
    • Primary functions include:
      • Act as a transparent bridge between clients who want to communicate directly.
      • Allow Admin control
      • Present web interface
      • Enforce tightly-defined roles
  • Three tightly-defined roles for systems connecting in:
    • Admin Client
      • Speaks RDVP protocol (JSON over WebSockets)
      • Can monitor and control activities and state of Server
      • Likely spawned from web interface, but also possibly from other system such as those implemented in Python in the first prototype client.
    • Server Client
      • States ID and waits for messages to be sent to it, which it will respond to as-appropriate.
      • No messages will be sent to the Server Client unless a Client Client indicates a desire to connect to it, and the RDVP Server bridges them.
    • Client Client
      • States ID and intended Server Client to connect to.
      • Connection to Server Client will immediately be bridged or this client will be rejected and closed.

The expected use of the above is:
  • Server Clients might be anything "dumb" (like a Pi program) which is waiting to be controlled but doesn't know by who.  Simply announce itself and wait.  This also makes internet communication and control possible since the RDVP Server can easily live on the internet.
  • Client Clients are expected to be initiated from more knowledgeable control mechanisms.  This might be from a web interface, or other purpose-built mechanism.
  • Admin Clients are meant for systems which want to discover Server Clients to connect to, or otherwise observe state.
Having a central server which brokers communication also allows for snooping of communication as well as control over systems connecting in.

Future projects should be able to make use of this scheme as well.


A very specific first-use-case will be attempting to initiate WebRTC with the UV4L server.

This UV4L server is a bit opaque but does have a webserver which also responds to WebSocket connections leading to a WebRTC connection.

I don't want the webpage, I just want it to give up its video stream.  In the diagram which follows, there is a bridge between the UV4L server and the RDVP server.  This is essentially a male-to-male connection which itself is a bridge, making connection to the UV4L server possible remotely.


Here is a rough architecture diagram:


Monday, November 23, 2015

Network Servo Control Demo

Now that my WebSockets libraries are working better, I decided to try to use them in a program which can control a Servo.

To make the demo more interesting, I strapped a webcam to the top of the servo so I could use it like a DIY security cam.


The servo controlling software opens a WebSocket port to listen for incoming messages.  For now, the messages are simple -- A number, which represents the percent of range of motion of the servo.

So if you send 50, that means 50% of the range of motion, and the program will instruct the servo to move there.

To send messages to the servo controller, I use a super simple program written to bridge stdio to WebSocket connection, basically a WebSocket 'telnet'.  This is my wsEndpoint program.

Feeding into the wsEndpoint is stdio, but now controlled by a 'tk' gui program showing the numbers 1-100.  Click the number, it prints the number to stdout, which is relayed over the WebSocket connection, and the servo moves.

In the screenshot above you can see a washed-out square image on the screen, that is the grid of numbers.

The webcam in this demo is hooked up to my laptop, not the Pi.  No WebRTC involved here.

Sunday, November 22, 2015

Network Control of the Pi (WebSockets) 2

Some success with WebSockets, finally.

I shied away from using asyncio support for WebSockets for several reasons:

  • I don't know much Python programming and don't understand the examples
  • It seems to be a much lower-level implementation than I want (maybe mistaken)
  • I don't want to require Python 3.4, which is required for asyncio.  I want to be able to use Python 2.7 in the event that I get some less-capable or less-modern devices involved.
I tried several libraries, and in the end had difficulty getting them to work properly on Pi.

In the end I fell back to use Tornado libraries, which is among many things, lets you implement and use:
  • An event manager
  • WebServer libs
  • WebSocket client libs

With these I've been able to build a basic set of libraries which allow me to write very short Python programs which can:
  • Listen on arbitrary WebSocket addresses (eg ws://127.0.01:4000/).
  • Connect to any arbitrary WebSocket adddress.
  • Handle console input while doing any of the above.
  • Do all of the above via an Event Loop, no blocking required.

Difficulties came up understanding how various events fire in association with WebSocket connections working, etc, and how that fit into the interface I wanted to build.

An example being - What if your program tries to connect outbound (async) and wants to cancel the attempt before finding out whether it worked.  Not supported (from what I can tell).  I had to implement a wrapper to fake it.

Saturday, November 21, 2015

Network Control of the Pi (WebSockets)

I don't know what the specific architecture will be for control of the Pi over the network.

However, it does appear likely at the moment that:

  • Python will be involved
  • WebRTC will be involved (in some cases)
  • Browsers will be involved
This leads me to consider WebSockets, which is bi-directional message passing, supported by Browsers, and also now naively by Python and other languages.

Python is in scope due to it being the language of choice on the Pi, and is covered by a number of libraries which claim WebSocket support.

WebRTC is in scope due to the requirement for "Signalling," which is the discovery and transfer of media/network details.  This can easily be done over WebSockets, and is seemingly commonly done that way.

Browsers are in scope since any control systems put together would be much nicer with a point-and-click interface, and Browsers are perfect for this.

So, I have deiced to learn how to implement, in Python, some libraries which can act as the middleware between my Pi and the internet (probably a relay of some sort for WebRTC Signalling).

Also any process-to-process communication on the Pi can be done over WebSockets because why not.  Keep it all simple and hopefully make the testing easier as well.

Thursday, November 19, 2015

Video on the Pi, and over the Network (with WebRTC)

It'd be nice to have the Pi able to:

  • Operate a camera (webcam)
  • Relay the video over the network
Thinking about this, I'd like to do as little work as possible on the video.  I don't know much about encoding/decoding, but I do know it's CPU intensive (something I don't have much of on the Pi).

Therefore I'd like to do minimal work but be able to kick a video stream out over the network.

It made me think of WebRTC, a web-standard peer-to-peer media transfer mechanism.  Used in several places include Google Hangouts.  I didn't know much about it so I researched it.



In short, a WebRTC endpoint (like a web browser) will want to establish a peer-to-peer connection with another endpoint.  This entails:
  • Discovering another endpoint (not part of the standard, you implement this)
  • Exchanging details about media capabilities, and network / NAT details (details acquired by API, but still up to you to implement the transfer.
  • Attempt direct-connection (API handles this, but you need to provide STUN server details)
  • Javascript (or other language) then is provided with a stream of media content (like video) which can be directed to the screen (like a <video> tag 'src' attribute in a browser).

This seems promising on the Pi side if there is a non-browser implementation.  And there is.

Hunting around there appears to be several mentions of WebRTC and Python and Pi, including OpenWebRTC, and others.

However, the most successful path I could find online appeared to be message boards discussing the UV4L (Userspace Video 4 Linux) implementation of WebRTC and interface via a WebServer.


Another post will include detail on attempts to set up and use.


Resources about WebRTC:
  • WebRTC Demo (link)
  • WebRTC Tutorial - Infrastructure (link)
  • WebRTC Basics (link)

Resources about UV4L:
  • UV4L Announcement about supporting WebRTC (link)
  • UV4L Instructions on use (link)