Thousands Of Changes And No New Features - CueCam Beta 3.3

CueCam 3.3 is the biggest change to CueCam since its release. I’ve spent hundreds of hours reworking CueCam’s underlying architecture. I’ve deleted about 18,000 lines of code and removed multiple framework dependencies.
cuecam-3.3-diff.webp
I’ve built an entirely new rendering engine and changed the way everything is put together. But nothing should have actually changed.
Should?
Yes. Nothing should have changed, but some things probably have. It’s unavoidable with a rebuild like this. That’s where you come in.

Why has it changed?

I needed to be able to fix bugs like this:
bugs
There are loads of little problems like colour precision, compositing and animation synchronisation that were symptomatic of a piecemeal architecture that had accumulated over a long period of time.

Why was it like this?

The idea for CueCam Presenter emerged from several other projects: Shoot, Video Pencil, Beat Sheet, Video Pencil Camera, Easy VJ and more.
When I first added in-camera drawing Shoot Pro Webcam, I had a surge of interest from people who loved the concept and had ideas on how to take it further. I was hearing from school teachers, sports coaches, entrepreneurs and professionals, to veteran broadcasters pushing the latest technological developments.
Some people wanted more power.
Others just needed simplicity.
I’ve always started with the people who know their stuff - like how to manage an NDI feed, and how to use applications like Ecamm Live, mimoLive and OBS.
But I’ve always pushed towards solutions that are simple enough for anybody to pick up.
So when I released Video Pencil for iPad, which lets you draw on any camera source coming from any other device, I met the needs of video professionals first.
Then I released Video Pencil Camera, a macOS app that makes Video Pencil work with zero configuration (beyond a few macOS prompts that I could not control!).
This didn’t just mean an easier Video Pencil, it also meant a remote-controllable Video Pencil. Now I had a Mac app with a custom network connection to the iPad, I could start adding remote control features, like switching pens or clearing drawings using your Mac’s keyboard.
Meanwhile, other people were interested in a different Mac app I’d released called Beat Sheet. This allowed a sequence of cue cards to be created that would select different scenes in Ecamm Live or OBS in a linear sequence. That is, you could run a show without having to think about a million different stream deck buttons. People asked for teleprompter support. I added the ability to generate title graphics over NDI. I created an iOS teleprompter app for Beat Sheet that reused the networking functionality from Video Pencil and Video Pencil Camera.
I was adding more features for professionals, but the ecosystem felt pretty inaccessible to non-technical users.
And I kept having more ideas for Video Pencil camera - remote control, screen sharing, Aside 3D, an audio pipeline and more.
The apps were great if you understood how to set everything up, but as the capabilities evolved, I needed a way to bring everything together in a way that anybody could use.

Talking to users

I make a habit of talking to my users at every opportunity.
One day I found myself in a conversation with a guy from one of the big software companies. They were looking for an easy way to set up salespeople with presentation features that went beyond screen sharing or a vanilla webcam, but OBS was far too complex to explain, and impossible to share templates and content throughout an organisation.
That’s when it struck me:
“The crux of all this isn’t Shoot or Video Pencil, it’s Beat Sheet. I need to migrate the virtual camera from Video Pencil Camera. That way we don’t need this weird NDI feed from Beat Sheet. Documents and branding can be shared throughout an organisation. Secondary devices running Shoot and/or Video Pencil can be connected easily. And I can put everything under one license, and give bulk and education discounts, as well as running promotions that App Store distribution makes impossible. I already have the technology, I just need to put it together with a different user interface.”
This was when ChatGPT had just appeared, and I was blown away with how quickly I could throw up a new website for a new product.
CueCam Pre...
No.
Beat Sheet Cloud.
No.
Beat Sheet Studio
Well.
Anyway, I had the technology, but getting everything working well much more difficult than I expected.
Months passed as I poured all my energy into this project. Deadlines whooshed by, including one based on a relocation from London to Edinburgh and another based on the birth of my son.
I started by shipping something that would give good results to somebody who knows what they’re doing. But for this project to succeed, I needed it to be flawless.

Releases

CueCam 1.0 was the ‘it works if you know what you’re doing’ release.
1.0
CueCam 2.0 came a few months later, and was the first ‘this will actually help you understand what’s going on’ release.
2_live
2_deck
CueCam 3.0 came another year later and started to make things more ‘idiot-proof’, with a new graphic style that made it harder for people to produce ugly presentations, a simplified sharing interface and a more familiar presentation workflow.
share-bar-camera.png

recording.png
presentation-mode.png
CueCam 3.1 introduced live streaming support.
edit-stream
CueCam 3.2 introduced Slots.
slots
CueCam 3.3 will not have any major new features, but it will solve a lot of the problems that made previous versions sometimes confusing to use.

Challenges

