I bought a camera yesterday. This is the camera I bought:
I bought it because I wanted something cheap to point-and-shoot amateur photos of fjords, on an upcoming trip to Norway. It's worth mentioning at this point that I'm really, really not a photographer. I just needed a thing which took better photos than my smartphone.
That being said, I do like exploring things. So one of the things I looked for in the camera was that I could use my phone as a remote control. Not for anything fancy, just to take photos or to start/stop videos recording.
As soon as I got the camera I tried it out, and honestly the Android app–PlayMemories Mobile–is a bit rubbish. It's got a nice live preview (shown below), but some of the settings are arbitrarily in menus. Also, I wanted to try shooting a timelapse, and it turns out Sony charges a whopping £7.99 for the privilege of installing a Time Lapse App. Nope.
Luckily Sony has a page just for people like me – the Camera Remote API! In a nutshell, a bunch of Sony cameras implement some or all of a big JSON-RPC API. Among the hundreds of things you can do, you can start video recording, stream the camera's output live to a video player, adjust all settings in manual mode, and take still images.
In the Development Guide, three steps are suggested to use the camera remote API:
- Download the Camera Remote API SDK
- Use SSDP to find the camera endpoint's URL
- Send JSON-RPC messages to the camera via HTTP POST messages
I skipped number 1 because I wanted to use Python, which wasn't supported. Plus, I figured I'd much rather test the remote API in Postman than learn to use a wrapper framework.
There's something strange here, though – the camera generates its own WiFi network, which the phone/laptop must connect to in order to control it. So... why the need to use SSDP to find the camera? Is the camera constantly changing how its own HTTP server works? Or changing its own IP address, despite hosting its own wireless access point?
As it turns out – no, the camera isn't changing anything. It's completely safe to just use the same URL endpoint: IP address and server path. So I skipped ahead to stage 3 to get some actual work done.
After playing around with the API in Postman for a bit, I worked out that the mode the camera was in mattered a huge amount – if the camera was in manual, for example, I'd be able to change things like shutter speed and exposure, but in automatic I couldn't do much more than change white balance and take the photo.
I also ended up having to install a slightly different "Play Memories" app on the camera – I thought the "embedded" version would have all the features, but it turns out installing the app-store version makes a few more commands available to the API. (Fair warning though, to use the app store on the camera involves typing a full email address and password pair with a tiny rotary dial – not my favourite way to spend several minutes).
The end result was a small timelapse utility, written in Python, which lets me put the camera on a tripod and set it taking photos at a given interval, for any length of time. I can even do it while it's plugged into a power bank, to make sure it doesn't run out of charge! The script downloads each photo taken into the current directory, so I made sure to create a new directory for each new timelapse.
To create a timelapse, I chained the frames together into an MP4 using ffmpeg, tweaked them in Premiere Pro with a slight tilt-shift and some saturation, then output from Premiere as a GIF.
Here's the command I used:
ffmpeg -framerate 24 -pattern_type glob -i '*.jpg' -c:v libx264 out.mp4
And here are two of the timelapses I started testing with:
As it turns out, I was much prouder with the still photos I took in Norway than the morning timelapses I tried – but this was a fun bit of programming which I'm sure will come in handy in the future!