如何使用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里面可以看到,它配置了这个东西,用于在网页认证成功后接收的:
<activityandroid: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密钥.