ChatGPT was an incredible new tool when I started this project. It let me very quickly spin up a ‘mostly working’ version of a new feature. CueCam has been my first big post-LLM project, and I’ve learned a lot. AI tools are great for surfacing APIs and fleshing out code in unfamiliar languages, but they also make a lot of stuff up, and I don’t know if I’ve ever kept and code that was generated by a machine. It can pollute a codebase with unclear naming conventions and inefficient implementations, using much more code than necessary.
When it gets stuck, it has a tendency to either make up APIs (at which point I know to stop asking it for help) or it will wrap the same flawed core logic in increasingly complex layers of indirection.
The problem is that AI kept leading me into alleys with quick wins that instantly became technical debt, which needed dedicated time for me to understand and resolve properly.
For example: Support for Camera LUTs took me an hour, but it’s never had an “amount” slider.

Architectural issues

I can’t blame everything on The Robot though. I was using a lot of Apple frameworks for the first time, so my understanding lacked depth.
I chose SceneKit for the virtual camera renderer because I could set up a 3D environment in a visual editor and lean on certain image processing features and shader support.
I used Metal for compositing because I understood it was the most efficient way to approach graphics.
I used SwiftUI for slide layouts because it made it possible to have much more dynamic cards than if I’d been doing text layout myself.
Slide animations were created as follows:
SwiftUI renders the layout, tracking the frames of each element
ImageRenderer is used to create a texture
A Metal pipeline takes over, cropping, animating and compositing sections of the source image.
I offloaded all the virtual camera rendering to a global actor (”RenderActor”) to resolve memory safety issues when passing around buffers from different sources like cameras, screen shares or network connections.
I had to write C to implement the virtual mic. I went through three full rebuilds of the audio pipeline before version 1.0.
I learned a lot.

What I needed

I had a lot of problems with my architecture, from colour matching to animation glitches. I just couldn’t get it perfect, and no Apple framework solved all of my problems at once.
It felt like it was held together with string, and it was getting almost impossible to modify. Synchronising camera motion (SceneKit Actions) with a Metal shader running on a different thread was not only increasingly difficult to reason about, it was half-buried in some opaque Apple systems that they were in the process of getting rid of.
Even simple things like moving the picture-in-picture position had become fraught and error prone.
I waited for Apple’s 2025 developer conference just in case they had anything that would solve my problems, but I was resigned to the fact I needed to build a framework myself.
I wanted something with the declarative syntax of SwiftUI, optimised for video and audio rendering over a virtual mic and camera.
I wanted a simple source of truth for the state of my application at any moment in time, and I wanted a framework to be responsible for animations and transitions, just like SwiftUI.
I did some research, and after reading Chris Eidhof and Florian Kugler’s book “Thinking In SwiftUI” (a $40 purchase!) the prospect felt just demystified enough for me to attempt something similar.

RealtimeSwift

RealtimeSwift is my SwiftUI-style declarative audio/video framework that will power CueCam Presenter and my other applications from now on.
The virtual camera looks like this:

Arbitrary a/v sources can be registered and passed into the environment, so that regardless of whether something is an image, a movie file, a live camera or a Syphon feed, it can all be presented using the same code.
While I was working with Metal I found myself building abstractions like a “QuadRenderer”. I realised that Apple’s CoreImage framework is basically doing the same thing, but much better and with powerful visual debugging features that look like this:

Not to be outdone, I’ve built in some debugging tools of my own for RealtimeSwift, which look like this:

My other important realisation was that the virtual camera needs to be on the Main Thread, just like the user interface, not drifting about in the background. So RealtimeSwift runs on MainActor, allowing interactions and the user interface to be tightly locked to the output feed.
I was in the middle before. Now I’m on the right! (By the way, I don’t endorse IQ or “” as a concept, it just made me think of this meme.)
meme

Progress

I started by sharing a lot of progress reports on YouTube.
I made a lot of progress but then I started hitting the law of any project: the last 20% takes another 100% of the time.
I’ve had my head down. I’ve been getting through it, despite a toddler and some encroaching burnout.

Where am I up to?

I’m nearly ready to start beta testing. But I don’t want to dump something on you with a lot of avoidable bugs, so I’ll either be releasing the beta at the start of next week or early November after I’ve had a couple of weeks off. If it’s not clear, this has been an incredibly tough project and the long tail has been especially punishing (thanks largely to ChatGPT!).
Increasingly, however, I’ll get a glimpse of how it’s going to be.
And it’s incredibly exciting.
Buttery-smooth, interruptible transitions. Picture in picture that’s always in the right place. Crisp, efficient rendering. An incredible debugging experience. Something I can build on! Amazing features with hardly any code.
It’s hard not to fixate on what doesn’t work yet, but when I look at what does, I can’t wait to show it off.

How can you help?

If you know how to report a bug, you can be a huge help.
I have a form on the website that posts issues to the public Discord, which you can use to track any little details (or big features!) that don’t quite work.
Reach out to me at if you’re interested in getting this on your machine and doing some bug testing.

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.