Laden Sie eine video-Datei von chunks

Ja, es ist eine lange Frage mit vielen Details... So, meine Frage ist: Wie kann ich den stream ein upload auf Vimeo in Segmente?

Für alle, zu kopieren und zu Debuggen, die auf Ihrer eigenen Maschine: Hier sind die Dinge, die Sie brauchen:

  • Mein code hier.
  • Gehören die Schreiber Bibliothek gefunden hier
  • Haben eine gültige video-Datei (mp4), die mindestens größer als 10 MB und steckte es in das Verzeichnis C:\test.mp4 oder ändern, dass der code zu zeigen, wo deiner ist.
  • Das ist es! Danke für die Hilfe mich aus!

Großes update: ich habe eine funktionierende API-Key und Secret für Vimeo in den code hier. So lange, wie Sie einen Vimeo-account, alle sollte der code gut funktionieren für Sie, sobald Sie erlaubt haben, die Anwendung und der Eingabe der token. Kopieren Sie einfach den code aus diesem link in ein Projekt in Ihrer bevorzugten IDE und sehen, ob Sie können dieses Problem beheben, bei mir. Ich gebe das Kopfgeld auf wer gibt mir den funktionierenden code. Danke! Oh, und erwarte nicht, diesen Schlüssel verwenden und das Geheimnis für lange. Sobald dieses problem ist behoben, ich werde es löschen. 🙂

Überblick über das problem: Das problem ist, wenn ich das Letzte Stück der bytes an, die Vimeo und überprüfen Sie den laden, die Antwort gibt, dass die Länge aller Inhalte ist die Länge, nur das Letzte Stück, nicht alle chunks kombiniert werden, wie es sein sollte.

SSCCE Hinweis: ich habe mein ganzes SSCCE hier. Ich habe es woanders so kann es sein, C ompilable. Es ist NICHT sehr S hort (über 300 Zeilen), aber ich hoffe, Sie finden es zu S elf-enthalten, und es ist sicherlich eine E Beispiel!). Ich bin, jedoch, die Veröffentlichung der relevanten Teile von meinem code in diesem post.

Dies ist, wie es funktioniert:, Wenn Sie ein video hochladen auf Vimeo über das streaming-Verfahren (siehe Upload-API-Dokumentation hier für das setup zu diesem Punkt zu kommen), muss man ein paar Header: Endpunkt -, content-length und content-type. Die Dokumentation sagt, dass es ignoriert alle anderen Kopfzeilen. Sie geben auch eine payload der byte-Informationen für die Datei, die Sie hochladen. Und dann unterzeichnen und senden Sie es (ich habe eine Methode, die dies tun, mit Schreiber).

Mein problem: Alles funktioniert Super wenn ich Sie nur schicken Sie das video in einer Anfrage. Mein problem ist, in den Fällen, wenn ich das hochladen mehrere größere Dateien, wird der computer ich bin mit nicht genügend Speicher zum laden des byte-Informationen und steckte es in die HTTP-PUT-Anfrage, so muss ich es aufteilen in 1-MB-Segmenten. Dies ist, wo die Dinge schwierig werden. Die Dokumentation erwähnt, dass es möglich ist auf "fortsetzen" uploads, so dass ich versucht bin zu tun, dass mit meinem code, aber es funktioniert nicht ganz richtig. Unten sehen Sie den code für das senden der video. Erinnern meine SSCCE ist hier.

Dinge, die ich versucht habe: ich denke es hat etwas zu tun mit dem Content-Range-header... Also hier sind die Dinge, die ich versucht habe in das verändert, was die Content-Range-header sagt...

  • Nicht das hinzufügen von content-range-header auf das erste Stück
  • Hinzufügen eines Präfixes zu den content-range-header (jedes mit einer Kombination von den vorherigen header):

    • "bytes"
    • "bytes" (wirft Verbindung Fehler, siehe ganz unten für den Fehler) --> Es erscheint in der Dokumentation, dass dies ist, was Sie suchen, aber ich bin mir ziemlich sicher, dass es Tippfehler in der Dokumentation, da Sie den content-range-header auf Ihrem "Lebenslauf" Beispiel: 1001-339108/339108 sein, wenn es 1001-339107/339108. So... Ja...
    • "bytes" %20"
    • "bytes:"
    • "bytes: "
    • "bytes="
    • "bytes= "
  • Nicht etwas hinzuzufügen, die als Präfix für den content-range-header

Hier der 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
}

Hier ist die signAndSendToVimeo Methode:

/**
* 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;
}

Und hier ist einige (ein Beispiel... Alle den Ausgang gefunden werden kann hier) für die Ausgabe des printRequest und printResponse Methoden: HINWEIS Dieser Ausgang sich ändert, je nachdem, was der contentRangeHeaderPrefix eingestellt ist und die first boolean gesetzt ist (was angibt, ob oder nicht die Content-Range-header auf das erste Stück).

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: 

Dann der code geht zu den upload-und video-Informationen (Sie können sehen, dass in mein vollständiger code).

Edit 2: Versucht haben, entfernen die "%20" aus dem content-Bereich und erhielt diesen Fehler herstellen der Verbindung. Ich muss entweder "bytes" %20" oder nicht " add "bytes" an alle...

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: Aktualisiert den code und die Ausgabe. Brauche immer noch Hilfe!

  • Sieht aus wie andere Konten als Ihre sind nicht in der Lage zu verwenden Sie Ihren API-Schlüssel + Geheimnis. Aber ich habe festgestellt, dass einige weitere Dokumentation auf fortsetzbare uploads und fand heraus, dass 1. der header sollte ja auch Aussehen wie "Content-Range: bytes 0-499/1000" und 2. der header für Ihre last LEGEN sollte wie folgt Aussehen "Content-Range: bytes 500-999/1000". code.google.com/apis/gdata/docs/resumable_upload.html#Resuming
  • Komisch, der Vimeo API, was nicht funktioniert. @jemand anderes: Ist das der gleiche für Sie? Ich kann nicht scheinen, um meine Kopfzeile so Aussehen, wie Sie angegeben haben, weil es wirft eine Verbindung Ausnahme, wenn ich "bytes" als prefix bytes, ich gebe es (siehe Fehler oben).
  • der link zu dem 'arbeiten-api' Sie Links ist gebrochen!
  • sorry, ich habe nicht mehr diesen code.
  • Können Sie bitte teilen Sie Ihre volle Video-Upload-Code auf Vimeo hier habe ich auch versucht, video-upload auf vimeo, aber nichts über Antwort
  • Sorry @smitmodi, wie gesagt, Langusten, ich habe nicht mehr diesen code. Es ist schon seit 4 Jahren...

InformationsquelleAutor kentcdodds | 2012-04-11
Schreibe einen Kommentar