YouTube direct upload using ClientLogin via Android
I have to make an application which uploads videos for specific YouTube user. I've tried several libraries but unfortunately without any success. So since what I want to do is really very simple, I've decided to do it on my own, but with not much luck until now. I am able to retrieve authentication token successfully, but couldn't manage to make the file upload work. Here is my code:
File file = new File(videoPath);
String boundary = "f93dcbA3";
String endLine = "\r\n";
StringBuilder sb = new StringBuilder();
sb.append("--");
sb.append(boundary);
sb.append(endLine);
sb.append("Content-Type: application/atom+xml; charset=UTF-8");
sb.append(endLine);
sb.append(endLine);
sb.append(entry);
sb.append(endLine);
sb.append("--");
sb.append(boundary);
sb.append(endLine);
sb.append("Content-Type: video/3gpp");
sb.append(endLine);
sb.append("Content-Transfer-Encoding: binary");
sb.append(endLine);
sb.append(endLine);
String bodyStart = sb.toString();
sb = new StringBuilder();
sb.append(endLine);
sb.append("--");
sb.append(boundary);
sb.append("--");
String bodyEnd = sb.toString();
HttpURLConnection conn;
try {
FileInputStream fIn = new FileInputStream(file);
byte fileBytes[] = new byte[(int) file.length()];
fIn.read(fileBytes);
conn = (HttpURLConnection) new URL("http://uploads.gdata.youtube.com/feeds/api/users/" + username + "/uploads")
.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/related; boundary=\"" + boundary + "\"");
conn.setRequestProperty("Host", "uploads.gdata.youtube.com");
conn.setRequestProperty("Authorization", "GoogleLogin auth=" + auth);
conn.setRequestProperty("GData-Version", "2");
conn.setRequestProperty("X-GData-Key", "key=" + devKey);
conn.setRequestProperty("Slug", "video.3gp");
conn.setRequestProperty("Content-Length", "" + (bodyStart.getBytes().length
+ fileBytes.length + bodyEnd.getBytes().length));
conn.setRequestProperty("Connection", "close");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
try {
conn.connect();
Log.d("ID", "" + file.length());
try {
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(bodyStart.getBytes());
os.write(fileBytes);
os.write(bodyEnd.getBytes());
os.flush();
String response = "";
try {
response = "Success! " + read(conn.getInputStream());
} catch (FileNotFoundException e) {
/开发者_开发知识库/ Error Stream contains JSON that we can parse to a FB error
response = "Error!" + read(conn.getErrorStream());
}
Log.d("ID", response);
} catch (FileNotFoundException e1) {
Log.d("ID", e1.getMessage(), e1);
} catch (IOException e) {
Log.d("ID", e.getMessage(), e);
}
} catch (IOException e2) {
Log.d("ID", e2.getMessage(), e2);
}
} catch (MalformedURLException e3) {
Log.d("ID", e3.getMessage(), e3);
} catch (IOException e3) {
Log.d("ID", e3.getMessage(), e3);
}
And the xml entry (a simple copy-paste from the specification):
private static String entry = "<?xml version=\"1.0\"?>"
+ "<entry xmlns=\"http://www.w3.org/2005/Atom\""
+ " xmlns:media=\"http://search.yahoo.com/mrss/\""
+ " xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">"
+ "<media:group>"
+ "<media:title type=\"plain\">Bad Wedding Toast</media:title>"
+ "<media:description type=\"plain\">"
+ "I gave a bad toast at my friend's wedding. Maybe"
+ "</media:description>"
+ "<media:category"
+ " scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">People"
+ "</media:category>"
+ "<media:keywords>toast, wedding</media:keywords>"
+ "</media:group>"
+ "</entry>";
The code above is written according to the YouTube specification In short - the response I receive is "411 Length Required", meaning that I don't have Content-Length in the header, but I do! I have no idea where the problem is, I don't know if any of my code is correct :( I'd appreciate any help you could offer me :(
I found it with the help of Wireshark! Although I still can't see it, there is a symbol for a new line at the end of my auth string. This adds an extra line in my http header which should not be there and at the the end the result is "411 Length Required" for some weird reason.
So if you get the same error, try removing the last character from your auth string.
精彩评论