cmd/vidforward: initial build of a video forwarding service to eventually enable persistent streams

Issue #378 resolved
Saxon Milton created an issue

We have concluded that we can probably increase public engagement through our live broadcasts if we can do persistent broadcasts. This will be beneficial in a couple of ways, firstly, the link for the broadcast will remain the same for long periods, secondly, having a persistent stream reportedly works better with the youtube algorithm. In practice, we’d have to stream a slate image over night while the video is down. This could contain messaging to say that we’ll be back, donation instructions and directions for seeing past streams.

To achieve this, we need an intermediary stage in our video streaming pipeline. Currently the pipeline is composed of just two components; the camera and youtube. Up until this point, the camera has acted not only as the video capture device, but also as the RTMP encoder i.e. the camera has sent video straight to youtube over RTMP. Unfortunately, at night, the entire camera is powered off, therefore no more transmission of video to youtube can be made. If we are to send a slate image in down time, we will need the RTMP encoder to be separate from the camera. We have therefore proposed that we have an additional component in the pipeline; a “video forwarding” stage. This stage would accept the video data as MPEG-TS over HTTP through recv requests (just like vidgrind) extract the h264 access units, and then write the data to a revid pipeline which can then encode into FLV over RTMP for youtube. When the video forwarding software is informed that the camera is to powered down, h264 frames representative of our slate image can be encoded instead.

Unfortunately, such a service cannot run on google appengine due to constraints re communication between GAP and other google services. The next best platform is google compute engine; initial investigations have shown that it’s easy to set up a virtual machine running ubuntu, install our revid software and send some video to youtube via RTMP (albeit with machine and data costs).

It’s proposed that an initial vidfoward implementation be written to run on GCE. This will manifest as a basic service that receives video from devices through a recv handler. At least initially, for ease of configuration, we’ll fuse this with netsender client functionality so that we can control via variables, with a plan to add another handler function for “control” requests through which vidgrind can communicate broadcasting configurations.

The primary control netsender variable will be “Actives”. This will contain a CSV list of key-value pairs. The pairs will be MACs of devices and the values will be RTMP destination URLs. According to this variable, the vidfoward software will manage a map containing a series of MAC:REVID pairs i.e. each MAC will have its own revid pipeline (configured with the corresponding RTMP URL).

The revid pipeline uses an input of type Device, which is an interface from revid/device, representative of an input device. We have implementations of this interface such as “Raspivid”, “File”, “GoeVision”, but nothing offers “manual” writing e.g. if we wish through software to write directly to the revid pipeline using discrete access units, we currently cannot. It’s therefore proposed that we write a new implementation of Device to allow this. We’ll also add a Write method to the Revid type such that it implements io.Writer; this will be how we write data to the pipeline. If the “ManualInput” device has not be configured, the write method will return an error. This implementation will use a pipe i.e. each write will block until all of the written data is read. This works well given that each write is a single access unit, therefore each whole read (if we provide a large enough buffer) corresponds to a whole access unit.

We’ll also need to provide a “no op” implementation of a lexer. This will need to perform some timing duties, given that frames will come in as MPEG-TS clips over HTTP every x seconds of interval. We could write a proportional controller to maintain a steady number of frames in a temporary buffer i.e. adjustment a delay between writes to the reset of the pipeline. This kind of mechanism should work for any framerate.

Vidforward Design Doc

Comments (2)

  1. Log in to comment