安卓視頻播放器(VideoView)

VideoView是安卓自帶的視頻播放器類,該類集成有顯示和控制兩大部分,在佈局文件中添加VideoView而後在java文件中簡單的調用控制命令,便可實現本地或者網絡視頻的播放。本章實現視頻的居中播放、網絡視頻播放、本地視頻播放、視頻卡頓監聽、網絡鏈接錯誤監聽、視頻外自定義視頻控件、視頻內自定義視頻控件等。html

 

支持的格式:flv、3gp、mp4java

 

類的一些重要方法

void start();                 //開始播放android

void pause();              //暫停網絡

void resume();           //從新播放,使用時須要在本句後加上開始播放app

void seekTo(int msec);       //從第幾毫秒開始播放ide

void stopPlayback();          //中止播放並釋放資源佈局

int getCurrentPosition();    //獲取當前播放的位置。this

int getDuration();               //獲取當前播放視頻的總長度。url

void setVideoPath(String path);    //以文件路徑的方式設置VideoView播放的視頻源。spa

void setVideoURI(Uri uri);            //以Uri的方式設置VideoView播放的視頻源,能夠是網絡Uri或本地Uri

void isPlaying();                           //當前VideoView是否在播放視頻

setMediaController(MediaController controller);                               //設置MediaController控制器

setOnCompletionListener(MediaPlayer.onCompletionListener l);     //監聽播放完成的事件

setOnErrorListener(MediaPlayer.OnErrorListener l);                        //監聽播放發生錯誤時候的事件

setOnPreparedListener(MediaPlayer.OnPreparedListener l);          //監聽視頻裝載完成的事件

setOnInfoListener(new MediaPlayer.OnInfoListener(){});                 //視頻卡頓監聽

 

實現簡單的視頻播放

                                             

佈局文件:

實現視頻播放重要在於VideoView標籤,若是讓該標籤的父級標籤爲FramLayout,設置相應屬性就能夠實現視頻居中播放和默認的播放控件 MediaController 在視頻內顯示效果,還能夠在VidoView標籤上層加入TextView標籤,實現視頻播放的一些狀態顯示,如播放卡頓、切換播放、播放失敗等的提示信息顯示。另外可加入ImageView標籤,便可顯示圖片或gif圖,更具人性化。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:paddingBottom="0dp"
 7     android:paddingLeft="0dp"
 8     android:paddingRight="0dp"
 9     android:orientation="vertical"
10     android:paddingTop="0dp"
11     tools:context="com.example.videodong.MainActivity">
12 
13     <TextView
14         android:layout_width="wrap_content"
15         android:layout_height="wrap_content"
16         android:text="視頻播放器:\n"
17         android:textSize="15dp"
18         android:id="@+id/textView" />
19     <FrameLayout
20         android:layout_width="match_parent"
21         android:background="@color/colorBlack"
22         android:layout_height="300dp">
23        <VideoView
24         android:layout_width="match_parent"
25         android:layout_gravity="center"
26         android:layout_height="300dp"
27         android:id="@+id/videoView"
28         />
29 
30         <TextView
31             android:layout_width="wrap_content"
32             android:layout_height="wrap_content"
33             android:textSize="15dp"
34             android:text="點擊播放"
35             android:textColor="@color/colorWhite"
36             android:id="@+id/vv_text"
37             android:layout_gravity="center" />
38     </FrameLayout>
39 
40     <ProgressBar
41         android:id="@+id/vv_bar"
42         style="?android:attr/progressBarStyleHorizontal"
43         android:layout_width="match_parent"
44         android:layout_height="wrap_content"/>
45 
46         <TextView
47             android:layout_width="wrap_content"
48             android:text="時間軸爲:0.00/000"
49             android:id="@+id/vv_starttime"
50             android:layout_height="wrap_content" />
51 
52 
53      <LinearLayout
54          android:layout_width="match_parent"
55          android:orientation="horizontal"
56          android:layout_gravity="center"
57          android:layout_height="wrap_content">
58          <TextView
59              android:layout_width="wrap_content"
60              android:layout_weight="1"
61              android:layout_height="wrap_content" />
62          <Button
63              android:layout_width="wrap_content"
64              android:text="開始"
65              android:id="@+id/vv_start"
66              android:layout_height="wrap_content" />
67          <Button
68              android:layout_width="wrap_content"
69              android:text="暫停"
70              android:id="@+id/vv_pause"
71              android:layout_height="wrap_content" />
72          <Button
73              android:layout_width="wrap_content"
74              android:text="重播"
75              android:id="@+id/vv_restart"
76              android:layout_height="wrap_content" />
77          <Button
78              android:layout_width="wrap_content"
79              android:text="下一個"
80              android:id="@+id/vv_next"
81              android:layout_height="wrap_content" />
82          
83      </LinearLayout>
84     <TextView
85         android:layout_width="wrap_content"
86         android:id="@+id/vv_state"
87         android:layout_height="wrap_content" />
88 </LinearLayout>
View Code

