分块上传视频文件 [英] Upload a video file by chunks

查看:45
本文介绍了分块上传视频文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是的,这是一个很长的问题,有很多细节......所以,我的问题是:如何将上传的内容分段流式传输到 Vimeo?

对于想要在自己的机器上进行复制和调试的任何人:以下是您需要的东西:

  • 我的代码这里.
  • 包括在此处
  • 找到的 Scribe 库
  • 拥有一个至少大于 10 MB 的有效视频文件 (mp4) 并将其放入目录 C:\test.mp4 或更改该代码以指向您所在的任何位置.
  • 就是这样!感谢您帮助我!

重大更新:我在代码此处为 Vimeo 留下了有效的 API 密钥和秘密.因此,只要您拥有 Vimeo 帐户,一旦您允许该应用程序并输入您的令牌,所有代码都应该适合您.只需将该链接中的代码复制到您最喜欢的 IDE 上的项目中,看看您是否可以与我一起解决此问题.我会给给我工作代码的人赏金.谢谢!哦,不要指望长时间使用这个 Key 和 Secret.一旦这个问题解决了,我会删除它.:)

问题概述: 问题是当我将最后一个字节块发送给 Vimeo 然后验证上传时,响应返回所有内容的长度仅为最后一个块,不是所有的块都按原样组合在一起.

SSCCE 注意:我有我的整个 SSCCE 这里.我把它放在其他地方,所以它可以C ompilable.它不是很S hort(大约300 行),但希望你发现它包含S 小精灵,而且它肯定是一个E示例!).但是,我在这篇文章中发布了我的代码的相关部分.

工作原理:当您通过流式传输方法将视频上传到 Vimeo 时(请参阅上传 API 文档here 用于设置以达到这一点),您必须提供一些标题:端点、内容长度和内容类型.文档说它忽略任何其他标题.您还可以为您上传的文件提供字节信息的有效负载.然后签名并发送它(我有一个方法可以使用 scribe).

我的问题:当我只在一个请求中发送视频时,一切都很好.我的问题是,当我上传几个更大的文件时,我使用的计算机没有足够的内存来加载所有这些字节信息并将其放入 HTTP PUT 请求中,因此我必须将其拆分为1 MB 段.这就是事情变得棘手的地方.文档提到可以恢复"上传,所以我试图用我的代码来做到这一点,但它工作得不太正确.下面,您将看到发送视频的代码.记住我的 SSCCE 这里.

我尝试过的事情:我认为这与 Content-Range 标头有关...所以这里是我在更改 Content-Range 时尝试过的事情标题说...

  • 未将内容范围标头添加到第一个块
  • 向内容范围标题添加前缀(每个都与前一个标题的组合):

    • 字节"
    • "bytes" (抛出连接错误,错误见最底部) --> 它出现在 documentation 这就是他们正在寻找的内容,但我很确定文档中有错别字,因为他们的简历"示例中的内容范围标题为:1001-339108/339108 应该是 1001-339107/339108.所以......是的......
    • "bytes%20"
    • 字节:"
    • "字节:"
    • "bytes="
    • "bytes="
  • 不向内容范围标题添加任何前缀

代码如下:

