Streamie's Secret Sauce

 

Or the journey to stable RTSP streaming.

 

In the beginning…VLC

 

In the beginning I used VLC on my Mac to watch my four home security cameras. I wanted the cameras on my office TV, so I used the TV as a 2nd display on my Mac. The catch was that VLC doesn't support multiple streams, so I had VLC-1.app, VLC-2.app, VLC-3.app and VLC-4.app. This was not an ideal situation.

 

VLC on Mac

 

A better solution would have been an Apple TV app, but the year was 2015 and Apple wouldn't end up porting VideoToolbox until tvOS 10.2 some two years later, so I hobbled along with my four copies of VLC. Strangely, Apple doesn't even make mention of VideoToolbox in the release notes.

 

VLC Install Meme

 

CameraMan

 

As you might imagine, launching four copies of VLC and getting each running with the correct URL wasn't a great user experience. Enter CameraMan. CameraMan, my native macOS app, did not support ONVIF, H.265 or even audio (to begin with) -- but it did stream the video from my cameras, which came as an RTSP stream using H.264 encoding. It let you save snapshots. Drag and resize windows. Record 24/7 to your Mac. It served its purpose for many years.

 

CameraMan Config

 

Long after CameraMan lost its value as a live streaming app, I continued to use it as a 24/7 recording app, which my 2012 quad-core Mac Mini could do for 15 cameras using little more than 10% of the CPU. I still use this Mac Mini as a file server in 2022; it's a great machine.

 

CameraMan Streaming

 

Live555

 

But back to RTSP....

 

I did initially glance at the RTSP spec. It is always my inclination to roll a minimally acceptable implementation of a protocol instead of importing a 3rd party dependency. It was clear that it would not be a quick undertaking so I found myself looking at Live555. I didn't find the API particularly intuitive, but it worked, and it worked well for years.

 

CameraMan on MacBook Pro

 

FFmpeg

 

Until one day I upgraded the firmware on my four Hikvision home security cameras and everything started falling apart. Whenever I'd start a stream, it would just do nothing for about ten seconds, and then it'd start streaming correctly. The only change was the updated firmware and I couldn't find a solution in the Live555 source code and while a ten second initial pause wasn't a big deal for the office TV (which just ran the cameras 24/7), it was highly annoying for situations where I quickly wanted to take a look at a camera.

 

I had initially eliminated FFmpeg from consideration due to its heft. Live555 was a single-purpose library; FFmpeg, much less so. After some testing I verified that FFmpeg did not have that same, annoying 10-second pause when starting streams, and there was a lot more documentation and example code available. At this point it had been a couple of years and Apple had finally decided to get VideoToolbox running on the Apple TV. So with the transition from Live555 ===> FFmpeg for RTSP streaming I decided to roll an Apple TV app that could get these cameras on my office TV without using my Mac to drive it, and some months later I decided to get the app into the App Store so that maybe a little bit of income from the app would pay for my camera addiction, and Streamie v2.0.16 was introduced to the world (for tvOS); the iOS app followed a year later.

 

Streamie on Apple TV

 

Once the app was in the store though, the bug reports started coming in. Up to this point I had been primarily working with a single make and model of camera, and it was wired. This was basically the worst possible test case because it is highly stable and predictable. Streamie users on the other hand were also using cheap, Chinese wifi cameras with varying interpretations of what the RTSP spec really meant.

 

My camera collection continued to grow as I continued to try to trick FFmpeg into being stable in the face of unstable cameras. Eventually I ran out of tricks. If I started up a screen full of unstable wifi cameras, FFmpeg would simply crash in less than a minute. I wasn't even trying to keep streaming working at that point; I just didn't want the app to crash. The blame for the crashing could easily be considered the fault of the camera, but it just looked bad for the reputation of my app.

 

Streamie on Apple TV Cameras

 

FFmpeg had served faithfully from 2018 to 2021.

 

Krill

 

It was around this time that I had decided to take Streamie to the next level with full time development, and the most important facet of a video streaming app is to stream video reliably and stably. FFmpeg had to go. Krill is our home-rolled RTSP streamer and it was launched with Streamie v3.0.0 in April of 2021. It definitely made improvements over FFmpeg, but it was also new and there were _so many_ issues to work out as it reached broader use than my test bench. Eventually though, I could launch Streamie with a grid of unstable, cheap wifi cameras which would continue to fail for various reasons, but come the following morning, it'd all still be working fine, resolving errors, recovering corrupted streams, restarting decoders and on and on.

 

Camera Test Bench

 

Since that time we've added support for additional streaming protocols, codecs, home automation systems, file sharing and on and on, but reliable, predictable, stable streaming underlies all of that.

 

Streamie on Mac Studio

 

This is the secret sauce.

 

 

Related Topics

 

Blog General