使用youtube的api

发布时间:2023年12月18日

如何使用youtube的data api

https://console.cloud.google.com/apis/dashboard?到这个地方先启用api,找到YouTube Data API v3 这个api,启用它

然后创建凭据

去创建凭据,里面创建相应的客户端,web的需要填写redirect地址,就是回调用的.客户端不需要这个.

创建客户端不需要详细地说了,进入填写包名,这里以android为例,填写上最后打包的签名的key的sha1值就可以了,下面都提示如何拿到这个值.成功后就有了一个key

上图里面的api密钥,这个是用于访问youtube时用到的.没有就申请一个.

没有发布应用,所以我在oauth权限请求页面,添加上测试用户的邮箱.

账户申请就这些差不多了,网上有很多相关的文章.这步不会有什么错.

申请oauth时要注意什么

要注意的是包名不要有下划线这些字符,普通的字母与.号,我遇到过有下划线的,认证失败了.

web与客户端是不能通用的,有人说用web的key成功认证,这显然是不合理的.因为他用的是postman,或浏览器测试.

认证时,有哪些途径.

谷歌,自称有signin相关的按钮,直接接入.然后我就试了一下.

比如常见的代码:

GetSignInIntentRequest request =
//                GetSignInIntentRequest.builder()
//                        .setServerClientId(cliendId)
//                        .build();
//
//        Identity.getSignInClient(OauthActivity.this)
//                .getSignInIntent(request)
//                .addOnSuccessListener(
//                        result -> {
//                            try {
//                                startIntentSenderForResult(
//                                        result.getIntentSender(),
//                                        REQUEST_CODE_GOOGLE_SIGN_IN,
//                                        /* fillInIntent= */ null,
//                                        /* flagsMask= */ 0,
//                                        /* flagsValue= */ 0,
//                                        /* extraFlags= */ 0,
//                                        /* options= */ null);
//                            } catch (IntentSender.SendIntentException e) {
//                                Log.e("TAG", "Google Sign-in failed");
//                            }
//                        })
//                .addOnFailureListener(
//                        e -> {
                            Log.e("TAG", "Google Sign-in failed", e);
                        });

或者

signInRequest = BeginSignInRequest.builder()
//                .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder()
//                        .setSupported(true)
//                        .build())
//                .setGoogleIdTokenRequestOptions(BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
//                        .setSupported(true)
//                        // Your server's client ID, not your Android client ID.
//                        .setServerClientId(cliendId)
//                        .setFilterByAuthorizedAccounts(true)
//                        .build())
//                // Automatically sign in when exactly one credential is retrieved.
//                .setAutoSelectEnabled(true)
//                .build();*/

注释去了.

其实这些都是依赖于play service的.

当然依赖要配上

implementation('com.google.apis:google-api-services-youtube:v3-rev20200618-1.30.9') {
        exclude group: 'org.apache.httpcomponents'
    }
    implementation 'com.google.http-client:google-http-client-android:1.37.0'
    implementation('com.google.api-client:google-api-client-android:2.2.0') {
        exclude group: 'org.apache.httpcomponents'
    }
    implementation 'com.google.api-client:google-api-client-gson:1.30.11'
    implementation 'com.google.android.gms:play-services-auth:20.7.0'

最后会发现,这些是无效的,有些api在target<30以下还可以调用,但多数情况在target>=30已经不行了,现在谷歌的市场是要求33,所以这些都不行,没有测试过,目标机器上的Play service升级到最高版本会如何,但你无法要求客户去升级的.所以这些办法放弃.

另外,有些人会提到代码,判断服务是否正常.或返回10,或1250这些

