本文介绍了YouTube API 3 上传视频 - 访问未配置 - Android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我正在开发一个 Android 应用程序,该应用程序可以录制视频并允许用户使用 YouTube 数据 API v3 将其直接上传到 YouTube.

I am working on an Android app that records video and allows the user to upload it directly to YouTube using the YouTube Data API v3.

我已在 Google 的 API 控制台中设置了我的应用程序.在服务下,我启用了 YouTube Data API v3.在 API 访问下,我有一个已安装应用程序的客户端 ID"部分(包括一个客户端 ID 和客户端密钥)和一个简单 API 访问"部分 ->Android 应用程序的密钥(带有证书)"(其中包括一个 API 密钥和一个Android 应用程序"部分,现在留空,即允许所有 Android 应用程序,但我已经尝试设置我的 android 密钥).

I have set up my app in Google's API console. Under services, I have YouTube Data API v3 enabled. Under API access I have both a section "Client ID for installed applications" (including a Client ID and Client Secret) and a section "Simple API Access" -> "Key for Android apps (with certificates)" (which includes an API key and an "Android Apps" section, which is left blank for now, i.e. allow all Android apps, but I have tried it with setting my android key).

我的代码基于多个地方,主要是:

I have based my code from a number of places, primarily:

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=samples

上传初始化成功,启动 AsyncTask,但随后我得到一个 IOException 抛出:

The upload initialises OK, starts the AsyncTask, but then I get an IOException thrown saying:

{
    "code": 403,
    "errors": [
        {
            "domain": "usageLimits",
            "message": "Access Not Configured",
            "reason": "accessNotConfigured"
        }
    ],
    "message": "Access Not Configured"
}

类似的 SO 帖子表明这与我的 Google API 控制台设置有关,但我找不到任何问题.有什么建议?我想知道是不是因为我没有在任何地方提供我的客户 ID 或秘密......

Similar SO posts suggest it is to do with my Google API console settings, but I can't find anything wrong. Any suggestions? I wonder if it is because I am not providing my client ID or secret anywhere ...

谢谢.

我的代码从包含视频列表的片段运行.相关部分是:

My code runs from a fragment containing a list of videos. The relevant sections are:

-- 初始化

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

-- Setup credential and youtube

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ...
        credential = googleAccountCredential(scopes);
        youtube = new YouTube.Builder(transport, jsonFactory, credential)
            .setApplicationName("MyAppName")
            .build();
        ...
    }

-- 点击按钮,开始上传

-- On button click, initiate upload

    @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);
    }

-- 从用户选择和帐户返回时--/请求授权

-- On return from the user choosing and account-- / requesting authorization

    /**
     * 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;
        }
    }

-- 根据我们掌握的信息多次调用-- 账号、授权等

-- Called multiple times depending on what information we have-- account, authorization, etc.

    /**
     * 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 the upload-- Puts everything together

    /**
     * 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 服务

-- Require Google play services

    /**
     * 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 that runs execute on the upload

    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"按钮后的设置.

The answer provided by @Ibrahim was almost correct for me. What I needed to do was edit my API configuration. However, it was not the "Simple API access" section I needed to edit, it was the settings after clicking the button "Create another client Id".

然后我可以选择已安装的应用程序"->Android".输入我的包名和 SHA1 并等待 15 分钟后,我的应用程序按预期运行.我还设置了简单 API 访问".我不确定你是否需要两者.

Then I could select "Installed application" -> "Android". After inputting my package name and SHA1, and waiting 15 minutes, my app worked as expect. I also have the "Simple API access" set up. I am not sure if you need both or not.

这篇关于YouTube API 3 上传视频 - 访问未配置 - Android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 17:39