Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vimeo API : streaming upload using HTTP PUT and blueimp's jQuery fileupload

I'm trying to implement an upload module on a website which would allow our users to upload videos to our Vimeo account. I'm using blueimp's jQuery File upload and Vimeo's new API. https://github.com/blueimp/jQuery-File-Upload/wiki/Options https://developer.vimeo.com/api/upload#http-put-uploading I think it's close to be working but I must be missing some detail. According to Vimeo's API, I need to : 1. Generate an upload ticket, which works fine 2. I then pass the upload_link_secure to jquery file upload which starts uploading. This is what the requests headers for the PUT request look like :

Request Method:PUT
Status Code:200 OK
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:43418955
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarye8sGy57JH6ACoOfJ

This is how I call jQuery file upload :

$('#file').fileupload({
url: upload_link_secure,
type: 'PUT'
});

I also tried forcing the Content-Type header to "video/mp4" but it doesn't make any difference in the end.

I also checked the size of the file by binding jquery fileupload's submit event and I also get a lower bytes count than what's sent in the headers, 43418764 in this example, is this okay ?

  1. Verify the upload by sending PUT requests on upload_link_secure, some response headers I get :

Status Code:308 Resume Incomplete

Range:bytes=0-3948544

Status Code:308 Resume Incomplete

Range:bytes=0-38682624

Status Code:308 Resume Incomplete

Range:bytes=0-43401216

  1. Make sure all the bytes made it to Vimeo, then complete the upload by sending a DELETE request on complete_uri I get this last header when verifying the upload :

Range:bytes=0-43418955

It seems to match the Content-Length send in the first request so I perform a DELETE request, and this is the reponse I get :

{"body":{"error":"Your video file is not valid. Either you have uploaded an invalid file format, or your upload is incomplete. Make sure you verify your upload before marking it as complete."},"status":400,"headers":{"Date":"Mon, 06 Oct 2014 17","Server":"Apache","Vary":"Accept,Vimeo-Client-Id,Accept-Encoding","Cache-Control":"no-cache, max-age=315360000","Expires":"Thu, 03 Oct 2024 17","Content-Length":"184","X-Cnection":"close","Content-Type":"application/vnd.vimeo.error+json","Via":"1.1 dca1-10"}}

I must have made a very dumb mistake but I'm not very familiar with all those HTTP requests and reponses, does anybody know what I did wrong ?

Thanks !

[edit] Thanks a lot Dashron, I actually had to set jQuery fileupload's multipart option to false :

$('#file').fileupload({
        url: upload_link_secure,
        type: 'PUT',
        multipart: false
    });

After that, I was getting this HTTP error :

XMLHttpRequest cannot load https://1511632921.cloud.vimeo.com/upload?[...]. Request header field Content-Disposition is not allowed by Access-Control-Allow-Headers. 

There might be a clean fix for that but I didn't find it so I simply commented the lines that set the Content-Disposition header in jquery.fileupload.js

// if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
//     options.headers['Content-Disposition'] = 'attachment; filename="' +
//         encodeURI(file.name) + '"';
// }

(see edit3)

Now it works fine ! :)

[edit2] I was asked for a more complete example of the code I came up with to make that PUT upload work so here is a Gist containing the relevant Twig template from my Symfony application. I hope it's clear enough and that it can help. The code can probably be improved a lot but I guess it's an okay starting point. https://gist.github.com/paulgv/13ff6d194bc0d662de7b

[edit3] I also realize that I never updated my code with a cleaner fix for the issue I had with the Content-Disposition header (see crossed out text above). Thanks to blueimp's help, I found out that you can simply remove this header in fileuploadsend callback :

.bind('fileuploadsend', function (e, data) {
    data.headers = {};
})
like image 737
paulgv Avatar asked Oct 06 '14 18:10

paulgv


1 Answers

PUT uploads do not support multipart form encoding. PUT uploads should have a request body of only the raw bytes of the file.

Multipart is supported on POST uploads, but POST uploads do not support resumable uploads or range headers.

like image 98
Dashron Avatar answered Sep 21 '22 08:09

Dashron