/*** 发送视频数据** @return 视频是否发送成功*/private static boolean sendVideo(String endpoint, File file) 抛出 FileNotFoundException, IOException {//设置文件long contentLength = file.length();String contentLengthString = Long.toString(contentLength);FileInputStream is = new FileInputStream(file);int bufferSize = 10485760;//10 MB = 10485760 字节字节[] bytesPortion = 新字节[bufferSize];int byteNumber = 0;int maxAttempts = 1;而 (is.read(bytesPortion, 0, bufferSize) != -1) {String contentRange = Integer.toString(byteNumber);long bytesLeft = contentLength - byteNumber;System.out.println(newline + newline + "Bytes Left: " + bytesLeft);if (bytesLeft < bufferSize) {//将bytesPortion数组复制到一个只包含剩余字节的较小数组中bytesPortion = Arrays.copyOf(bytesPortion, (int) bytesLeft);//这只是使它不会在下一次迭代时抛出 IndexOutOfBounds 异常.它不应该通过另一个迭代bufferSize = (int) bytesLeft;}byteNumber += bytesPortion.length;contentRange += "-" + (byteNumber - 1) + "/" + contentLengthString;int 尝试 = 0;布尔成功 = 假;而(尝试< maxAttempts&& !成功){int bytesOnServer = sendVideoBytes("Test video", endpoint, contentLengthString, "video/mp4", contentRange, bytesPortion, first);如果(bytesOnServer == byteNumber){成功=真;} 别的 {System.out.println(bytesOnServer + " != " + byteNumber);System.out.println("成功不是真的!");}尝试++;}第一个 = 真;如果(!成功){返回假;}}返回真;}/*** 将给定的字节发送到给定的端点** @return 服务器上的最后一个字节(来自 verifyUpload(endpoint))*/private static int sendVideoBytes(String videoTitle, String endpoint, String contentLength, String fileType, String contentRange, byte[] fileBytes, boolean addContentRange) 抛出 FileNotFoundException, IOException {OAuthRequest request = new OAuthRequest(Verb.PUT, endpoint);request.addHeader("Content-Length", contentLength);request.addHeader("Content-Type", fileType);如果(添加内容范围){request.addHeader("Content-Range", contentRangeHeaderPrefix + contentRange);}request.addPayload(fileBytes);响应 response = signAndSendToVimeo(request, "sendVideo on " + videoTitle, false);if (response.getCode() != 200 && !response.isSuccessful()) {返回-1;}返回 verifyUpload(endpoint);}/*** 验证上传并返回是否成功** @param 端点以验证上传到* @return 服务器上的最后一个字节*/public static int verifyUpload(字符串端点){//验证上传OAuthRequest request = new OAuthRequest(Verb.PUT, endpoint);request.addHeader("Content-Length", "0");request.addHeader("Content-Range", "bytes */*");响应 response = signAndSendToVimeo(request, "verifyUpload to " + endpoint, true);if (response.getCode() != 308 || !response.isSuccessful()) {返回-1;}String range = response.getHeader("Range");//范围=字节=0-10485759"返回 Integer.parseInt(range.substring(range.lastIndexOf("-") + 1)) + 1;//最后的 + 1 是因为 Vimeo 为您提供了 0-任何字节,其中 0 = 第一个字节}

这是 signAndSendToVimeo 方法:

/*** 签署请求并发送.返回响应.** @param 服务* @param accessToken* @param 请求* @return 响应*/公共静态响应 signAndSendToVimeo(OAuthRequest request, String description, boolean printBody) 抛出 org.scribe.exceptions.OAuthException {System.out.println(换行+换行+签名"+描述+请求:"+ ((printBody && !request.getBodyContents().isEmpty()) ? 换行符 + "\tBody Contents:" + request.getBodyContents() : "")+ ((!request.getHeaders().isEmpty()) ? 换行符 + "\tHeaders: " + request.getHeaders() : ""));service.signRequest(accessToken, request);打印请求(请求,描述);响应 response = request.send();打印响应(响应,描述,printBody);返回响应;}

这里是一些(一个例子......所有的输出都可以在这里找到a>) 来自 printRequest 和 printResponse 方法的输出:注意 此输出根据 contentRangeHeaderPrefix 设置的内容和 first 布尔值而变化设置为(指定是否在第一个块上包含 Content-Range 标头).

我们正在发送视频以供上传!剩余字节数:15125120在测试视频请求上签署 sendVideo:标题:{Content-Length=15125120,Content-Type=video/mp4,Content-Range=bytes%200-10485759/15125120}在测试视频上发送视频 >>>要求头:{授权= OAuth的oauth_signature = zUdkaaoJyvz%2Bt6zoMvAFvX0DRkc%3D",oauth_version = 1.0",oauth_nonce = 340477132",oauth_signature_method = HMAC-SHA1",oauth_consumer_key = 5cb447d1fc4c3308e2c6531e45bcadf1",组oauth_token = 460633205c55d3f1806bcab04174ae09",oauth_timestamp =1334336004",内容长度=15125120,内容类型=视频/mp4,内容范围=字节:0-10485759/15125120}动词:PUT完整网址:http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d在测试视频上发送视频 >>>回复代码:200标头:{null=HTTP/1.1 200 OK,Content-Length=0,Connection=close,Content-Type=text/plain,Server=Vimeo/1.0}签名 verifyUpload 到 http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d 请求:标头:{Content-Length=0, Content-Range=bytes */*}验证上传到 http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>要求头:{授权= OAuth的oauth_signature = FQg8HJe84nrUTdyvMJGM37dpNpI%3D",oauth_version = 1.0",oauth_nonce = 298157825",oauth_signature_method = HMAC-SHA1",oauth_consumer_key = 5cb447d1fc4c3308e2c6531e45bcadf1",组oauth_token = 460633205c55d3f1806bcab04174ae09",oauth_timestamp =1334336015", Content-Length=0, Content-Range=bytes */*}动词:PUT完整网址:http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d验证上传到 http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>回复代码:308标头:{null=HTTP/1.1 308 恢复不完整,Range=bytes=0-10485759,Content-Length=0,Connection=close,Content-Type=text/plain,Server=Vimeo/1.0}身体:剩余字节数:4639360在测试视频请求上签署 sendVideo:标题:{内容长度=15125120,内容类型=视频/mp4,内容范围=字节:10485760-15125119/15125120}在测试视频上发送视频 >>>要求头:{授权= OAuth的oauth_signature = qspQBu42HVhQ7sDpzKGeu3%2Bn8tM%3D",oauth_version = 1.0",oauth_nonce = 183131870",oauth_signature_method = HMAC-SHA1",oauth_consumer_key = 5cb447d1fc4c3308e2c6531e45bcadf1",组oauth_token = 460633205c55d3f1806bcab04174ae09",oauth_timestamp =1334336015",内容长度=15125120,内容类型=视频/mp4,内容范围=字节%2010485760-15125119/15125120}动词:PUT完整网址:http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d在测试视频上发送视频 >>>回复代码:200标头:{null=HTTP/1.1 200 OK,Content-Length=0,Connection=close,Content-Type=text/plain,Server=Vimeo/1.0}签名 verifyUpload 到 http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d 请求:标头:{Content-Length=0, Content-Range=bytes */*}验证上传到 http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>要求头:{授权= OAuth的oauth_signature = IdhhhBryzCa5eYqSPKAQfnVFpIg%3D",oauth_version = 1.0",oauth_nonce = 442087608",oauth_signature_method = HMAC-SHA1",oauth_consumer_key = 5cb447d1fc4c3308e2c6531e45bcadf1",组oauth_token = 460633205c55d3f1806bcab04174ae09",oauth_timestamp =1334336020", Content-Length=0, Content-Range=bytes */*}动词:PUT完整网址:http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d4639359 != 15125120验证上传到 http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>回复成功不是真的!代码:308标头:{null=HTTP/1.1 308 恢复不完整,Range=bytes=0-4639359,Content-Length=0,Connection=close,Content-Type=text/plain,Server=Vimeo/1.0}身体:

然后代码继续完成上传和设置视频信息(你可以在我的完整代码中看到)).

编辑 2: 尝试从内容范围中删除%20",但在建立连接时收到此错误.我必须使用bytes%20"或根本不添加bytes"...

线程main"org.scribe.exceptions.OAuthException 中的异常:创建连接时出现问题.在 org.scribe.model.Request.send(Request.java:70)在 org.scribe.model.OAuthRequest.send(OAuthRequest.java:12)在 autouploadermodel.VimeoTest.signAndSendToVimeo(VimeoTest.java:282)在 autouploadermodel.VimeoTest.sendVideoBytes(VimeoTest.java:130)在 autouploadermodel.VimeoTest.sendVideo(VimeoTest.java:105)在 autouploadermodel.VimeoTest.main(VimeoTest.java:62)引起:java.io.IOException:写入服务器时出错在 sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:622)在 sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:634)在 sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1317)在 java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)在 org.scribe.model.Response.(Response.java:28)在 org.scribe.model.Request.doSend(Request.java:110)在 org.scribe.model.Request.send(Request.java:62)……还有 5 个Java 结果:1

编辑 1: 更新了代码和输出.还需要帮助!

解决方案

我认为您的问题可能只是这行的结果:

request.addHeader("Content-Range", "bytes%20" + contentRange);

尝试将 "bytes%20" 简单地替换为 "bytes "

在您的输出中,您会看到相应的标题内容不正确:

标题:{内容长度=15125120,内容类型=视频/mp4,内容范围=字节%200-10485759/15125120 <-- 不正确}

关于Content-Range...

您是对的,示例最终内容块的范围应类似于 14680064-15125119/15125120.这是 HTTP 1.1 规范的一部分.

Yes, it's a long question with a lot of detail... So, my question is: How can I stream an upload to Vimeo in segments?

For anyone wanting to copy and debug on their own machine: Here are the things you need:

  • My code here.
  • Include the Scribe library found here
  • Have a valid video file (mp4) which is at least greater than 10 MB and put it in the directory C:\test.mp4 or change that code to point wherever yours is.
  • That's it! Thanks for helping me out!

Big update: I've left a working API Key and Secret for Vimeo in the code here. So as long as you have a Vimeo account, all the code should work just fine for you once you've allowed the application and entered your token. Just copy the code from that link into a project on your favorite IDE and see if you can fix this with me. I'll give the bounty to whoever gives me the working code. Thanks! Oh, and don't expect to use this Key and Secret for long. Once this problem's resolved I'll delete it. :)