須要添加的權限:

由於視頻來源能夠是網絡或者本地,因此須要動態申請網絡訪問權限和本地文件讀寫權限,文件讀寫權限通常還須要手動獲取

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

尋找到VideoView控件:

vv=(VideoView)findViewById(R.id.videoView);

視頻預裝完成監聽:

1 //視頻準備完成時進入
2 vv.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
3             @Override
4             public void onPrepared(MediaPlayer mp) {
5                 //設置屏幕提示信息爲空
6                 vv_text.setText("");
7             }
8 });

視頻播放完成監聽:

 1 vv.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
 2             @Override
 3             public void onCompletion(MediaPlayer mp) {
 4                 String strres="播放完成";
 5                 //判斷視頻的總長度與當前長度是否在偏差區間內
 6                 if(Math.abs(vv.getDuration()-vv.getCurrentPosition())>1000){
 7 
 8                     strres="播放錯誤,可能無網絡鏈接";
 9 
10                 }
11                 //設置屏幕提示信息
12                 vv_text.setText(strres);
13 
14             }
15 });

視頻播放錯誤監聽:

 1 vv.setOnErrorListener(new MediaPlayer.OnErrorListener() {
 2             @Override
 3             public boolean onError(MediaPlayer mp, int what, int extra) 
 4            {
 5                //設置屏幕顯示信息
 6                 vv_text.setText("視頻未知錯誤");
 7 
 8                 return false;
 9             }
10  });

視頻卡頓和中止卡頓監聽:

 1 vv.setOnInfoListener(new MediaPlayer.OnInfoListener(){
 2             @Override
 3             public boolean onInfo(MediaPlayer mp, int what, int extra){
 4 
 5                 switch(what){
 6                     case MediaPlayer.MEDIA_INFO_BUFFERING_START:
 7                         //設置屏幕顯示信息,開始卡頓
 8                         vv_text.setText("視頻卡頓,加載中.....");
 9                         break ;
10                     case MediaPlayer.MEDIA_INFO_BUFFERING_END:
11                         //設置屏幕顯示信息,卡頓結束
12                         vv_text.setText("");
13                         break ;
14                 }
15              return true;
16             }
17 }) ;

設置播放資源:

1 //本地文件
2 vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
3 
4 //URL形式,支持本地URL和網絡URL
5 //vv.setVideoURI(Uri.parse("https://www.bilibili.com/video/xxxxx"));
6        
7 //設置自帶的播放控件
8 //vv.setMediaController(new MediaController(this));

播放開始按鈕監聽:

 1 //開始播放視頻按鈕
 2 vv_start.setOnClickListener(new View.OnClickListener() {
 3             @Override
 4             public void onClick(View v) {
 5                 
 6                 //設置屏幕顯示信息
 7                 vv_text.setText("");
 8 
 9                 //開始播放
10                 vv.start();
11 
12             }
13 });

播放暫停按鈕監聽:

 1 //暫停播放視頻按鈕
 2 vv_pause.setOnClickListener(new View.OnClickListener() {
 3             @Override
 4             public void onClick(View v) {
 5 
 6                 //設置屏幕顯示信息
 7                 vv_text.setText("視頻暫停中");
 8 
 9                 //暫停視頻播放
10                 vv.pause();
11 
12             }
13 });