private boolean isGooglePlayServicesAvailable() {
//        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
//        final int connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(this);
//        return connectionStatusCode == ConnectionResult.SUCCESS;
//    }
//
//    private void acquireGooglePlayServices() {
//        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
//        final int connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(this);
//        if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
//            showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
//        }
//    }
private void getResultsFromApi() {
//        if (!isGooglePlayServicesAvailable()) {
//            acquireGooglePlayServices();
//        } else if (mCredential.getSelectedAccountName() == null) {
//            chooseAccount();
//        } else if (!isDeviceOnline()) {
//            mOutputText.setText("No network connection available.");
//        } else {
//            new MakeRequestTask().execute();
//        }
//    }

这种相关的代码是从系统的登录账户中选一个.没有就登录一个,也是受限于play service的api的.至少我是没有成功,如果target=29,是可以用.但高了不行.

认证遇到的问题与解决方案

谷歌在官方的文档里面提到oauth认证的方案.开始感觉到惊喜,以前做新浪微博的时候,也是oauth2认证,结果,文档里面写到,webview已经不支持这种方式了,url拼完,它也不给你加载.

文档提到了使用app-auth库,这个库认证能成功,但有不好的体验,一个是加载浏览器慢,另一个,由于接口是先调用google的,所以国内测试比较慢,时不时还连不上.不知道在国外会不会好些.

认证过程:https://approov.io/blog/adding-oauth2-to-mobile-android-and-ios-clients-using-the-appauth-sdk 这个库,可以下载到源码.

认证步骤与ui展示,如果自己觉得不好看可以修改

最重要的就剩下配置文件了.

{
  "client_id": "17240232499-.apps.googleusercontent.com",
  "redirect_uri": "com.arch.youtube.demo:/oauth2redirect",
  "end_session_redirect_uri": "com.arch.youtube.demo:/oauth2redirect",
  "authorization_scope": "openid email profile https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.force-ssl",
  "discovery_uri": "https://accounts.google.com/.well-known/openid-configuration",
  "authorization_endpoint_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_endpoint_uri": "https://oauth2.googleapis.com/token",
  "registration_endpoint_uri": "https://www.googleapis.com/oauth2/v3/userinfo",
  "user_info_endpoint_uri": "",
  "https_required": true
}

scope要填写上youtube 上要用的.

redirect_uri这个要注意的是包名加上后面的部分,后面是随意的.从app-auth里面可以看到,它配置了这个东西,用于在网页认证成功后接收的:
<activity
            android:name=".RedirectUriReceiverActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="${appAuthRedirectScheme}" />
            </intent-filter>
        </activity>

所以要在build.gradle:android{}里面加上

manifestPlaceholders = [
        'appAuthRedirectScheme': 'com.arch.youtube.demo'
]
discovery_uri这是要配置的,有它,可以不用user_info_endpoint_uri,国内就是访问这个地址比较慢.
client_id填写上面申请的oauth的客户端id就可以了.

配置文件的核心点在于,先访问discovery_uri,然后剩下的逻辑是它读取配置文件,然后拼接一下认证的地址,然后打开浏览器去认证,在手机上会打开外部浏览器去加载.

https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=com.arch.youtube.demo:/oauth2redirect&client_id=17240232499-.apps.googleusercontent.com&response_type=code&state=G2DGez5QTA4qhc9Ik_80Dw&nonce=77sOq_FlX2qLQJTkjUVgTg&scope=openid email profile&code_challenge=wOTi0Ysfs8rr4kAf5s5mJOo97AOWC2eBv-kKaXsy8VY&code_challenge_method=S256

我抓取它最后访问的结果大概是这样的.

关于youtube的api,调用的方式就简单了,上面的gradle依赖加上,就可以直接用了

HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        instance.mYoutube = new YouTube.Builder(
                transport, jsonFactory, credential)
                .setApplicationName(context.getResources().getString(R.string.app_name))
                .build();

这样就完成了api的初始化,如果没有账户信息,那么搜索这些是不可用的

YouTube.Search.List search = YoutubeApiHolder.instance.mYoutube.search().list(Collections.singletonList("id,snippet"));

                search.setQ(searchText)
                        .setKey(ApiConfig.YOUTUBE_API_KEY)
                        .setType(Collections.singletonList(mTypeOptions))
                        .setOrder(mSortingOptions)
                        .setVideoDuration(mDurationOptions)
                        .setVideoDefinition(mFeatureOptions)
                        .setPageToken(nextPageToken)
                        .setFields("nextPageToken,items(id,snippet(channelId,title,description,thumbnails/default))")
                        .setMaxResults(15L);

                SearchListResponse searchResponse = search.execute();
                nextPageToken = searchResponse.getNextPageToken();
                emitter.onNext(searchResponse);

密钥在调用的时候设置上就可以了.是上面的api密钥,不是oauth密钥.

文章来源:https://blog.csdn.net/archko/article/details/135067103
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。