Overview of the problem: The problem is when I send the last chunk of bytes to Vimeo and then verify the upload, the response returns that the length of all the content is the length of only the last chunk, not all the chunks combined as it should be.

SSCCE Note: I have my entire SSCCE here. I put it somewhere else so it can be C ompilable. It is NOT very S hort (about 300 lines), but hopefully you find it to be S elf-contained, and it's certainly an E xample!). I am, however, posting the relevant portions of my code in this post.

This is how it works: When you upload a video to Vimeo via the streaming method (see Upload API documentation here for setup to get to this point), you have to give a few headers: endpoint, content-length, and content-type. The documentation says it ignores any other headers. You also give it a payload of the byte information for the file you're uploading. And then sign and send it (I have a method which will do this using scribe).

My problem: Everything works great when I just send the video in one request. My problem is in cases when I'm uploading several bigger files, the computer I'm using doesn't have enough memory to load all of that byte information and put it in the HTTP PUT request, so I have to split it up into 1 MB segments. This is where things get tricky. The documentation mentions that it's possible to "resume" uploads, so I'm trying to do that with my code, but it's not working quite right. Below, you'll see the code for sending the video. Remember my SSCCE is here.

Things I've tried: I'm thinking it has something to do with the Content-Range header... So here are the things I've tried in changing what the Content-Range header says...

  • Not adding content range header to the first chunk
  • Adding a prefix to the content range header (each with a combination of the previous header):

    • "bytes"
    • "bytes " (throws connection error, see the very bottom for the error) --> It appears in the documentation that this is what they're looking for, but I'm pretty sure there are typos in the documentation because they have the content-range header on their "resume" example as: 1001-339108/339108 when it should be 1001-339107/339108. So... Yeah...
    • "bytes%20"
    • "bytes:"
    • "bytes: "
    • "bytes="
    • "bytes= "
  • Not adding anything as a prefix to the content range header

