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>
須要添加的權限:
由於視頻來源能夠是網絡或者本地,因此須要動態申請網絡訪問權限和本地文件讀寫權限,文件讀寫權限通常還須要手動獲取
<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();
利用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>
尋找播放控件標籤:
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