One of the apps we’re writing for our customer requires the ability to upload videos to Vimeo, so I got the chance to work with their web services APIs this weekend. There aren’t any publicly available Objective C classes for this, so I ended up rolling my own.
Unfortunately, this ended up being an exercise in the value of good documentation. Here’s what I found.
Vimeo uses OAuth, and I find that Google’s OAuth classes work fine for this.
The Upload Process
The real problem was in step 3: “Post the Video Files.” This step didn’t work, and I spent about 20 hours altogether, with considerable help from my friend and business partner George, trying to figure out what was going on.
Here’s what the Vimeo Upload API site currently has to say:
So, right off the bat, we have to do some special things around authentication. Okay, we’ll keep that in mind if anything goes wrong. This is a POST transaction, so the parameters probably need to go in the POST body.
So we try it, and get a response of “415 – media format not supported.”
The problem here is that it’s a guessing game: we have been given the rules but haven’t actually been given any clear guidelines about where the parameters are supposed to be and what format the video is supposed to be in (I’m talking about upload format, not video codec format).
Eventually we started using a multipart MIME format for the document, which got us past the 415 response code. The entirety of the new error message was:
Upload failed. try again!
No error code, no explanation. Nothing.
The biggest red flag, to my mind, was the signature. The API documentation had gone out of its way to emphasize the importance of getting the signature parameters right, so this is where we looked first.
After several hours we learned:
* A hell of a lot about OAuth signature generation
* A hell of a lot about Google’s OAuth code
* That GData OAuth only uses URL parameters for generating a signature. It does not look at the body at all.
Eventually I realized that there was too much ambiguity about where the service was expecting to find the parameters, so I downloaded Vimeo’s desktop uploader (an Adobe AIR app), and started looking at call traces with Wireshark. This was a lifesaver:
- The Vimeo app doesn’t sign its own uploads
- There was a missing parameter in the API documentation (“filename”).
Once I added the filename attribute the upload worked on the first try. I was able to verify that I could upload chunks with or without authenticating the upload chunk request before sending it.
The winning combination
So, what worked for us was to do a POST, as the document indicates, with the ticket_id and chunk_id as URL parameters, and with the FileName and file_data parameters as multipart form data, followed by the actual chunk data, with a content type of video/quicktime.
At first I thought of the Vimeo documentation as a few tantalizing clues to help you solve the uploading puzzle, but now I consider it to be openly malicious documentation. You would actually be better off without it because they withhold information critical to your success while simultaneously throwing a gigantic red herring at you.
I don’t know why Vimeo states that they require this step to be authenticated, nor why they have stated so explicitly how the signature has to be constructed for this particular call. Perhaps they had to relax the requirement internally and didn’t update their documentation. What I do know is that it steered me in a completely different direction than I needed to go in.
Likewise, the response messages from the upload server are almost criminally opaque. If a parameter is missing, it would be helpful to indicate that in the error message. Most of the other error and status messages Vimeo provides are detailed and articulate.
Finally, the omission of the Filename parameter itself from the API documentation, which is mandatory for the upload to succeed, sucked. In retrospect, this is a standard part of the Content-Disposition field and probably would have been included anyway if we’d started out on this with directions appropriate for doing a low-level implementation of the protocol.
In any case, if you are looking to do Vimeo uploading in native code, the bottom line is: use multipart-mime with a content disposition block for the actual binary data. Authentication for this particular call appears to be disabled, but could come back at any time. For now, if you’re having problems with uploading, it’s probably due to your message format and not your signature.