看了下網(wǎng)上關(guān)于集成Youtube視頻開發(fā)的文章不是很多捐顷,
所以今天把我開發(fā)中所遇到的問題和實(shí)現(xiàn)代碼分享給大家。
應(yīng)用運(yùn)行環(huán)境:AndroidTV端雨效、Android手機(jī)端
https://developers.google.com/youtube/iframe_api_reference(YouTube開發(fā)者專區(qū))![](https://img-blog.csdnimg.cn/20190718102141212.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Ymox,size_16,color_FFFFFF,t_70)
這是開發(fā)者專區(qū)中的入口迅涮,上邊這句話的意思是,使用嵌入式播放器在您的應(yīng)用中播放視頻徽龟,并自定義播放體驗(yàn)叮姑。
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190718102517110.png)
點(diǎn)進(jìn)來可以看到他提供了Android、IOS据悔、和IFrame(html)三種Api,因?yàn)橹皇窃贏ndroid設(shè)備上運(yùn)行传透,所以只講Android和IFrame
這兩種,先說一下這AndroidAPI和IFrameApi的區(qū)別屠尊,
? 1旷祸、AndroidAPI
如果想播放YouTube視頻,Android設(shè)備上必須有YouTube的應(yīng)用讼昆,優(yōu)點(diǎn)是開發(fā)快、適配性比較好。
? 2浸赫、IFrameAPI
基于瀏覽器內(nèi)核闰围,有些設(shè)備使用會(huì)有問題,好處是不用YouTube應(yīng)用的支持既峡,可以直接播放羡榴,缺點(diǎn)是需要跨平臺(tái)開發(fā),步驟繁瑣运敢,適配性比較差.
![在這里插入圖片描述](https://img-blog.csdnimg.cn/2019071810454856.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Ymox,size_16,color_FFFFFF,t_70)
基本上國外Android設(shè)備上都會(huì)自帶YouTube應(yīng)用校仑,但是我負(fù)責(zé)的項(xiàng)目在AndroidTV端運(yùn)行,
Android盒子更新比較慢传惠,YouTube對(duì)2012年以前的智能電視不再提供支持迄沫,所以項(xiàng)目開發(fā)中我選擇了IFrameAPI的方式。
所以就先講IFrameApi的方式卦方。
**IFrameAPI**
? Android端需要做的有兩件事
? 1羊瘩、Android通過webview調(diào)用html,在接口中傳入YouTube視頻的id盼砍、以及視頻的寬高 尘吗。
? 如何獲取視頻id?
? 訪問Youtube的網(wǎng)站浇坐,當(dāng)前播放視頻地址欄v后面的就是視頻id睬捶,如:
? https://www.youtube.com/watch?v=1xRjMEIzn48
? 2、通過Android的遙控器監(jiān)聽事件調(diào)用html中的方式控制視頻的播放近刘、暫停侧戴、快進(jìn)、快退功能跌宛。
? android代碼
**MainActivity**
? ```javascript
package com.example.administrator.intelchange;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
? ? private static final String TAG = "MainActivity";
? ? WebView wv_common_webview;
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? DisplayMetrics outMetrics = new DisplayMetrics();
? ? ? ? getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
? ? ? ? int widthPixels = outMetrics.widthPixels;
? ? ? ? int heightPixels = outMetrics.heightPixels;
? ? ? ? wv_common_webview = (WebView) findViewById(R.id.webview);
? ? ? ? String id="_vw0dH3ic4A";
? ? ? ? //調(diào)用本地html
? ? ? ? //wv_common_webview.loadUrl("file:///android_asset/111.html");
? ? ? //調(diào)用服務(wù)端html
? ? ? ? wv_common_webview.loadUrl("http://ott.bangtv.tv/yt/play.html?v="+id+"&w="+widthPixels*0.75+"&h="+heightPixels*0.75);
? ? ? ? //加上下面這段代碼可以使網(wǎng)頁中的鏈接不以瀏覽器的方式打開
? ? ? ? wv_common_webview.setWebViewClient(new WebViewClient());
? ? ? ? //得到webview設(shè)置
? ? ? ? WebSettings webSettings = wv_common_webview.getSettings();
? ? ? ? //允許使用javascript
? ? ? ? webSettings.setJavaScriptEnabled(true);
? ? ? ? webSettings.setUseWideViewPort(true);
? ? ? ? webSettings.setLoadWithOverviewMode(true);
? ? ? ? wv_common_webview.getSettings().setBuiltInZoomControls(true);
? ? ? ? wv_common_webview.getSettings().setUseWideViewPort(true);
? ? ? ? wv_common_webview.getSettings().setLoadWithOverviewMode(true);
? ? ? ? wv_common_webview.getSettings().setTextZoom(100);
? ? ? ? wv_common_webview.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
? ? ? ? // 如果頁面中鏈接酗宋,如果希望點(diǎn)擊鏈接繼續(xù)在當(dāng)前browser中響應(yīng),
? ? ? ? ? ? ? ? // 而不是新開Android的系統(tǒng)browser中響應(yīng)該鏈接疆拘,必須覆蓋webview的WebViewClient對(duì)象
? ? ? ? ? ? ? ? wv_common_webview.setWebViewClient(new WebViewClient() {
? ? ? ? ? ? ? ? ? ? public boolean shouldOverrideUrlLoading(WebView view, String url) {
? ? ? ? ? ? ? ? ? ? ? ? //? 重寫此方法表明點(diǎn)擊網(wǎng)頁里面的鏈接還是在當(dāng)前的webview里跳轉(zhuǎn)蜕猫,不跳到瀏覽器那邊
? ? ? ? ? ? ? ? ? ? ? ? view.loadUrl(url);
? ? ? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? });
? ? }
? ? //調(diào)用html中的方法,傳入按鍵狀態(tài)
? ? @SuppressLint("SetJavaScriptEnabled")
? ? public void testJS(int keycode,String key) {
? ? ? ? if (keycode == KeyEvent.KEYCODE_DPAD_LEFT) {
? ? ? ? ? ? wv_common_webview.loadUrl("javascript:operation( "+KeyEvent.KEYCODE_DPAD_LEFT+","+key+")");
? ? ? ? }else if(keycode == KeyEvent.KEYCODE_DPAD_RIGHT){
? ? ? ? ? ? wv_common_webview.loadUrl("javascript:operation( "+KeyEvent.KEYCODE_DPAD_RIGHT+","+key+")");
? ? ? ? }
? ? ? ? else if(keycode == KeyEvent.KEYCODE_DPAD_UP){
? ? ? ? ? ? wv_common_webview.loadUrl("javascript:operation( "+KeyEvent.KEYCODE_DPAD_UP+","+key+")");
? ? ? ? }else if(keycode == KeyEvent.KEYCODE_DPAD_DOWN){
? ? ? ? ? ? wv_common_webview.loadUrl("javascript:operation( "+KeyEvent.KEYCODE_DPAD_DOWN+","+key+")");
? ? ? ? }
? ? ? ? else if(keycode == KeyEvent.KEYCODE_DPAD_CENTER){
? ? ? ? ? ? wv_common_webview.loadUrl("javascript:operation( "+KeyEvent.KEYCODE_DPAD_CENTER+","+key+")");
? ? ? ? }
? ? }
//
? ? /**
? ? * 監(jiān)聽遙控器按鍵事件
? ? */
? ? @Override
? ? public boolean dispatchKeyEvent(KeyEvent event) {
? ? ? ? // TODO Auto-generated method stub
? ? ? ? //? ? ? ? if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT
//? ? ? ? ? ? ? ? | event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP
//? ? ? ? ? ? ? ? | event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT
//? ? ? ? ? ? ? ? | event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN‘’
//? ? ? ? ? ? ? ? ? | event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_CENTER
//? ? ? ? ? ? ? ? ? && event.getAction() == KeyEvent.ACTION_DOWN) {
//? ? ? ? ? ? testJS(event.getKeyCode(),"0");
//
//? ? ? ? }
//? ? ? ? if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT
//? ? ? ? ? ? ? ? | event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP
//? ? ? ? ? ? ? ? |event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT
//? ? ? ? ? ? ? ? | event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN
//? ? ? ? ? ? ? ? &&event.getAction() == KeyEvent.ACTION_UP) {
//? ? ? ? ? ? testJS(event.getKeyCode(),"1");
//
//? ? ? ? }
? ? ? ? //按鍵按下時(shí)傳參數(shù)給html哎迄,”0“為按下回右,”1“為按鍵抬起
? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_LEFT&&event.getAction() == KeyEvent.ACTION_DOWN ){
? ? ? ? ? ? testJS(event.getKeyCode(),"0");
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了左鍵",0.LENGTH_SHORT).show();
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_LEFT&& event.getAction() == KeyEvent.ACTION_UP){
? ? ? ? ? ? testJS(event.getKeyCode(),"1");
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了左鍵",Toast.LENGTH_SHORT).show();
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_RIGHT&&event.getAction() == KeyEvent.ACTION_DOWN){
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了右鍵",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? testJS(event.getKeyCode(),"0");
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_RIGHT&&event.getAction() == KeyEvent.ACTION_UP){
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了右鍵",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? testJS(event.getKeyCode(),"1");
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_UP&&event.getAction() == KeyEvent.ACTION_DOWN){
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了上鍵",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? testJS(event.getKeyCode(),"0");
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_UP&&event.getAction() == KeyEvent.ACTION_UP){
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了上鍵",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? testJS(event.getKeyCode(),"1");
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_DOWN&&event.getAction() == KeyEvent.ACTION_DOWN){
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了下鍵",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? testJS(event.getKeyCode(),"0");
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_DOWN&&event.getAction() == KeyEvent.ACTION_UP){
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了下鍵",Toast.LENGTH_SHORT).show();
? ? ? ? ? ? testJS(event.getKeyCode(),"1");
? ? ? ? }
? ? ? ? if(event.getKeyCode()? == KeyEvent.KEYCODE_DPAD_CENTER&& event.getAction() != KeyEvent.ACTION_UP){
? ? ? ? ? ? testJS(event.getKeyCode(),"0");
//? ? ? ? ? ? Toast.makeText(this,"點(diǎn)擊了確定鍵",Toast.LENGTH_SHORT).show();
? ? ? ? }
? ? ? ? ? if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
? ? ? ? ? ? this.finish();
? ? ? ? ? }
? ? ? ? return true;
? ? }
}
```
```javascript
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? android:orientation="vertical">
? ? <WebView
? ? ? ? android:id="@+id/webview"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="match_parent"></WebView>
</LinearLayout>
```
**html代碼**
urlhelper.js
```javascript
/**
* 獲取url參數(shù)
* @param {string} name
*/
function getQueryString(name){
? ? var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
? ? var r = window.location.search.substr(1).match(reg);
? ? if(r!=null)return? unescape(r[2]); return null;
}
```
player.html
```javascript
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>play</title>
? ? <style>*,body,html,div,p,img{border:0;margin:0;padding:0;}</style>
</head>
<body>
? ? ? ? <div id="show"></div>
? ? ? ? <div id="showup"></div>
? ? ? ? <div id="player"></div>
? ? ? ? <script src="./urlhelper.js"></script>
? ? ? ? <script>
? ? ? ? ? //獲取視頻ID
? ? ? ? ? var vid = getQueryString("v");
? ? ? ? ? var w = parseInt(getQueryString("w"));
? ? ? ? ? var h =? parseInt(getQueryString("h"));
? ? ? ? ? // document.getElementById('show').innerHTML=w+ '? '+ h;
? ? ? ? ? //初始化播放器
? ? ? ? ? var tag = document.createElement('script');
? ? ? ? ? tag.src = "https://www.youtube.com/iframe_api";
? ? ? ? ? var firstScriptTag = document.getElementsByTagName('script')[0];
? ? ? ? ? firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
? ? ? ? ? var player;
? ? ? ? ? var duration = 0;
? ? ? ? ? function onYouTubeIframeAPIReady() {
? ? ? ? ? ? player = new YT.Player('player', {
? ? ? ? ? ? ? height: 360,
? ? ? ? ? ? ? width: 640,
? ? ? ? ? ? ? videoId: vid,
? ? ? ? ? ? ? events: {
? ? ? ? ? ? ? ? 'onReady': onPlayerReady,
? ? ? ? ? ? ? ? 'onStateChange': onPlayerStateChange
? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? ? }
? ? ? ? ? function onPlayerReady(event) {
? ? ? ? ? ? duration = player.getDuration();
? ? ? ? ? ? // var fr = player.getIframe();
? ? ? ? ? ? event.target.playVideo();
? ? ? ? ? }
? ? ? ? ? //全局視頻信息
? ? ? ? ? var state; //視頻播放狀態(tài)
? ? ? ? ? var keyCode=-1; //對(duì)應(yīng)按鍵
? ? ? ? ? var keyEv=-1; //事件
? ? ? ? ? var optime = 0; //時(shí)間點(diǎn)
? ? ? ? ? //按鍵
? ? ? ? ? var keyCodeLeft = 21;
? ? ? ? ? var keyCodeRight = 22;
? ? ? ? ? var keyCodeOk = 23;
? ? ? ? ? var keyCodeUp = 24;
? ? ? ? ? var keyCodeDown = 25;
? ? ? ? ? //事件
? ? ? ? ? var keyEvDown = 0;
? ? ? ? ? var keyEvUp = 1;
? ? ? ? ? function onPlayerStateChange(event) {
? ? ? ? ? ? state = event.data;
? ? ? ? ? }
? ? ? ? ? //操作 keycode按鍵 ev事件 0-按下 1-抬起
? ? ? ? ? function operation(keycode, ev){
? ? ? ? ? ? switch(keycode){
? ? ? ? ? ? ? case keyCodeLeft:
? ? ? ? ? ? ? ? left(ev);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? case keyCodeRight:
? ? ? ? ? ? ? ? right(ev);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? case keyCodeOk:
? ? ? ? ? ? ? ? ok(ev);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? case keyCodeUp:
? ? ? ? ? ? ? ? up(ev);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? case keyCodeDown:
? ? ? ? ? ? ? ? down(ev);
? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? ? //ok鍵
? ? ? ? ? function ok(ev){
? ? ? ? ? ? state == YT.PlayerState.PLAYING?player.pauseVideo():player.playVideo();
? ? ? ? ? }
? ? ? ? ? //右鍵
? ? ? ? ? function right(ev){
? ? ? ? ? ? if(ev){
? ? ? ? ? ? }else{
? ? ? ? ? ? ? //計(jì)算時(shí)間,重新加載
? ? ? ? ? ? ? var ctime = player.getCurrentTime();
? ? ? ? ? ? ? ctime += 5;
? ? ? ? ? ? ? ctime = ctime<duration?ctime:duration;
? ? ? ? ? ? ? player.seekTo(ctime, true);
? ? ? ? ? ? }
? ? ? ? ? ? // if(ev){
? ? ? ? ? ? //? //定位
? ? ? ? ? ? //? document.getElementById('showup').innerHTML = optime+ '? 11111';
? ? ? ? ? ? //? optime = optime<duration?optime:duration;
? ? ? ? ? ? //? player.seekTo(optime, true);
? ? ? ? ? ? //? optime = 0;
? ? ? ? ? ? //? // keyEv = -1;
? ? ? ? ? ? // }else{
? ? ? ? ? ? //? if(optime == 0){
? ? ? ? ? ? //? ? optime = player.getCurrentTime();
? ? ? ? ? ? //? }
? ? ? ? ? ? //? optime += 5;
? ? ? ? ? ? // }
? ? ? ? ? }
? ? ? ? ? //左鍵
? ? ? ? ? function left(ev){
? ? ? ? ? ? if(ev){
? ? ? ? ? ? }else{
? ? ? ? ? ? ? //計(jì)算時(shí)間漱挚,重新加載
? ? ? ? ? ? ? var ctime = player.getCurrentTime();
? ? ? ? ? ? ? ctime -= 5;
? ? ? ? ? ? ? ctime = ctime>0?ctime:0;
? ? ? ? ? ? ? player.seekTo(ctime, true);
? ? ? ? ? ? }
? ? ? ? ? ? // if(ev){
? ? ? ? ? ? //? //定位
? ? ? ? ? ? //? optime = optime>0?optime:0;
? ? ? ? ? ? //? player.seekTo(optime, true);
? ? ? ? ? ? //? optime = 0;
? ? ? ? ? ? // }else{
? ? ? ? ? ? //? if(optime == 0){
? ? ? ? ? ? //? ? optime = player.getCurrentTime();
? ? ? ? ? ? //? }
? ? ? ? ? ? //? optime -= 5;
? ? ? ? ? ? // }
? ? ? ? ? }
? ? ? ? ? //向上
? ? ? ? ? function up(){}
? ? ? ? ? //向下
? ? ? ? ? function down(){}
? ? ? ? </script>
</body>
</html>
```
**AndroidAPI**
要運(yùn)行AndroidAPi的Youtube視頻翔烁,需要:
1、Android Studio SDK 1.2或更高版本旨涝。
2蹬屹、適用 于API 23或更高版本的Android SDK包,包括最新版本的Google Repository,Android支持庫和Google Play服務(wù)慨默。
3贩耐、在您的測試設(shè)備上訪問互聯(lián)網(wǎng)。
4厦取、Google帳戶潮太。
開發(fā)前,需要在google注冊(cè)您的應(yīng)用虾攻,包括你的數(shù)字簽名和證書铡买。
1、進(jìn)入google[開發(fā)控制臺(tái)](https://console.developers.google.com/)霎箍,
2奇钞、創(chuàng)建一個(gè)新項(xiàng)目。我的是ALXYoutubePlayer朋沮。
3蛇券、在該項(xiàng)目中創(chuàng)建后出現(xiàn)的頁面上,展開API和驗(yàn)證左側(cè)邊欄樊拓,單擊的API纠亚。在API的列表,點(diǎn)擊YouTube數(shù)據(jù)API并啟用
YouTube數(shù)據(jù)API V3后面的頁面上筋夏。
在左側(cè)邊欄蒂胞,選擇證書。對(duì)于資格證書条篷,API支持的OAuth 2.0骗随,使用服務(wù)帳戶的API密鑰和。我們將使用API密鑰選項(xiàng)赴叹。
選擇API密鑰從添加憑據(jù)下拉菜單鸿染。會(huì)顯示一個(gè)彈出讓你指定密鑰類型。選擇Android的關(guān)鍵乞巧。接下來選擇添加包名和指紋涨椒,并添
加Android應(yīng)用程序的包名(我的是vc.zz.qduxsh.alxyoutubeplayer),然后在終端中運(yùn)行以下命令來獲取SHA-1證書指紋绽媒。
keytool -list -v -keystore ~/.android/debug.keystore‘’
輸入的android系統(tǒng)提示時(shí)作為密碼蚕冬。上位于調(diào)試密鑰庫上面的命令打印資料?/ .android / debug.keystore您的計(jì)算機(jī)上。這是通
過Eclipse中或Android工作室當(dāng)你第一次建立了一個(gè)Android應(yīng)用程序自動(dòng)生成的是辕。在終端方面囤热,你會(huì)看到MD5和SHA-1證書指
紋。復(fù)制SHA-1指紋获三,并將其粘貼在谷歌開發(fā)者控制臺(tái)旁蔼,然后點(diǎn)擊創(chuàng)建按鈕锨苏。API密鑰將會(huì)產(chǎn)生。稍后我們將使用此牌芋。
在Andropid項(xiàng)目中蚓炬,創(chuàng)建一個(gè)名為類Config.java并粘貼以下松逊。
```javascript
package vc.zz.qduxsh.alxyoutubeplayer;
/**
* Created by gzj? on 7/15/19.
*/
public final class Config {
? ? private Config() {
? ? }
? ? public static final String YOUTUBE_API_KEY = "YOUR API KEY";
}
```
然后一個(gè)下載的最新版本的Android版YouTube播放器API的躺屁。下載完成后放到libs目錄下,右鍵--》add as library
地址:https://developers.google.com/youtube/android/player/downloads/
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20190718153344955.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0d5Ymox,size_16,color_FFFFFF,t_70)
在build.gradle中加入
compile files('libs/YouTubeAndroidPlayerApi.jar')
activity_youtube.xml
```javascript
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? tools:context=".MainActivity">
? ? <com.google.android.youtube.player.YouTubePlayerView
? ? ? ? android:id="@+id/youtube_view"
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="wrap_content"/>
</RelativeLayout>
```
MainActivity.java
```javascript
package vc.zz.qduxsh.alxyoutubeplayer;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
import vc.zz.qduxsh.alxyoutubeplayer.player.YoutubePlayerView;
public class MainActivity extends AppCompatActivity {
? ? private List<YoutubePlayerView> playerViewList;//一個(gè)頁面可以播放多個(gè)視頻经宏,將所有的播放控件收集到這里進(jìn)行維護(hù)犀暑,主要是控制離開頁面時(shí)候的暫停
? ? //定位到y(tǒng)outube的某個(gè)視頻有三種方式
? ? public static final String VideoUrl_normal = "https://www.youtube.com/watch?v=PFKutKoYX7E";//這種是最普通的寫在地址欄中的視頻地址
? ? private View mVideoProgressView;
? ? private View mCustomView;//全屏顯示的View
? ? private View mVideoFullScreenBack;
? ? private LinearLayout ll_player_container;
? ? private int mOriginalSystemUiVisibility;
? ? private int mOriginalOrientation;
? ? private WebChromeClient.CustomViewCallback mCustomViewCallback;
? ? Button btnWebview;
? ? Button btnvideo;
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? btnWebview = (Button) findViewById(R.id.btn_webview);
? ? ? ? btnvideo = (Button) findViewById(R.id.btn_videoview);
? ? ? ? btnWebview.setOnClickListener(new View.OnClickListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onClick(View view) {
? ? ? ? ? ? ? ? String videoUrl = VideoUrl_normal;
? ? ? ? ? ? ? ? String videoID = YoutubePlayerView.parseIDfromVideoUrl(videoUrl);
? ? ? ? ? ? ? ? Log.i("Alex","視頻的ID是=="+videoID);
? ? ? ? ? ? ? ? View youtubeView = LayoutInflater.from(MainActivity.this).inflate(R.layout.layout_youtube_player, null);
? ? ? ? ? ? ? ? YoutubePlayerView youtubePlayerView = (YoutubePlayerView) youtubeView.findViewById(R.id.youtubePlayerView);
? ? ? ? ? ? ? ? youtubePlayerView.setAutoPlayerHeight(MainActivity.this);
? ? ? ? ? ? ? ? youtubePlayerView.initialize(videoID, new YoutubePlayerCallBack(youtubePlayerView), mWebChromeClient);
? ? ? ? ? ? ? ? mVideoFullScreenBack = findViewById(R.id.detail_video_back);
? ? ? ? ? ? ? ? if(playerViewList == null){
? ? ? ? ? ? ? ? ? ? playerViewList = new ArrayList<>();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ll_player_container = (LinearLayout) findViewById(R.id.ll_player_container);
? ? ? ? ? ? ? ? ll_player_container.addView(youtubeView);
? ? ? ? ? ? ? ? playerViewList.add(youtubePlayerView);
? ? ? ? ? ? ? ? youtubePlayerView.seekToMillis(80000);
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? btnvideo.setOnClickListener(new View.OnClickListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onClick(View view) {
? ? ? ? ? ? ? ? Intent intent = new Intent(MainActivity.this,YoutubeActivity.class);
? ? ? ? ? ? ? ? startActivity(intent);
? ? ? ? ? ? }
? ? ? ? });
? ? }
? ? @Override
? ? protected void onStart() {
? ? ? ? super.onStart();
? ? }
? ? private class YoutubePlayerCallBack implements YoutubePlayerView.YouTubeListener {
? ? ? ? private YoutubePlayerView mYoutubeView;
? ? ? ? YoutubePlayerCallBack(YoutubePlayerView view){
? ? ? ? ? ? this.mYoutubeView = view;
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onReady() {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onStateChange(YoutubePlayerView.STATE state) {
? ? ? ? ? ? if(state == YoutubePlayerView.STATE.PLAYING && mYoutubeView!=null){
? ? ? ? ? ? ? ? if(playerViewList!=null){
? ? ? ? ? ? ? ? ? ? for(YoutubePlayerView v : playerViewList){
? ? ? ? ? ? ? ? ? ? ? ? if (v != null && v != mYoutubeView && (v.getPlayerState() == YoutubePlayerView.STATE.PLAYING ||
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? v.getPlayerState() == YoutubePlayerView.STATE.PAUSED)) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? v.stop();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onPlaybackQualityChange(String arg) {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onPlaybackRateChange(String arg) {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onError(String arg) {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onApiChange(String arg) {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onCurrentSecond(double second) {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onDuration(double duration) {
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void logs(String log) {
? ? ? ? }
? ? }
? ? /**
? ? * 用于全屏顯示的代碼
? ? */
? ? private WebChromeClient mWebChromeClient = new WebChromeClient(){
? ? ? ? @Override
? ? ? ? public View getVideoLoadingProgressView() {
? ? ? ? ? ? if (mVideoProgressView == null) {
? ? ? ? ? ? ? ? LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
? ? ? ? ? ? ? ? mVideoProgressView = inflater.inflate(R.layout.video_layout_loading, null);
? ? ? ? ? ? }
? ? ? ? ? ? return mVideoProgressView;
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
? ? ? ? ? ? // if a view already exists then immediately terminate the new one
? ? ? ? ? ? if (mCustomView != null) {
? ? ? ? ? ? ? ? onHideCustomView();
? ? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? ? ? // 1. Stash the current state
? ? ? ? ? ? mCustomView = view;
? ? ? ? ? ? mOriginalSystemUiVisibility = MainActivity.this.getWindow().getDecorView().getSystemUiVisibility();
? ? ? ? ? ? mOriginalOrientation = MainActivity.this.getRequestedOrientation();
? ? ? ? ? ? Log.i("Alex","原來的屏幕方向是"+mOriginalOrientation);
? ? ? ? ? ? // 2. Stash the custom view callback
? ? ? ? ? ? mCustomViewCallback = callback;
? ? ? ? ? ? // 3. Add the custom view to the view hierarchy
? ? ? ? ? ? FrameLayout decor = (FrameLayout) MainActivity.this.getWindow().getDecorView();
? ? ? ? ? ? decor.addView(mCustomView, new FrameLayout.LayoutParams(
? ? ? ? ? ? ? ? ? ? ViewGroup.LayoutParams.MATCH_PARENT,
? ? ? ? ? ? ? ? ? ? ViewGroup.LayoutParams.MATCH_PARENT));
? ? ? ? ? ? if(mVideoFullScreenBack!=null){
? ? ? ? ? ? ? ? mVideoFullScreenBack.setVisibility(View.VISIBLE);
? ? ? ? ? ? }
? ? ? ? ? ? // 4. Change the state of the window
? ? ? ? ? ? MainActivity.this.getWindow().getDecorView().setSystemUiVisibility(
? ? ? ? ? ? ? ? ? ? View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
? ? ? ? ? ? ? ? ? ? ? ? ? ? View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
? ? ? ? ? ? ? ? ? ? ? ? ? ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
? ? ? ? ? ? ? ? ? ? ? ? ? ? View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
? ? ? ? ? ? ? ? ? ? ? ? ? ? View.SYSTEM_UI_FLAG_FULLSCREEN |
? ? ? ? ? ? ? ? ? ? ? ? ? ? View.SYSTEM_UI_FLAG_IMMERSIVE);
? ? ? ? ? ? MainActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
? ? ? ? }
? ? ? ? @Override
? ? ? ? public void onHideCustomView() {
? ? ? ? ? ? // 1. Remove the custom view
? ? ? ? ? ? FrameLayout decor = (FrameLayout) MainActivity.this.getWindow().getDecorView();
? ? ? ? ? ? decor.removeView(mCustomView);
? ? ? ? ? ? mCustomView = null;
? ? ? ? ? ? if(mVideoFullScreenBack!=null){
? ? ? ? ? ? ? ? mVideoFullScreenBack.setVisibility(View.GONE);
? ? ? ? ? ? }
? ? ? ? ? ? // 2. Restore the state to it's original form
? ? ? ? ? ? MainActivity.this.getWindow().getDecorView().setSystemUiVisibility(mOriginalSystemUiVisibility);
? ? ? ? ? ? MainActivity.this.setRequestedOrientation(mOriginalOrientation);
? ? ? ? ? ? // 3. Call the custom view callback
? ? ? ? ? ? if(mCustomViewCallback!=null){
? ? ? ? ? ? ? ? mCustomViewCallback.onCustomViewHidden();
? ? ? ? ? ? ? ? mCustomViewCallback = null;
? ? ? ? ? ? }
? ? ? ? }
? ? };
? ? @Override
? ? public void onPause() {
? ? ? ? //視頻播放器當(dāng)頁面停止的時(shí)候所有的視頻播放全部暫停
? ? ? ? if(playerViewList!=null){
? ? ? ? ? ? for(YoutubePlayerView v : playerViewList){
? ? ? ? ? ? ? ? if(v.getPlayerState() == YoutubePlayerView.STATE.PLAYING ){
? ? ? ? ? ? ? ? ? ? v.pause();
? ? ? ? ? ? ? ? }else if(v.getPlayerState() == YoutubePlayerView.STATE.BUFFERING){
? ? ? ? ? ? ? ? ? ? v.stop();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? super.onPause();
? ? }
? ? @Override
? ? public void onDestroy() {
? ? ? ? super.onDestroy();
? ? ? ? if (playerViewList != null) {
? ? ? ? ? ? for (YoutubePlayerView v : playerViewList) {
? ? ? ? ? ? ? ? if (v != null) v.onDestroy();
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? public boolean closeFullScreen(){
? ? ? ? if(mCustomView!=null && mCustomViewCallback!=null){
? ? ? ? ? ? mWebChromeClient.onHideCustomView();
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? return false;
? ? }
? ? @Override
? ? public void onBackPressed() {
? ? ? ? Log.i("Alex", "進(jìn)入onBackPressed方法");
? ? ? ? closeFullScreen();
? ? ? ? super.onBackPressed();
? ? }
}
```
在上面的代碼中,我們創(chuàng)建一個(gè)類烁兰,是的子類YouTubeBaseActivity耐亏。這需要利用YouTubePlayerView。我們使用
YouTubePlayer.OnInitializedListener偵聽初始化成功或失敗沪斟。該接口有兩個(gè)方法广辰,一個(gè)名為onInitializationFailure()和
onInitializationSuccess() 。
例如主之,如果YouTube應(yīng)用是不是安裝在用戶的設(shè)備上或已過期择吊,對(duì)話將有一個(gè)提示,經(jīng)確認(rèn)后槽奕,將打開谷歌Play商店安裝或相應(yīng)
地更新它的用戶几睛。如果YouTube應(yīng)用在設(shè)備上禁用,則該提示將打開系統(tǒng)設(shè)置為用戶啟用它粤攒。
當(dāng)用戶從錯(cuò)誤恢復(fù)對(duì)話返回所森,的onActivityResult()被調(diào)用檢查,查看是否用戶執(zhí)行的恢復(fù)操作夯接。如果是這樣焕济,我們重試初始
化。
運(yùn)行該應(yīng)用程序盔几,你應(yīng)該能夠發(fā)揮在代碼中指定的視頻晴弃。請(qǐng)注意,您將需要您的設(shè)備上的YouTube應(yīng)用问欠。該API客戶端庫與分布
的YouTube應(yīng)用為Android平臺(tái)的部分服務(wù)進(jìn)行交互肝匆。用戶需要運(yùn)行移動(dòng)版YouTube應(yīng)用程式(或更高)的版本4.2.16使用API。
通常情況下顺献,運(yùn)行Android 2.2(升級(jí)Froyo)或更高版本有谷歌Play商店應(yīng)用的設(shè)備應(yīng)該能夠運(yùn)行向上的最新版本的YouTube應(yīng)
用旗国。
這意味著什么,除非你已經(jīng)安裝了谷歌Apps的虛擬設(shè)備注整,您將無法測試在模擬器上的代碼能曾。默認(rèn)的Android模擬器不支持在設(shè)備
上安裝谷歌企業(yè)應(yīng)用套件度硝,但如果你使用的模擬器像Genymotion,就可以使用了寿冕。即使在我的模擬器安裝了谷歌企業(yè)應(yīng)用套
件蕊程,我仍然無法播放視頻。視頻縮略圖加載沒關(guān)系的看法驼唱,但在攻播放按鈕藻茂,加載指示燈會(huì)出現(xiàn),但再裝載會(huì)失敗玫恳,“連接到服
務(wù)器丟失”的消息辨赐。您可能需要準(zhǔn)備一個(gè)真正的設(shè)備。
結(jié)論
Android版的YouTube庫提供了一個(gè)很好的API京办,你可以自定義此API掀序,我們僅僅觸及了它的邊緣。要了解更多關(guān)于庫惭婿,一定要通
過文檔閱讀并隨附庫下載示例應(yīng)用程序不恭。
你可以在這里下載完整的項(xiàng)目。記得放置在您的密鑰Config.java文件财饥。
IFrameAPI:https://github.com/gongzaijing/intelchange.git
AndroidAPI:https://github.com/gongzaijing/Android-VideoTube-master.git