Building a cross platform remote control for presentations
Tags: java, flutter, mobile
Published: 2022-06-27 17:19:49

If you are occasionally or even frequently presenting something using PowerPoint, Keynote, or a similar software, you may have a so-called wireless presenter, which is basically a specialized remote control for presentations.

![A wireless presenter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g67jg1ar1mxdkc7tpf4o.png)

Mine used to work flawlessly for many years, but recently it decided to break. While I could have just bought a new one, I though *Why not use an app instead*? There a quite a few available for both Android and iOS. Being a developer, I wanted to write my own, though. 

Actually, I had started one quite a few years ago. In late 2019 I wrote an article on Medium called [Don’t stop](https://medium.com/@tkuenneth/dont-stop-3f0465dcc05b), a very personal view about performing presentations. If you look at the cover image, you see a slide that reads *Souffleur - An open source cross platform remote control for presentations*. The idea of *Souffleur* was to...

- show speaker notes for the currently displayed slide, and to
- provide buttons to navigate through the presentation.

I started writing a tool that could extract speaker notes from PowerPoint slides, but it turned out it was too cumbersome to do in a cross platform way. Also - what about other presentation software? It would have been almost impossible to get speaker notes from all of them. While I could have asked the users to write the notes themselves, that just didn't feel right. 

...so the repository sat there and waited...

When my hardware remote control broke, I decided to remove the speaker notes part from *Souffleur* and focus on the core functionality by providing big friendly buttons to flip the slides.

![The Souffleur client written in Flutter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzvtxwqehwcyvvek4gn7.png)

We have only four buttons: *next*, *previous*, *first slide*, and *last slide*. While this doesn't sound much, my hardware remote control provided mostly the same, and that served me well for many years. *Souffleur* doesn't have a laser pointer, tough... 🤔 The app is written in Flutter. I will be telling more about this later. But first, let's focus on a crucial question: 

How does it flip slides? 

The presentation software runs on a Windows, macOS, or Linux machine. While in presentation mode, pressing certain keys navigates through the presentation. Simply put, hardware remote controls send key presses. How can apps, which run on a separate computer (the smartphone or tablet), achieve this? It turns out there are quite a few options. For example, the mobile device could simulate a Bluetooth mouse or keyboard. *Souffleur* follows a much more simplistic approach. The app relies on a companion software that is installed on the machine doing the presentation. That companion sends the key presses when it receives a corresponding command from the Flutter app. I call this companion the *Souffleur server*.

![The Souffleur server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/31cklp5fo6w7g8vuq335.png)

But how does it receive the commands? Here, too, I follow a simplistic approach: the companion is a specialized web server. The Flutter app sends commands by triggering certain urls. This works surprisingly well and stable. The only thing the user must make sure is that both computer and smartphone/tablet belong to the same network. At a conference venue this could be the wireless local area network provided by the organizer. If there is no wlan, the mobile device could become a wireless hotspot to which the presenting computer connects wirelessly. 

You are probably asking yourself how the Flutter app knows which url to use? The companion can show a QR code which needs to be scanned with the mobile device.

![Scanning a QR code with the connection url](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igbub5qvrqdt7ruvili7.png)
 
Once the url has been obtained, the app sends a *hello* message. When the companion receives it, the QR code popup is automatically closed. 

At this point you may be thinking: *If I know the ip address of the presenting computer, I can send commands, too, right?* 

When the companion is first started, it creates a random UUID and stores it locally. Only clients than know this UUID can build valid urls. If the UUID gets lost (on either the client or the server), the QR code can be scanned again.

This concludes the first part of this series. In the next installment, I will show you some code from the companion software. If you are curious to try *Souffleur* for yourself, feel free to clone the [GitHub repo](https://github.com/tkuenneth/souffleur). Please note: currently you can't get the client from the app stores, and there also isn't a ready to use installer. At least some of this may change soon.