Here's the code:

/**
* Send the video data
*
* @return whether the video successfully sent
*/
private static boolean sendVideo(String endpoint, File file) throws FileNotFoundException, IOException {
  // Setup File
  long contentLength = file.length();
  String contentLengthString = Long.toString(contentLength);
  FileInputStream is = new FileInputStream(file);
  int bufferSize = 10485760; // 10 MB = 10485760 bytes
  byte[] bytesPortion = new byte[bufferSize];
  int byteNumber = 0;
  int maxAttempts = 1;
  while (is.read(bytesPortion, 0, bufferSize) != -1) {
    String contentRange = Integer.toString(byteNumber);
    long bytesLeft = contentLength - byteNumber;
    System.out.println(newline + newline + "Bytes Left: " + bytesLeft);
    if (bytesLeft < bufferSize) {
      //copy the bytesPortion array into a smaller array containing only the remaining bytes
      bytesPortion = Arrays.copyOf(bytesPortion, (int) bytesLeft);
      //This just makes it so it doesn't throw an IndexOutOfBounds exception on the next while iteration. It shouldn't get past another iteration
      bufferSize = (int) bytesLeft;
    }
    byteNumber += bytesPortion.length;
    contentRange += "-" + (byteNumber - 1) + "/" + contentLengthString;
    int attempts = 0;
    boolean success = false;
    while (attempts < maxAttempts && !success) {
      int bytesOnServer = sendVideoBytes("Test video", endpoint, contentLengthString, "video/mp4", contentRange, bytesPortion, first);
      if (bytesOnServer == byteNumber) {
        success = true;
      } else {
        System.out.println(bytesOnServer + " != " + byteNumber);
        System.out.println("Success is not true!");
      }
      attempts++;
    }
    first = true;
    if (!success) {
      return false;
    }
  }
  return true;
}

