द्वारा एक वीडियो फ़ाइल अपलोड करें हां, यह बहुत विस्तार से एक लंबा प्रश्न है ... तो, मेरा सवाल है: मैं सेगमेंट में वीमियो को अपलोड कैसे कर सकता हूं?चंक्स
अपने स्वयं मशीन पर कॉपी और डिबग के लिए इच्छुक किसी के लिए:
- मेरे कोड here: यहाँ चीजें आप की जरूरत है।
- शामिल स्क्राइब पुस्तकालय पाया here
- कोई मान्य वीडियो फ़ाइल (MP4) जो 10 MB से कम से कम अधिक है है और बात करने के लिए जहाँ कहीं भी तुम्हारा है निर्देशिका
C:\test.mp4
में रख या कि कोड बदल जाते हैं। - यही वह है! मेरी मदद करने के लिए धन्यवाद!
बिग अद्यतन: मैं कोड here में Vimeo के लिए एक काम कर API कुंजी और गुप्त छोड़ दिया है। इसलिए जब तक आपके पास Vimeo खाता है, तब तक जब आप एप्लिकेशन को अनुमति देते हैं और अपना टोकन दर्ज करते हैं तो सभी कोड आपके लिए ठीक काम करना चाहिए। बस उस लिंक से कोड को अपने पसंदीदा आईडीई पर एक प्रोजेक्ट में कॉपी करें और देखें कि क्या आप इसे मेरे साथ ठीक कर सकते हैं। मैं जो भी मुझे कामकाजी कोड देता हूं उसे बक्षीस दूंगा। धन्यवाद! ओह, और लंबे समय तक इस कुंजी और गुप्त का उपयोग करने की उम्मीद नहीं है। एक बार यह समस्या हल हो जाने के बाद मैं इसे हटा दूंगा। समस्या का :)
अवलोकन: समस्या है जब मैं Vimeo बाइट्स के अंतिम हिस्सा भेजने और अपलोड करने की पुष्टि, प्रतिक्रिया लौटाता है कि सभी सामग्री की लंबाई केवल पिछले हिस्सा की लंबाई है , सभी हिस्सों को संयुक्त नहीं होना चाहिए।
एसएससीसीई नोट: मेरे पास मेरा पूरा एसएससीसीई here है। मैंने इसे कहीं और रखा है, इसलिए यह सी अयोग्य हो सकता है। यह बहुत एस हॉर्ट (लगभग 300 लाइनें) नहीं है, लेकिन उम्मीद है कि आपको एस एल्फ-निहित होना चाहिए, और यह निश्चित रूप से ई xample!) है। हालांकि, मैं इस पोस्ट में अपने कोड के प्रासंगिक भाग पोस्ट कर रहा हूं। , सामग्री- समाप्ति बिंदु:
यह है कि यह कैसे काम करता है: आप स्ट्रीमिंग विधि के माध्यम से Vimeo करने के लिए एक वीडियो अपलोड करते हैं (अपलोड API दस्तावेज़ here देख सेटअप इस बिंदु को पाने के लिए के लिए), तो आपको कुछ हेडर देना है लंबाई, और सामग्री प्रकार। दस्तावेज कहता है कि यह किसी भी अन्य शीर्षकों को अनदेखा करता है। आप इसे अपलोड करने वाली फ़ाइल के लिए बाइट जानकारी का एक पेलोड भी देते हैं। और उसके बाद हस्ताक्षर करें और भेजें (मेरे पास एक तरीका है जो scribe का उपयोग करके ऐसा करेगा)।
मेरी समस्या: जब मैं सिर्फ एक अनुरोध में वीडियो भेजता हूं तो सबकुछ बढ़िया काम करता है। मेरी समस्या उन मामलों में है जब मैं कई बड़ी फाइलें अपलोड कर रहा हूं, कंप्यूटर जो मैं उपयोग कर रहा हूं उसमें सभी बाइट जानकारी लोड करने के लिए पर्याप्त स्मृति नहीं है और इसे HTTP PUT अनुरोध में डाल दिया गया है, इसलिए मुझे इसे विभाजित करना है 1 एमबी सेगमेंट यह वह जगह है जहां चीजें मुश्किल हो जाती हैं। प्रलेखन का उल्लेख है कि अपलोड को "फिर से शुरू करना" संभव है, इसलिए मैं इसे अपने कोड के साथ करने की कोशिश कर रहा हूं, लेकिन यह बिल्कुल सही काम नहीं कर रहा है। नीचे, आप वीडियो भेजने के लिए कोड देखेंगे। याद रखें मेरी SSCCE here है।
जो चीजें मैंने कोशिश की हैं: मुझे लगता है कि यह सामग्री-श्रेणी शीर्षलेख के साथ कुछ करने के लिए है ...तो यहाँ बातें मैं बदल रहा है क्या सामग्री रेंज हैडर का कहना है में की कोशिश की है ...
- पहले हिस्सा
सामग्री रेंज शीर्षक के एक उपसर्ग जोड़ने के लिए सामग्री सीमा हेडर को जोड़े नहीं (प्रत्येक रहे हैं पिछले हैडर का एक संयोजन) के साथ:
- "बाइट"
- "बाइट" (कनेक्शन त्रुटि फेंकता है, त्रुटि के लिए बहुत नीचे देखें) -> यह documentation में प्रतीत होता है कि यह क्या है वे की तलाश में है, लेकिन मुझे यकीन है कि टी हैं दस्तावेज में ypos क्योंकि उनके पास "resume" उदाहरण पर सामग्री-श्रेणी शीर्षलेख है:
1001-339108/339108
जब यह1001-339107/339108
होना चाहिए। तो ... हाँ ... - "बाइट्स% 20"
- "बाइट:"
- "बाइट:"
- "बाइट्स ="
- "बाइट्स ="
सामग्री रेंज हैडर
यहाँ करने के लिए एक उपसर्ग के रूप में कुछ भी जोड़ने नहीं कोड है:
01,235,/**
* 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
}
यहाँ signAndSendToVimeo विधि है:
/**
* 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;
}
और यहाँ कुछ (एक उदाहरण ... उत्पादन के सभी here पाया जा सकता है) printRequest और printResponse तरीकों से उत्पादन की है: नोट यह आउटपुट contentRangeHeaderPrefix
पर सेट किया गया है और first
बूलियन पर सेट किया गया है (जो निर्दिष्ट करता है कि पहले खंड पर सामग्री-श्रेणी शीर्षलेख शामिल करना है या नहीं)।
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:
तो कोड अपलोड और सेट वीडियो जानकारी पूरा करने के लिए पर चला जाता है (आपको लगता है कि my full code में देख सकते हैं)।
संपादित करें 2: सामग्री-सीमा से "% 20" को निकालने का प्रयास किया और यह त्रुटि कनेक्शन बना। मैं या तो "बाइट्स% 20" का उपयोग करना चाहिए या नहीं जोड़ "बाइट" बिल्कुल ...
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
संपादित करें 1: कोड और आउटपुट अपडेट किया गया। अभी भी सहायता चाहिए!
तुम्हारा के अलावा अन्य खातों की तरह लग रहा अपनी API कुंजी + गुप्त उपयोग करने में सक्षम नहीं हैं। हालांकि, मुझे पुनः अपलोड करने योग्य अपलोड पर कुछ और दस्तावेज मिल गए हैं और पता चला है कि 1. हेडर वास्तव में "सामग्री-श्रेणी: बाइट 0-49 9/1000" और 2 जैसा दिखना चाहिए। 2. आपके अंतिम PUT के लिए शीर्षलेख इस तरह दिखना चाहिए " सामग्री-रेंज: 500-999/1000 बाइट्स "। http://code.google.com/apis/gdata/docs/resumable_upload.html#Resuming – TomTasche
अजीब Vimeo API चीज काम नहीं कर रही है। @anyone else: क्या यह आपके लिए भी वही है? मैं अपने हेडर को ऐसा संकेत नहीं दे रहा हूं जैसा आपने संकेत दिया है क्योंकि जब मैं बाइट्स को उपसर्ग के रूप में "बाइट्स" का उपयोग करता हूं तो यह एक कनेक्शन अपवाद फेंकता है (ऊपर त्रुटि देखें)। – kentcdodds
आपके द्वारा छोड़े गए 'काम कर रहे एपीआई' का लिंक टूटा हुआ है! –