從新播放按鈕監聽:

 1 //從新播放視頻
 2 vv_restart.setOnClickListener(new View.OnClickListener() {
 3             @Override
 4             public void onClick(View v) {
 5                 //設置屏幕顯示信息
 6                 vv_text.setText("正在從新播放中,請稍等");
 7 
 8                 //設置時間軸顯示爲0
 9                 vv_starttime.setText("時間軸爲:0.00/0.00");
10 
11                 //設置進度條顯示爲0
12                 vv_bar.setProgress(0);
13                 
14                 //從新播放視頻
15                 vv.resume();
16                 vv.start();
17 
18             }
19 });

播放下一個視頻監聽:

 1 vv_next.setOnClickListener(new View.OnClickListener() {
 2             @Override
 3             public void onClick(View v) {
 4                 //設置屏幕顯示信息
 5                 vv_text.setText("正在切換,請稍等");
 6 
 7                 //設置時間軸爲0
 8                 vv_starttime.setText("時間軸爲:0.00/0.00");
 9 
10                 //設置進度條爲0
11                 vv_bar.setProgress(0);
12                 
13                 //中止播放
14                 vv.pause();//暫停
15                 vv.stopPlayback();//中止播放並釋放資源
16 
17                 //獲得下一個視頻的資源
18                 if(nextbool){
19                     nextbool=false;
20                     //網絡資源,該url已通過期
21                     vv.setVideoURI(Uri.parse("http://193.112.87.88/video/xx.flv"));
22                 } else {
23                     nextbool=true;
24                     //本地資源
25                     vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
26                 }
27 
28                 //開始播放下一個
29                 vv.start();
30 
31             }
32 });

時間軸時間顯示和進度條更新實現:

時間軸時間顯示計算將在後文給出解釋,另外 %02d 能夠實現自動補零效果,runOnUiThread能夠在普通線程中進入UI線程,能夠實現UI的一系列操做。

 1 new Thread(new Runnable() {
 2             @Override
 3             public void run() {
 4                 while (true){
 5                     //延時1秒
 6                     try {
 7                         Thread.sleep(1);
 8                     } catch (InterruptedException e) {
 9                         e.printStackTrace();
10                     }
11 
12                     //進入主線程更新UI
13                     runOnUiThread(new Runnable() {
14                         @Override
15                         public void run() {
16                             if(vv.isPlaying()) {
17                                  
18                                 //獲取到視頻播放進度
19                                 int maxx=vv.getDuration();
20                                 int progress=vv.getCurrentPosition();
21 
22                                 //設置進度條信息
23                                 vv_bar.setMax(maxx);
24                                 vv_bar.setProgress(progress);
25 
26                                 //獲得時間軸字符串
27                                 String strtime=String.format("時間軸爲:%02d:%02d/%02d:%02d", (progress % 3600000) / 60000,(progress % 60000 ) / 1000, (maxx % 3600000) / 60000,(maxx % 60000 ) / 1000);
28                                 //顯示時間軸信息
29                                 vv_starttime.setText(strtime);
30 
31                             }
32                         }
33                     });
34                     }
35 
36                 }
37  }).start();
View Code

 

視頻播放進階

利用FrameLayout的層疊效果,實現視頻控件面板在視頻層之上顯示,利用視頻控件的點擊事件,實現視頻點擊監聽而後改變視頻控制面板的隱藏和顯示。其餘的視頻播放控制代碼基本以上類似

                                                                             

 佈局文件改變:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:paddingBottom="0dp"
 7     android:paddingLeft="0dp"
 8     android:paddingRight="0dp"
 9     android:orientation="vertical"