/**
* Sends the given bytes to the given endpoint
*
* @return the last byte on the server (from verifyUpload(endpoint))
*/
private static int sendVideoBytes(String videoTitle, String endpoint, String contentLength, String fileType, String contentRange, byte[] fileBytes, boolean addContentRange) throws FileNotFoundException, IOException {
  OAuthRequest request = new OAuthRequest(Verb.PUT, endpoint);
  request.addHeader("Content-Length", contentLength);
  request.addHeader("Content-Type", fileType);
  if (addContentRange) {
    request.addHeader("Content-Range", contentRangeHeaderPrefix + contentRange);
  }
  request.addPayload(fileBytes);
  Response response = signAndSendToVimeo(request, "sendVideo on " + videoTitle, false);
  if (response.getCode() != 200 && !response.isSuccessful()) {
    return -1;
  }
  return verifyUpload(endpoint);
}

/**
* Verifies the upload and returns whether it's successful
*
* @param endpoint to verify upload to
* @return the last byte on the server
*/
public static int verifyUpload(String endpoint) {
  // Verify the upload
  OAuthRequest request = new OAuthRequest(Verb.PUT, endpoint);
  request.addHeader("Content-Length", "0");
  request.addHeader("Content-Range", "bytes */*");
  Response response = signAndSendToVimeo(request, "verifyUpload to " + endpoint, true);
  if (response.getCode() != 308 || !response.isSuccessful()) {
    return -1;
  }
  String range = response.getHeader("Range");
  //range = "bytes=0-10485759"
  return Integer.parseInt(range.substring(range.lastIndexOf("-") + 1)) + 1;
  //The + 1 at the end is because Vimeo gives you 0-whatever byte where 0 = the first byte
}

Here's the signAndSendToVimeo method:

/**
* Signs the request and sends it. Returns the response.
*
* @param service
* @param accessToken
* @param request
* @return response
*/
public static Response signAndSendToVimeo(OAuthRequest request, String description, boolean printBody) throws org.scribe.exceptions.OAuthException {
  System.out.println(newline + newline
          + "Signing " + description + " request:"
          + ((printBody && !request.getBodyContents().isEmpty()) ? newline + "\tBody Contents:" + request.getBodyContents() : "")
          + ((!request.getHeaders().isEmpty()) ? newline + "\tHeaders: " + request.getHeaders() : ""));
  service.signRequest(accessToken, request);
  printRequest(request, description);
  Response response = request.send();
  printResponse(response, description, printBody);
  return response;
}

And here's some (an example... All of the output can be found here) of the output from the printRequest and printResponse methods: NOTE This output changes depending on what the contentRangeHeaderPrefix is set to and the first boolean is set to (which specifies whether or not to include the Content-Range header on the first chunk).

We're sending the video for upload!


Bytes Left: 15125120


Signing sendVideo on Test video request:
    Headers: {Content-Length=15125120, Content-Type=video/mp4, Content-Range=bytes%200-10485759/15125120}

sendVideo on Test video >>> Request
Headers: {Authorization=OAuth oauth_signature="zUdkaaoJyvz%2Bt6zoMvAFvX0DRkc%3D", oauth_version="1.0", oauth_nonce="340477132", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="5cb447d1fc4c3308e2c6531e45bcadf1", oauth_token="460633205c55d3f1806bcab04174ae09", oauth_timestamp="1334336004", Content-Length=15125120, Content-Type=video/mp4, Content-Range=bytes: 0-10485759/15125120}
Verb: PUT
Complete URL: http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d

sendVideo on Test video >>> Response
Code: 200
Headers: {null=HTTP/1.1 200 OK, Content-Length=0, Connection=close, Content-Type=text/plain, Server=Vimeo/1.0}


