当前位置: 首页 > 面试题库 >

YouTube API 3上传视频-未配置访问权限-Android

乜烨霖
2023-03-14
问题内容

我正在使用一个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。上传接口用到的所有