10     android:paddingTop="0dp"
11     tools:context="com.example.videodong.MainActivity">
12 
13     <TextView
14         android:layout_width="wrap_content"
15         android:layout_height="wrap_content"
16         android:text="視頻播放器:\n"
17         android:textSize="15dp"
18         android:id="@+id/textView" />
19     <FrameLayout
20         android:layout_width="match_parent"
21         android:background="@color/colorBlack"
22         android:layout_height="230dp">
23        <VideoView
24         android:layout_width="match_parent"
25         android:layout_gravity="center"
26         android:layout_height="230dp"
27         android:id="@+id/videoView"
28         />
29         <FrameLayout
30             android:layout_width="match_parent"
31             android:layout_gravity="bottom"
32             android:id="@+id/vv_framel"
33             android:layout_height="wrap_content">
34             <ImageView
35                 android:layout_width="match_parent"
36                 android:background="@color/colorWhite"
37                 android:alpha="0.5"
38                 android:layout_height="match_parent" />
39         <LinearLayout
40             android:layout_width="match_parent"
41             android:orientation="vertical"
42 
43             android:layout_height="wrap_content">
44             <ProgressBar
45                 android:id="@+id/vv_bar"
46                 style="?android:attr/progressBarStyleHorizontal"
47                 android:layout_width="match_parent"
48                 android:layout_height="wrap_content"/>
49             <LinearLayout
50                 android:layout_width="match_parent"
51                 android:orientation="horizontal"
52                 android:layout_gravity="center"
53                 android:layout_height="wrap_content">
54                 <TextView
55                     android:layout_width="wrap_content"
56                     android:text="時間軸爲:0.00/000"
57                     android:id="@+id/vv_starttime"
58                     android:layout_weight="1"
59                     android:layout_height="wrap_content" />
60                 <Button
61                     android:layout_width="wrap_content"
62                     android:text="開始"
63                     style="?android:attr/buttonStyleSmall"
64                     android:id="@+id/vv_start"
65                     android:layout_height="wrap_content" />
66                 <Button
67                     android:layout_width="wrap_content"
68                     android:text="暫停"
69                     android:id="@+id/vv_pause"
70                     style="?android:attr/buttonStyleSmall"
71                     android:layout_height="wrap_content" />
72                 <Button
73                     android:layout_width="wrap_content"
74                     android:text="重播"
75                     style="?android:attr/buttonStyleSmall"
76                     android:id="@+id/vv_restart"
77                     android:layout_height="wrap_content" />
78                 <Button
79                     android:layout_width="wrap_content"
80                     android:text="下一個"
81                     style="?android:attr/buttonStyleSmall"
82                     android:id="@+id/vv_next"
83                     android:layout_height="wrap_content" />
84 
85             </LinearLayout>
86         </LinearLayout>
87         </FrameLayout>
88 
89         <TextView
90             android:layout_width="wrap_content"
91             android:layout_height="wrap_content"
92             android:textSize="15dp"
93             android:text="點擊播放"
94             android:textColor="@color/colorWhite"
95             android:id="@+id/vv_text"
96             android:layout_gravity="center" />
97     </FrameLayout>
98 </LinearLayout>
View Code

尋找播放控件標籤:

vv_framel=(FrameLayout)findViewById(R.id.vv_framel);

設置視頻播放控件點擊事件監聽: 

 1 vv.setOnClickListener(new View.OnClickListener() {
 2     @Override
 3     public void onClick(View v) {
 4         //判斷是不是顯示
 5         if(vv_framel.getVisibility()==View.VISIBLE)
 6 
 7             //隱藏視頻播放控件
 8             vv_framel.setVisibility(View.INVISIBLE);
 9 
10         else
11 
12             //顯示視頻播放控件
13             vv_framel.setVisibility(View.VISIBLE);
14 
15     }
16 });

 

內容補充:

視頻播放時間軸時間計算:

若是隻知道毫秒數,如何轉換爲對應的時、分、秒,由於1秒爲1000毫秒,1分鐘爲60秒,1小時爲60分,因此若是求秒則須要去掉分鐘的值,若是求分鐘則須要去掉小時的值。

獲得秒:【(t % (60*1000) ) / 1000】

獲得分:【(t % (60*60*1000)) / (60*1000)】

獲得時:【(t / (60*60*1000))】

 

源碼資源下載:點我下載

 


 參考:

https://www.jianshu.com/p/0c3ef72c20d1?from=timeline&isappinstalled=0

https://www.cnblogs.com/tangs/articles/5463347.html

https://blog.csdn.net/qq_30983519/article/details/54407122

https://blog.csdn.net/qq_29272491/article/details/80475788

相關文章
相關標籤/搜索