Signing verifyUpload to http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d request:
    Headers: {Content-Length=0, Content-Range=bytes */*}

verifyUpload to http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>> Request
Headers: {Authorization=OAuth oauth_signature="FQg8HJe84nrUTdyvMJGM37dpNpI%3D", oauth_version="1.0", oauth_nonce="298157825", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="5cb447d1fc4c3308e2c6531e45bcadf1", oauth_token="460633205c55d3f1806bcab04174ae09", oauth_timestamp="1334336015", Content-Length=0, Content-Range=bytes */*}
Verb: PUT
Complete URL: http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d

verifyUpload to http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>> Response
Code: 308
Headers: {null=HTTP/1.1 308 Resume Incomplete, Range=bytes=0-10485759, Content-Length=0, Connection=close, Content-Type=text/plain, Server=Vimeo/1.0}
Body: 


Bytes Left: 4639360


Signing sendVideo on Test video request:
    Headers: {Content-Length=15125120, Content-Type=video/mp4, Content-Range=bytes: 10485760-15125119/15125120}

sendVideo on Test video >>> Request
Headers: {Authorization=OAuth oauth_signature="qspQBu42HVhQ7sDpzKGeu3%2Bn8tM%3D", oauth_version="1.0", oauth_nonce="183131870", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="5cb447d1fc4c3308e2c6531e45bcadf1", oauth_token="460633205c55d3f1806bcab04174ae09", oauth_timestamp="1334336015", Content-Length=15125120, Content-Type=video/mp4, Content-Range=bytes%2010485760-15125119/15125120}
Verb: PUT
Complete URL: http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d

sendVideo on Test video >>> Response
Code: 200
Headers: {null=HTTP/1.1 200 OK, Content-Length=0, Connection=close, Content-Type=text/plain, Server=Vimeo/1.0}


Signing verifyUpload to http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d request:
    Headers: {Content-Length=0, Content-Range=bytes */*}

verifyUpload to http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>> Request
Headers: {Authorization=OAuth oauth_signature="IdhhhBryzCa5eYqSPKAQfnVFpIg%3D", oauth_version="1.0", oauth_nonce="442087608", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="5cb447d1fc4c3308e2c6531e45bcadf1", oauth_token="460633205c55d3f1806bcab04174ae09", oauth_timestamp="1334336020", Content-Length=0, Content-Range=bytes */*}
Verb: PUT
Complete URL: http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d

4639359 != 15125120
verifyUpload to http://174.129.125.96:8080/upload?ticket_id=5ea64d64547e38e5e3c121852b2d306d >>> Response
Success is not true!
Code: 308
Headers: {null=HTTP/1.1 308 Resume Incomplete, Range=bytes=0-4639359, Content-Length=0, Connection=close, Content-Type=text/plain, Server=Vimeo/1.0}
Body: 

Then the code goes on to complete the upload and set video information (you can see that in my full code).

Edit 2: Tried removing the "%20" from the content-range and received this error making connection. I must use either "bytes%20" or not add "bytes" at all...

Exception in thread "main" org.scribe.exceptions.OAuthException: Problems while creating connection.
    at org.scribe.model.Request.send(Request.java:70)
    at org.scribe.model.OAuthRequest.send(OAuthRequest.java:12)
    at autouploadermodel.VimeoTest.signAndSendToVimeo(VimeoTest.java:282)
    at autouploadermodel.VimeoTest.sendVideoBytes(VimeoTest.java:130)
    at autouploadermodel.VimeoTest.sendVideo(VimeoTest.java:105)
    at autouploadermodel.VimeoTest.main(VimeoTest.java:62)
Caused by: java.io.IOException: Error writing to server
    at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:622)
    at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:634)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1317)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
    at org.scribe.model.Response.<init>(Response.java:28)
    at org.scribe.model.Request.doSend(Request.java:110)
    at org.scribe.model.Request.send(Request.java:62)
    ... 5 more
Java Result: 1

Edit 1: Updated the code and output. Still need help!

解决方案

I think your problem could simply be the result of this line:

request.addHeader("Content-Range", "bytes%20" + contentRange);

Try and replace "bytes%20" by simply "bytes "

In your output you see the corresponding header has incorrect content:

Headers: {
    Content-Length=15125120,
    Content-Type=video/mp4,
    Content-Range=bytes%200-10485759/15125120     <-- INCORRECT
}

On the topic of Content-Range...

You're right that an example final block of content should have a range like 14680064-15125119/15125120. That's part of the HTTP 1.1 spec.

这篇关于分块上传视频文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