Nearly three years ago, I posted about some fun I’d been having with VISCA using C#. As a reminder, VISCA is a camera control protocol, originally used over dedicated serial ports, but more recently over IP.
Until this week, all the cameras I’d worked with were very similar – PTZOptics, Minrray and ZowieTek all produce hardware which at least gives the impression of coming out of the same factory, with the same “base” firmware that’s then augmented by the specific company. I’ve seen differences in the past, but they’re largely similar in terms of VISCA implementation.
This week, my Obsbot Tail Air arrived. I’ve been looking at Obsbot for a while, attracted by the small form factor, reasonable price, and fun object tracking functionality. However, earlier models didn’t have the combination of the two features I was most interested: VISCA and NDI support. The Tail Air has both. I bought it in the hope that I could integrate it with my church A/V system (At Your Service) – allowing for auto-tracking and portability (as the Tail Air is battery powered and wireless).
The NDI integration worked flawlessly from the start. Admittedly the Tail Air takes a lot of bandwidth by default – I’ve turned the bitrate down to “low” in order to get to a reasonable level (which still looks great). But fundamentally it just worked.
VISCA was trickier – hence this blog post. First, there wasn’t documentation on whether it was using TCP or UDP, or which port it was listening on. To be clear, the product’s only just launched, and I’m sure the documentation will improve over time. Fortunately, there was information on the Facebook group, suggesting that other people had got some VISCA clients working with UDP port 52381.
To start with, that was going to cause a bit of a problem as my implementation only supported TCP. However, it was pretty easy to change it to support UDP; the code had already been written to isolate the transport from other aspects, at least to some extent. Fortunately, the PTZOptics camera supports both TCP and UDP, so it was easy to test the UDP implementation that way.
Unfortunately, the implementation that worked for my PTZOptics camera entirely failed for the Tail Air. After doing a bit of digging, I found out why.
It turns out that there are two variants of VISCA over IP – what I’ve called “raw” and “encapsulated”, but that’s definitely not official terminology. In the “raw” version, each message is between 3 and 16 bytes:
- The first byte designates the type of message, the source and destination devices, and normal/broadcast mode.
- There are 1-14 “payload” bytes
- The last byte is always 0xff (and no other byte ever should be)
The “encapsulated” version uses the same data part as the “raw” version, but with an additional header of 8 bytes:
- The first two bytes indicate the message “type” (command, inquiry, reply, device setting, control, control reply)
- The next two bytes indicate the length of the data to follow (even though it’s never more than 16 bytes…)
- The final four header bytes indicate a sequence number (initially 00 00 00 00, then 00 00 00 01 etc)
So for example, the raw command for “get power status” is 81-09-04-00-ff.
The encapsulated command for the same request (with a sequence number of 00-00-00-00) is 01-10-00-05-00-00-00-00-81-09-04-00-FF.
Once I’d figured that out (and hand-crafted the “get power status” packet to check that I was on the right lines), the rest was fairly straightforward. My VISCA library now allows the use of TCP or UDP, and raw or encapsulated format.
The Tail Air still doesn’t behave quite the same as my PTZOptics camera in terms of VISCA support, mind you:
- It ignores power standby/on commands.
- The “set pan/tilt” command ignores the specified tilt speed, using the pan speed for both pan and tilt.
- The “set pan/tilt” command replies that it’s completed immediately – instead of waiting until the camera has actually finished moving.
- The pan/tilt and zoom limits are (understandably) different.
Still, none of that should prevent fuller integration within At Your Service. I need to take account of the different pan/tilt/zoom limits within At Your Service, allowing them to be configurable, but after that I should have a reasonably workable system… as well as a handy little test camera to take for demo purposes!
All the code changes can be seen in the CameraControl directory of my demo code GitHub repo.
The Tail Air is not the only new toy I’ve received this week… I’ve also taken delivery of an Allen & Heath CQ20B digital mixer, so I’ve been playing with that today as well, trying to work out how to integrate that into DigiMixer. I’m really hoping to get a chance to write some more blog posts on DigiMixer over the Christmas holidays… watch this space.
There’s really no good documentation anywhere of even the basics of VISCA, is there?
Best I can find — for PTZOptics cameras possibly only, direct from them, so it doesn’t necessarily apply to any other cameras! — is command sheets that list “here are responses you can get” (but we won’t say precisely when they’ll be returned, what byte sequences of data they will pertain to, or to which commands they could be responses) and “here are the commands you can send” (but we won’t say what the response will look like unless it’s an inquiry, or any aspects of the timing of the response that should be considered part of the API [particularly relevant for VISCA over TCP] — like that Completion is only sent when a preset is fully recalled or canceled by another preset being recalled, or what mode has to be active for some commands to be supported).
And I’ve just found nothing about VISCA broadly: nothing even as basic as saying all commands are
[z0, …non-FF bytes…, FF]and responses are[8x, …non-FF bytes…, FF]and maybe there’s a length limit for each, to touch on things you mention here.I’ve been hacking away on the Bitfocus Companion module for PTZOptics cameras trying to improve them beyond just firing off byte sequences and ignoring the responses (including ones indicating syntax errors…and predictably one command was misimplemented such that it always triggered a syntax error). The absence of clarity means I’m sort of having to guess and assume that however my specific camera model behaves, generalizes to all PTZOptics cameras. (And I’m fairly sure some people are using non-PTZOptics cameras with the module, so who knows what effect changes will have on them.)
My previous world, web standards, could be unpleasant and vague — much more in the past, less so now. But it’s got nothing on VISCA for vagueness, as far as I can tell.
LikeLike
fyi, you can use nmap on windows to try to get what port something has open. you get the device and your computer on the same network, run `nmap <ip-address>` and it will try to connect to it over different ports to see which ones are open. by default it does the top 1000 ports, but you can do more with it with `nmap –top-ports 65535 <ip-address>`
hope this helps, i’ve definitely been there and it’s saved my bacon a couple times
LikeLike
Sony invented VISCA and all the Sony cameras that use VISCA have very comprehensive documentation on VISCA which can be downloaded from the Sony web site.
search for thi gs like the EVI-D30 (from the 1990s) or the EVI-D70
LikeLike