我试图这样做(来自here的想法):
Entry entry = new Entry();
entry.group = new MediaGroup();
entry.group.title = "test title";
entry.group.description = "test description";
entry.group.category = new MediaCategory();
entry.group.category.Cat = "People\n";
AtomContent aContent = new AtomContent();
aContent.entry = entry;
aContent.namespaceDictionary = NAMESPACE_DICTIONARY;
Uri uri = Uri.parse(r.uri);
File file = new File(r.text);
FileContent bContent = new FileContent(file);
// bContent.inputStream = new FileInputStream(r.text);//context.getContentResolver().openInputStream(uri);
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
bContent.type = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE));
//bContent.length = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
String fileName = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
// Build up the POST request
MultipartRelatedContent multiContent = new MultipartRelatedContent();
multiContent.parts.add(aContent);
multiContent.parts.add(bContent);
HttpTransport transport = new ApacheHttpTransport();
HttpRequestFactory requestFactory = transport.createRequestFactory();
// !
HttpRequest request = requestFactory.buildPostRequest(YouTubeUrl.uploadUrl(), multiContent);
GoogleHeaders headers = new GoogleHeaders();
headers.putAll(request.headers);
request.headers = headers;
headers.setSlugFromFileName(fileName);
headers.setDeveloperId(Consts.youtubeDevKey);
headers.setGoogleLogin(accountInfo.password);
// !
request.headers.contentType = multiContent.getType();
// request.headers.contentType = bContent.getType();
request.connectTimeout = 0;
request.readTimeout = 0;
HttpResponse response = request.execute();
String strResponse = NetworkHelper.readResponse(response.getContent());
使用NetHttpTransport我得到“系统调用期间的I / O错误,断管”
//使用ApacheHttpTransport我得到“org.apache.http.client.NonRepeatableRequestException:无法在5-20秒内使用不可重复的请求实体重试请求”。 PS。我们发现ApacheHttpTransport内部异常也是“Broken Pipe”
我正在尝试使用google-api-client 1.4.1在运行Android 2.3.3的设备上进行此操作
有什么建议吗?
答案 0 :(得分:1)
android的工作代码:
import com.google.api.client.googleapis.GoogleHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
import com.google.api.client.http.InputStreamContent;
import com.google.api.client.http.MultipartRelatedContent;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.http.xml.atom.AtomContent;
import com.google.api.client.util.Key;
import com.google.api.client.xml.XmlNamespaceDictionary;
....
public static final XmlNamespaceDictionary NAMESPACE_DICTIONARY = new XmlNamespaceDictionary();
static
{
NAMESPACE_DICTIONARY.set("", "http://www.w3.org/2005/Atom")
.set("atom", "http://www.w3.org/2005/Atom")
.set("exif", "http://schemas.google.com/photos/exif/2007")
.set("gd", "http://schemas.google.com/g/2005")
.set("geo", "http://www.w3.org/2003/01/geo/wgs84_pos#")
.set("georss", "http://www.georss.org/georss")
.set("gml", "http://www.opengis.net/gml")
.set("gphoto", "http://schemas.google.com/photos/2007")
.set("media", "http://search.yahoo.com/mrss/")
.set("openSearch", "http://a9.com/-/spec/opensearch/1.1/")
.set("xml", "http://www.w3.org/XML/1998/namespace");
}
/**
* Represents an Atom formatted upload request for YouTube
*
* @see http
* ://code.google.com/intl/en/apis/youtube/2.0/developers_guide_protocol_direct_uploading.html#Sending_a_Direct_Upload_API_Request
*
* <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. </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>
* @author fhackenberger
*/
public static class UploadEntry
{
@Key("media:group")
MediaGroup group = new MediaGroup();
}
/**
* @see UploadEntry
* @author fhackenberger
*/
public static class MediaGroup
{
@Key("media:title")
MediaAttribute title = new MediaAttribute();
@Key("media:description")
MediaAttribute description = new MediaAttribute();
@Key("media:category")
MediaCategory category = new MediaCategory();
@Key("media:keywords")
String keywords;
}
/**
* @see UploadEntry
* @author fhackenberger
*/
public static class MediaAttribute
{
@Key("@type")
String type = "plain";
@Key("text()")
String value;
}
/**
* @see UploadEntry
* @author fhackenberger
*/
public static class MediaCategory
{
@Key("@scheme")
String scheme = "http://gdata.youtube.com/schemas/2007/categories.cat";
@Key("text()")
String category;
}
/**
* Represents an error response from Youtube
*
* @see http://code.google.com/intl/en/apis/youtube/2.0/developers_guide_protocol_error_responses.html <errors> <error>
* <domain>yt:validation</domain> <code>invalid_value</code> <location
* type='xpath'>media:group/media:category[@scheme='http://gdata.youtube.com/schemas/2007/categories.cat']/text() </location>
* </error> </errors>
* @author fhackenberger
*
*/
public static class YoutubeErrors
{
@Key("error")
List<YoutubeError> errors;
}
/**
* @see YoutubeErrors
* @author fhackenberger
*/
public static class YoutubeError
{
@Key
String domain;
@Key
String code;
@Key
YoutubeErrorLocation location;
@Override
public String toString()
{
return "domain: " + domain + "; code: " + code + "; location: (" + location + ")";
}
}
/**
* @see YoutubeError
* @author fhackenberger
*/
public static class YoutubeErrorLocation
{
@Key("@type")
String type;
@Key("text()")
String location;
@Override
public String toString()
{
return "type: " + type + "; location: " + location;
}
}
/**
* Represents a YouTube video feed
*
* @see http://code.google.com/intl/en/apis/youtube/2.0/developers_guide_protocol_understanding_video_feeds.html
* @author fhackenberger
*/
public static class VideoFeed
{
@Key
List<Video> items;
@Override
public String toString()
{
return "Items: " + items;
}
}
/**
* A single video entry
*
* @see VideoFeed
* @author fhackenberger
*/
public static class Video
{
@Key
String id;
@Key
String title;
@Key
String description;
@Key
Player player;
@Key("link")
List<Link> links;
@Override
public String toString()
{
return "Id: " + id + " Title: " + title + " Description: " + description + " Player: " + player + " Links: " + links;
}
}
/**
* A related link for a {@link Video}
*
* @see VideoFeed
* @author fhackenberger
*/
public static class Link
{
@Key("@rel")
String rel;
@Key("@href")
String href;
@Key("@type")
String type;
@Override
public String toString()
{
return href;
}
}
/**
* The URL for the YouTube video player for a {@link Video}
*
* @see VideoFeed
* @author fhackenberger
*/
public static class Player
{
@Key("default")
String defaultUrl;
@Override
public String toString()
{
return "DefaultURL: " + defaultUrl;
}
}
public YouTubeUploader(Context context, AccountInfo accountInfo)
{
this.context = context;
this.accountInfo = accountInfo;
}
@Override
public void upload(Record r)
{
HttpRequest request = null;
try
{
HttpTransport transport = new NetHttpTransport();
HttpRequestFactory requestFactory = transport.createRequestFactory();
request = requestFactory.buildPostRequest(YouTubeUrl.uploadUrl(), null);
File file = new File(fileName);
InputStreamContent videoContent = new InputStreamContent();
videoContent.inputStream = new FileInputStream(file);
videoContent.type = "application/octet-stream";
// Describes the video
AtomContent atomContent = new AtomContent();
atomContent.namespaceDictionary = NAMESPACE_DICTIONARY;
UploadEntry uploadEntry = new UploadEntry();
uploadEntry.group.title.value = videoTitle;
uploadEntry.group.description.value = "";
uploadEntry.group.category.category = "People\n";
uploadEntry.group.keywords = "";
atomContent.entry = uploadEntry;
MultipartRelatedContent multiPartContent = MultipartRelatedContent.forRequest(request);
multiPartContent.parts.add(atomContent);
multiPartContent.parts.add(videoContent);
request.content = multiPartContent;
GoogleHeaders headers = new GoogleHeaders();
headers.setApplicationName(Consts.youtubeAppName);
headers.acceptEncoding = "gzip";
headers.mimeVersion = "1.0";
headers.gdataVersion = "2";
headers.setDeveloperId(Consts.youtubeDevKey);
headers.setGoogleLogin(accountInfo.token);
headers.slug = GoogleHeaders.SLUG_ESCAPER.escape(videoTitle);
request.headers = headers;
request.unsuccessfulResponseHandler = new YoutubeUnsuccessfulResponseHandler();
// HttpParser parser = new AtomParser();
// ((AtomParser)parser).namespaceDictionary = NAMESPACE_DICTIONARY;
// request.addParser(parser);
HttpResponse response = request.execute();
String responseStr = NetworkHelper.readResponse(response.getContent());
videoUrl = getContentLink(responseStr);
}
catch (HttpResponseException e)
{
YoutubeError error = ((YoutubeUnsuccessfulResponseHandler) request.unsuccessfulResponseHandler).errors.errors.get(0);
errorMessage = error + "";
}
catch (IOException e)
{
errorMessage = e.getMessage();
}
}
class YoutubeUnsuccessfulResponseHandler implements
HttpUnsuccessfulResponseHandler
{
YoutubeErrors errors = null;
@Override
public boolean handleResponse(HttpRequest request, HttpResponse response, boolean retrySupported) throws IOException
{
errors = response.parseAs(YoutubeErrors.class);
return false;
}
}
public class YouTubeUrl extends GoogleUrl
{
private static final boolean PRETTY_PRINT = true;
private static final String UPLOAD_URL = "https://uploads.gdata.youtube.com/feeds/api/users/default/uploads";
@Key
String author;
@Key("max-results")
Integer maxResults = 2;
YouTubeUrl(String encodedUrl, boolean json)
{
super(encodedUrl);
if (json)
this.alt = "jsonc";
this.prettyprint = PRETTY_PRINT;
}
public static GenericUrl uploadUrl()
{
return new YouTubeUrl(UPLOAD_URL, false);
}
}