Vimeo upload using chunks
我遇到了与此处相同的问题:使用 "Content-Range" 标头分块上传视频文件,但给出的解决方案均不适合我。我正在使用 javascript 将视频放到 Vimeo 端点。我得到了一张上传票,并通过 php 在另一台服务器上处理上传的初始化和完成。 javascript 所做的只是将视频数据放到一个端点。
我的客户端的互联网连接不可靠,因此我正在构建一个尝试自动恢复的可恢复上传器。
我注意到的是,如果我删除 "Content-Range" 标头并将我的块大小设置为大于上传视频,它会正确上传。一旦我添加标题,事情就会出错。
我知道标头的格式应该是 "Content-Range": "bytes 1001-4999/5000" 但这会由于某种原因导致问题。当我使用这种格式时,chrome 不会发送 "Content-Length" 标头并且请求失败。 FF 发送标头,但也失败了。
我已经为"Content-Range"标头尝试了不同的组合,包括:"1001-4999/5000"、"range=1001-4999-5000"。哪个不会给出错误但 vimeo 无法识别,因为当我要求上传的字节时,我总是得到最后上传的块的长度。我也尝试过发送没有标头的第一个块,其余的都带有它,但它是标头本身没有正确发送。
Javascript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* * Uploads raw data to the server * */ var uploadRawData = function(starting_byte, ending_byte, data_to_send){ $('.auto_uploader #play_pause_button').addClass('pause').removeClass('disabled'); $('.auto_uploader #stop_button').removeClass('disabled'); $('.auto_uploader #status_display').attr('class', '').fadeIn(); //Remove all other classes _offset_starting_from = parseInt(starting_byte) || 0; _uploader_process = $.ajax({ url: _endpoint, type: 'PUT', beforeSend: function (request) { //if (starting_byte != 0){ // Send the first chunk with without content-range header // If this function is being called to resume a file, add the starting offset var content_range_header ="bytes" + starting_byte +"-" + ending_byte +"/" + _file.size; request.setRequestHeader("Content-Range", content_range_header); //} request.setRequestHeader("Content-Type", _file.type); //request.setRequestHeader("Content-Length", data.byteLength); }, processData: false, xhr: function() { // custom xhr myXhr = $.ajaxSettings.xhr(); if(myXhr.upload){ // check if upload property exists myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // for handling the progress of the upload } return myXhr; }, //Ajax events success: function() { if (ending_byte < _file.size - 1){ // Not complete (chunk mode) var next_upload_byte = ending_byte + 1; retryUpload(); // Check for uploaded bytes before next chunk upload (this creates an infinite loop since vimeo only reports the last byte uploaded, since the Content-Range header above is not being recognised) - Or //uploadFilePart(next_upload_byte, next_upload_byte + _chunk_size - 1); // - doesn't check uploaded bytes before send of next chunk (Uploads all parts, but vimeo only registers the last chunk) } else { // Complete! //retryUpload(); // Check to make sure the entire file was uploaded $('.auto_uploader #status_display').attr('class', 'tick'); resetButtons(); _completeFunction(); //Call user defined callback } }, error: function(data) { console.log(data.responseText); if (!_paused && _file != null){ //Aborting (pausing) causes an error // Retry the upload if we fail if (_retry_count < _retry_limit){ _retry_count = _retry_count + 1; console.log('Error occurred while uploading file"' + _file.name + '", retry #' + _retry_count + ' in ' + _retry_count * 10 + ' sec'); setTimeout(function() { //calls click event after a certain time retryUpload(); // Call the retry upload method in 10 sec }, 10000); } else if (_retry_count == _retry_limit){ //We've tried enough!}); resetButtons(); $('.auto_uploader #status_display').attr('class', 'error'); alert('Maximum number of retries exceeded!'); } } }, //error: errorHandler, // Form data data: data_to_send, //Options to tell JQuery not to process data or worry about content-type cache: false, contentType: false }); } |
我在这里上传了一个测试版本:http://test.paperjet.info/auto_uploader/ 和完整的源代码:http://test.paperjet.info/auto_uploader.zip 标题被添加到第 121 行autoUploader.js 的。请注意,如果您使用它,它会在 index.html 中硬编码一个端点,并且可能已经过期。
如果有人解决了这个问题或者已经使用javascript成功实现了这个功能,请告诉我。
我遇到了同样的问题,并设法在 Github 上构建了一个将视频文件按块上传到 Vimeo 的实现:https://github.com/websemantics/vimeo-upload
它使用可恢复的 PUT 并显示一个进度条并返回上传视频的 url。
在服务器上获取字节的正确方法是在请求标头中使用
1 2 3 4 5 | var byte_request = new XMLHttpRequest(); byte_request.open('PUT', upload_url, true); byte_request.overrideMimeType('application/octet-stream'); byte_request.setRequestHeader('Content-Range', 'bytes */*'); byte_request.send(); |
这应该返回 308 响应。在您的成功处理程序中,将
1 2 3 4 5 6 7 8 9 10 11 12 13 | function onByteRequestSuccess(e) { var range_header, bytes_received; if (byte_request.status === 308) { range_header = xhr.getResponseHeader('Range'); // The Range header will return something like"bytes=0-215235". // This grabs the group of numbers AFTER the"-" character, // which is the total bytes on the server. bytes_received = parseInt(range_header.split('-')[1], 10); } } |
至于您的