我正在使用一个Android应用程序来录制视频,并允许用户使用YouTube数据API v3将其直接上传到YouTube。
我已经在Google的API控制台中设置了我的应用。在服务下,我启用了YouTube数据API
v3。在API访问下,我有一个“已安装应用程序的客户端ID”部分(包括一个客户端ID和客户端密钥)和一个“简单API访问”部分->“
Android应用程序的密钥(带有证书)”(其中包括一个API密钥)和“
Android应用程序”部分,该部分暂时留空,即允许所有Android应用程序,但我已尝试通过设置android密钥来进行尝试)。
我的代码来自很多地方,主要是:
https://developers.google.com/youtube/v3/code_samples/java#upload_a_video
和
https://code.google.com/p/google-api-java-client/source/browse/tasks-android-
sample/src/main/java/com/google/api/services/samples/tasks/android/
TasksSample.java?repo=样本
上载初始化确定,启动AsyncTask,但是随后我抛出IOException:
{
"code": 403,
"errors": [
{
"domain": "usageLimits",
"message": "Access Not Configured",
"reason": "accessNotConfigured"
}
],
"message": "Access Not Configured"
}
类似的SO帖子建议这与我的Google
API控制台设置有关,但我找不到任何错误。有什么建议?我想知道是否是因为我没有在任何地方提供我的客户ID或机密信息…
谢谢。
我的代码从包含视频列表的片段中运行。相关部分是:
- 在里面
public class UploadFragment extends Fragment {
private static GoogleAccountCredential credential;
private static final HttpTransport transport = AndroidHttp.newCompatibleTransport();
private static final JsonFactory jsonFactory = new GsonFactory();
public YouTube youtube;
List<String> scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_UPLOAD);
private static String VIDEO_FILE_FORMAT = "video/*";
static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
static final int REQUEST_AUTHORIZATION = 1;
static final int REQUEST_ACCOUNT_PICKER = 2;
-设置凭据和YouTube
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
credential = googleAccountCredential(scopes);
youtube = new YouTube.Builder(transport, jsonFactory, credential)
.setApplicationName("MyAppName")
.build();
...
}
-单击按钮即可启动上传
@Override void onClick(View v) {
...
if (hasGooglePlayServices()) {
uploadYouTubeVideos();
...
}
-建立凭证
/**
* Get the credential to authorize the installed application to access user's protected data.
*
* @param scopes list of scopes needed to run YouTube upload.
*/
private static GoogleAccountCredential googleAccountCredential(List<String> scopes) throws Exception {
credential = GoogleAccountCredential.usingOAuth2(context, scopes)
.setSelectedAccountName(PreferenceManager.getAccountName());
return credential;
}
-向用户请求一个帐户
/**
* Fire intent to get user to choose account
* Return to onActivityResult
*/
private void chooseAccount() {
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
-从用户选择和帐户返回时-/请求授权
/**
* Returns from chooseAccount and from request authorization
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
uploadYouTubeVideos();
} else {
chooseAccount();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
PreferenceManager.setAccountName(accountName);
uploadYouTubeVideos();
}
}
break;
}
}
-根据我们拥有的信息(帐户,授权等)多次调用
/**
* Uploads user selected video to the user's YouTube account using OAuth2
* for authentication.
*
* @param videoFile file to be uploaded
*/
public void uploadYouTubeVideos() {
if (credential.getSelectedAccountName() == null) {
chooseAccount();
} else {
File videoFile = getVideoFile();
Insert videoInsert = prepareUpload(videoFile);
new VideoUploadAsyncTask().execute(videoInsert);
}
}
-准备上传-将所有内容放在一起
/**
* Prepare upload. Just leaves execute to be run in AsyncTask.
*
* @param videoFile file to be uploaded
* @return
*/
public Insert prepareUpload( File videoFile ) {
try {
// Add extra information to the video before uploading.
Video videoObjectDefiningMetadata = new Video();
// Set the video to public (default).
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
// We set a majority of the metadata with the VideoSnippet object.
VideoSnippet snippet = new VideoSnippet();
// Video file name.
snippet.setTitle(videoFile.getName());
snippet.setDescription("Test description");
// Set keywords.
List<String> tags = new ArrayList<String>();
tags.add("test");
snippet.setTags(tags);
// Set completed snippet to the video object.
videoObjectDefiningMetadata.setSnippet(snippet);
InputStreamContent mediaContent = new InputStreamContent(
VIDEO_FILE_FORMAT, new BufferedInputStream(new FileInputStream(videoFile)));
mediaContent.setLength(videoFile.length());
/*
* The upload command includes: 1. Information we want returned after file is successfully
* uploaded. 2. Metadata we want associated with the uploaded video. 3. Video file itself.
*/
YouTube.Videos.Insert videoInsert = youtube.videos()
.insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);
// Set the upload type and add event listener.
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
/*
* Sets whether direct media upload is enabled or disabled. True = whole media content is
* uploaded in a single request. False (default) = resumable media upload protocol to upload
* in data chunks.
*/
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
Log.d(TAG, "Upload file: Initiation Started");
break;
case INITIATION_COMPLETE:
Log.d(TAG, "Upload file: Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
Log.d(TAG, "Upload file: Upload in progress");
Log.d(TAG, "Upload file: Upload percentage: " + uploader.getProgress());
break;
case MEDIA_COMPLETE:
Log.d(TAG, "Upload file: Upload Completed!");
break;
case NOT_STARTED:
Log.d(TAG, "Upload file: Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
return videoInsert;
} catch (FileNotFoundException e) {
Log.e(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
return null;
}
}
-需要Google Play服务
/**
* Pop up dialog requesting user to download Google Play Services.
* Returns to onActivityResult
*/
void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(connectionStatusCode, getActivity(),
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
});
}
-运行的AsyncTask在上载时执行
public class VideoUploadAsyncTask extends AsyncTask<Insert, Void, Void> {
@Override
protected Void doInBackground( Insert... inserts ) {
Insert videoInsert = inserts[0];
try {
Video returnVideo = videoInsert.execute();
} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
showGooglePlayServicesAvailabilityErrorDialog(
availabilityException.getConnectionStatusCode());
} catch (UserRecoverableAuthIOException userRecoverableException) {
startActivityForResult(
userRecoverableException.getIntent(), UploadFragment.REQUEST_AUTHORIZATION);
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
}
return null;
}
}
}
@Ibrahim提供的答案对我来说几乎是正确的。我需要做的是编辑我的API配置。但是,这不是我需要编辑的“简单API访问”部分,而是单击“创建另一个客户端ID”按钮后的设置。
然后,我可以选择“已安装的应用程序”->“
Android”。输入我的软件包名称和SHA1,并等待15分钟后,我的应用程序按预期工作。我还设置了“简单API访问”。我不确定是否需要两者。
我正在开发一个应用程序,集成W/Facebook发布视频,然后显示在我们的应用程序之外的FB。 我们有一个应用程序的脸书页面,通过FB Graph API(PHP)上传/发布到FB页面的流/时间线/专辑工作得很好,因为它上传视频,将隐私设置为公共,并将一个故事发布到时间线。(我已经通过应用程序的测试用户测试了非页面管理员发帖。一切顺利。) 目前,如果我发布到我自己的个人资料(使用发布请求到/me/
接口说明 上传视频文件 API地址 POST /api/marker/1.0.0/uploadVideo 是否需要登录 是 请求字段说明 参数 类型 请求类型 是否必须 说明 dataGuid string form 是 场景GUID file string form 是 视频文件 响应字段说明 参数 类型 说明 mp4UploadPath String 视频文件上传地址 响应成功示例 { "
用户通过视频上传、管理视频、获取代码,实现本地视频在制定网站播放。 2.1视频上传 进入视频页面,点击上传视频 按钮,在弹出的页面点击添加视频 : 1)选择视频“分类”,添加视频“标签”(选填); 2)点击【添加视频】或者【选择文件并上传】按钮选择本地一个或多个视频,点击确认即开始视频上传;或者在本地选择一个或多个视频,将视频拖拽到视频上传区,即可进行视频上传; 3)上传过程中点击视频上传或者取消
我需要一点指导如何设置我的S3桶策略和/或IAM权限配置文件。我们的Rails应用程序将文件上传到桶中,并在上传后显示文档的链接。基本上,我想启用阻止所有公共访问,因为它是安全的,但从内Rails应用程序文档应该能够上传和打开时,点击一个链接。因此,我创建了一个具有以下权限配置文件的IAM用户: 然后我添加了一个桶策略,如下所示: 对于,我想我是说:这个用户可以在这个bucket上做任何事情吗?这
用于执行登录 Sharding Proxy 的权限验证。 配置用户名、密码、可访问的数据库后,必须使用正确的用户名、密码才可登录。 rules: - !AUTHORITY users: - root@localhost:root # <username>@<hostname>:<password> - sharding@:sharding provid
Spark API 中所有的 Flash 接口需要 Flash 插件的版本在 10.1 以上才有效,使用前请确保 Flash 插件版本符合要求。 在上传视频的过程中,不用与 Spark 平台进行 HTTP 通信,使用 JavaScript 和 Spark 平台提供的 Flash 进行交互即可完成。关于如何在网页中嵌入 Flash 以及如何和 Flash 进行交互,请参阅附录 2。上传接口用到的所有