VNC Recording: Hassle free video capture

amit bezalel
5 min readAug 27, 2017

--

Saving a screencast video is fairly simple on your own machine, but when required in a cloud solution, it becomes a hard and lengthy process: using encoders require you to understand and traverse a quagmire of licenses and royalty payments, dedicate CPU power to resource hungry encoding algorithms and build specialized software facilities to treat and deliver the videos, which in most cases will never be watched even once.

The Recording VncProxy

This is why I wrote the Recording VncProxy which is able to record & replay your VNC stream directly from a file.

For many solutions screen-cast video can be produced by a VNC server which may be watched by live clients. After thinking this trough it seemed to me that re-encoding this VNC stream to h.264 is extremely wasteful if all you wanted to do with it is allow it to be replayed online, since the VNC player is already there for live viewing. Plus if there were a good player for the new VNC file format, offering to download the screencast would also make sense.

VncProxy can record, replay and proxy VNC traffic. It is cross platform, and has support for most RFB encodings and pseudo encodings and can be used for session management and security over existing VNC setups. I have been working on it mostly on spare time, but it has already been tested with most popular VNC servers & clients.

For a desktop installable player, I maintained compatibility with the FBS format, so recorded files can be replayed with TightVnc’s RFB player, which is an opensource GPL Java project, but that player is very basic and might not be what you want to provide your users. (Any collaborators that want to create a better player, or refresh the existing one, are welcome)

Bitrate & Quality Comparison

H.264/5, divx etc. are highly compressed video formats that reside in most mkv/avi/mp4 files we use today, but creating them takes a ton of cpu power, and they are meant for real HighRes video with 30+ fps with bitrates that average around 0.5 to 2 Mega Byte per Second (see youtube docs), a VNC stream that uses the currently popular Tight or TightPng encodings is around 3 fps, and 0.3 to 0.5 MBps for most common resolutions. Given that the quality is fixed by the lower VNC fps, it looks like we are in the same ballpark in terms of size. Even if using video encoding with lower bitrates could provide a large saving in size, cloud storage space is much cheaper than CPU power and there are many even cheaper storage options for rarely used or archived information.

Previous solutions

Some work was already done in the field, a format for saving vnc streams to disk called FBS exists, there is a FBS player in the tightVnc site and an RFBProxy implementation that does just what i wanted, So easy!?, not so fast. Under deeper examination, I saw that RFBProxy is very old, unmaintained and doesn’t work with current formats (tight etc.), using the older uncompressed VNC formats is out of the question since cloud solutions tend to use these pesky bandwidth constricted internet channels…

Looking at the C code of the RFBProxy didn’t make me want to take it up and maintain it, and I was meaning to write some Golang code, so I started cooking something up, building on the existing go-vnc code (which is basic but well written) and referring to some good RFB documentation i found online, the end result along with code and architecture charts, can be found on github: VncProxy, it is completely OpenSource & MIT licensed.

Usage:

The release zip contains 3 Executables

  • proxy — the actual recording proxy, supports listening to tcp & ws ports and recording traffic to fbs files
  • recorder — connects to a vnc server as a client and records the screen
  • player — a toy player that will replay a given fbs file to all incoming connections

Recorder:

  • recDir: the directory in which to save recording files
  • targPass: a password to send to the target VNC when a conn is proxied
  • targPort: the target VNC port
  • targHost: a VNC server to proxy connections to, defaults to “localhost”
recorder -recDir “/Users/amitbet/vncRec/recording.rbs” -targPort 5903 -targPass “password”

Proxy

  • tcpPort: the vnc server listener port to open
  • wsPort: a websockified connection for web clients like noVnc
  • vncPass: the password of our newly created proxy server
  • recDir: the directory in which to save recording files
  • targPass: a password to send to the target VNC when a conn is proxied
  • targPort & targHost: an actual VNC server to proxy connections to
proxy -tcpPort 4444 -wsPort 5555 -vncPass "<password>" -recDir "/rec/dir" -targPort 5901 -targHost "localhost"

Player

player is just a simple server that replays one single recording file to all incoming connections, params:

  • tcpPort: the vnc server listener port to open
  • wsPort: a websockified connection for web clients like noVnc
  • fbsFile: the recording file to replay
player -tcpPort 4444 -wsPort 5555 -fbsFile "/rec/dir/file.fbs"

Future tasks and thoughts

I think there are several features that should be added in the future, like the ability to seek to different positions while replaying, which is important to most use-cases and would require to have an index of some sort, as well as adding some IFrames (non-incremental rfb requests) at known intervals. Another thing is having a good desktop player for such files, that includes all the usual player buttons. A convertor to conventional video format is also a possibility, and there is a way to get the VNC stream converted into a ppm stream that ffmpeg accepts over a pipe (see the rfbrecord npm), such an implementation would require a full VNC client which converts the RFB rects into bitmap which is currently not supported in my client code, but this can already be found in one of the other go-vnc forks.

Summary

VNC is already a video format of sorts, since it does send a moving picture stream to the other side, tapping into this is beneficial for screen casting since VNC is already very wide spread, cross OS, has an acceptable bitrate for long term storage, and its CPU consumption is extremely low while encoding.

I hope you find my project useful, if you like it, star it on github.

--

--

amit bezalel

After 17 years developing software, Coding is still a passion of mine, a hands-on SaaS cloud architect working in TS and GO & learning something new everyday.