We’re excited to have launched last week a site for people around the world to speak directly to their ministers responsible for protecting the oceans. It’s live, and the ICS5 conference is happening right now.

Jess has written more about the tool’s purpose, but we also leveraged some interesting technical toys to make it happen. We’re excited to be able to keep using these with Greenpeace and beyond, and I wanted to share a bit more with you about what we learned and built upon.

It’s great to finally see web standards getting onto enough phones and computers that we can – carefully! – move to the cutting edge for the best experience of tools like this, without leaving people behind.

Recording without leaving the site

Only a few years ago this was just not reliable on enough browsers – but the web is accelerating! We give everybody, even on the oldest browsers, options to talk to their minister through a pre-recorded file upload. However on newer devices, the experience is way quicker for most people. We’ll detect if your browser records video and put that option first if it does, and show you a (nearly) live preview in a Canvas element if your browser supports that too. This was especially helpful in a previous version of the tool, where we played with drawing a bounding box on top of the recording to help people organise their recording frame for a slightly different use case.

Everything uses progressive enhancement via feature detection – no are-you-this-browser? hacks. So it should keep working for future campaigns with minimal work.

The key browser APIs here are MediaDevices.getUserMedia() – also involved in permission handling for most modern browsers – and ImageCapture. And we found that once we had feature detection right, these pretty much just worked. Two small caveats on the browser side:

  1. Encoding and container availability: before you make a plan for using video, you want to be reasonably clear what the browser is going to give you. MediaRecorder.isTypeSupported() is a must to include in your feature detection here, especially if you’re expecting a particular encoding. Some browsers just do WebM containers, some just MP4, and that’s before you even get into which ones will let you be picky about codec and which ones they can save. We’ll get into using what you captured in a moment.
  2. Nuxt server rendering: For projects like this we’ll often use Vue.js with Nuxt and let it server-render out the box. This gives us more flexible, search-friendly web apps and makes conventional URL routing an option, while keeping the power of a Single-Page App. But you have to remember that all your code has two places it runs: browsers and servers. The bit that was new to me here is simple once you know it: if you have a conditional template piece using v-if, in code that happens on the initial render of a page or component, chances are you’d be better off with v-show instead.

I’m on camera, now make me a star!

We have videos in browsers! Now how do we get them in front of powerful ocean policymakers? Twitter!

Twitter’s version 2 API is being pushed fairly heavily – and is also not finished yet. This caused us a few headaches. So the first gotcha here is around uploading media at all. As of August 2022 you will be forced to use v1 to get user media saved, and this means there is a very good chance that – contrary to most documentation’s advice – you are also better off using the old OAuth 1.0a token exchange for now. Frustrating but good to know!

The next is around media support. Gosh there are a lot of video flavours out there. Video codecs! Audio formats! Pixel sizes! Aspect ratios! Bit rates! Container formats that may or may not support all of these things!

I started trying to map all the different types of most-likely browser format to the quite narrow range of thing-in-MP4-container file types that Twitter permit via their API, even getting as far as building Node.js code to call a library someone’s made which swaps out the WebM container of certain video files for an MP4 container. This solved one browser record scenario we’d seen break. Then I considered all the other formats of video people might use that upload button for. And thought again.

Fortunately, we are far from the first team to hit this point. And there’s enough money in the requirement to convert unknown format video that Amazon have as-a-service-ified it with MediaConvert. (Or, more accurately, bought a company who had done so!) This made stable transcoding something we could add in about a day, including the work to securely keep temporary files on S3.

Now, if you have a video, you probably have a video that works.

What’s next?

We also used a little CloudFront header magic to detect where in the world you are, and Vue I18n to translate the tool. With our existing tech stack these are easy wins that give a much smoother translated experience wherever you are.

While things are mostly wrapped up for this campaign, we’re still thinking about how the tool in general and this localisation tech especially scales – and how we can adapt and improve it for the next global push for the planet.