Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android應用開發入門(六十三)使用VideoView播放視頻示例

Android應用開發入門(六十三)使用VideoView播放視頻示例

編輯:Android開發實例

前言

  之前有講過如何使用SurfaceView配合MediaPlayer播放視頻,其實Android還為開發人員提供了另外一種更簡單的播放視頻媒體的方式,那就是VideoView,本文就來講講VideoView如何播放視頻,最後將以一個簡單的Demo演示。

  本文的主要內容如下:

  1. VideoView
  2. VideoView簡單的Demo
  3. MediaController
  4. MediaController簡單的Demo

 

VideoView

  VideoView,用於播放一段視頻媒體,它繼承了SurfaceView,位於"android.widget.VideoView",是一個視頻控件。

  既然是播放一段視頻,那麼不可避免的要涉及到一些開始、暫停、停止等操作,VideoView也為開發人員提供了對應的方法,這裡簡單介紹一些常用的:

  • int getCurrentPosition():獲取當前播放的位置。
  • int getDuration():獲取當前播放視頻的總長度。
  • isPlaying():當前VideoView是否在播放視頻。
  • void pause():暫停
  • void seekTo(int msec):從第幾毫秒開始播放。
  • void resume():重新播放。
  • void setVideoPath(String path):以文件路徑的方式設置VideoView播放的視頻源。
  • void setVideoURI(Uri uri):以Uri的方式設置VideoView播放的視頻源,可以是網絡Uri或本地Uri。
  • void start():開始播放。
  • void stopPlayback():停止播放。
  • setMediaController(MediaController controller):設置MediaController控制器。
  • setOnCompletionListener(MediaPlayer.onCompletionListener l):監聽播放完成的事件。
  • setOnErrorListener(MediaPlayer.OnErrorListener l):監聽播放發生錯誤時候的事件。
  • setOnPreparedListener(MediaPlayer.OnPreparedListener l)::監聽視頻裝載完成的事件。

  上面的一些方法通過方法名就可以了解用途。和MediaPlayer配合SurfaceView播放視頻不同,VideoView播放之前無需編碼裝載視頻,它會在start()開始播放的時候自動裝載視頻。並且VideoView在使用完之後,無需編碼回收資源。

VideoView簡單的Demo

  VideoView其實沒有什麼難點,通過它自帶的API方法,即可完成一段視頻的播放,無非就是注意它方法的調用時機即可。下面通過一個簡單的Demo,演示VideoView如何播放一段SD卡上的視頻文件。在Demo中提供了四個Button,分別表示播放、暫停、重播、停止,並配合進度條顯示。代碼注釋比較完整,細節部分這裡不再累述。

  布局代碼:activity_videoview.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="match_parent" 
  4.     android:layout_height="match_parent" 
  5.     android:orientation="vertical" > 
  6.  
  7.     <EditText 
  8.         android:id="@+id/et_path" 
  9.         android:layout_width="match_parent" 
  10.         android:layout_height="wrap_content" 
  11.         android:text="/sdcard/ykzzldx.mp4" /> 
  12.  
  13.     <SeekBar 
  14.         android:id="@+id/seekBar" 
  15.         android:layout_width="match_parent" 
  16.         android:layout_height="wrap_content" /> 
  17.  
  18.     <LinearLayout 
  19.         android:layout_width="wrap_content" 
  20.         android:layout_height="wrap_content" 
  21.         android:orientation="horizontal" > 
  22.  
  23.         <Button 
  24.             android:id="@+id/btn_play" 
  25.             android:layout_width="0dip" 
  26.             android:layout_height="wrap_content" 
  27.             android:layout_weight="1" 
  28.             android:text="播放" /> 
  29.  
  30.         <Button 
  31.             android:id="@+id/btn_pause" 
  32.             android:layout_width="0dip" 
  33.             android:layout_height="wrap_content" 
  34.             android:layout_weight="1" 
  35.             android:text="暫停" /> 
  36.  
  37.         <Button 
  38.             android:id="@+id/btn_replay" 
  39.             android:layout_width="0dip" 
  40.             android:layout_height="wrap_content" 
  41.             android:layout_weight="1" 
  42.             android:text="重播" /> 
  43.  
  44.         <Button 
  45.             android:id="@+id/btn_stop" 
  46.             android:layout_width="0dip" 
  47.             android:layout_height="wrap_content" 
  48.             android:layout_weight="1" 
  49.             android:text="停止" /> 
  50.     </LinearLayout> 
  51.  
  52.     <VideoView 
  53.         android:id="@+id/vv_videoview" 
  54.         android:layout_width="fill_parent" 
  55.         android:layout_height="fill_parent" /> 
  56.  
  57. </LinearLayout> 

  實現代碼:VideoViewActivity.java

  1. package cn.bgxt.videoviewdemo;  
  2.  
  3. import java.io.File;  
  4.  
  5. import android.app.Activity;  
  6. import android.media.MediaPlayer;  
  7. import android.media.MediaPlayer.OnCompletionListener;  
  8. import android.media.MediaPlayer.OnErrorListener;  
  9. import android.os.Bundle;  
  10. import android.util.Log;  
  11. import android.view.View;  
  12. import android.widget.Button;  
  13. import android.widget.EditText;  
  14. import android.widget.SeekBar;  
  15. import android.widget.Toast;  
  16. import android.widget.VideoView;  
  17. import android.widget.SeekBar.OnSeekBarChangeListener;  
  18.  
  19. public class VideoViewActivity extends Activity {  
  20.     private final String TAG = "main";  
  21.     private EditText et_path;  
  22.     private Button btn_play, btn_pause, btn_replay, btn_stop;  
  23.     private SeekBar seekBar;  
  24.     private VideoView vv_video;  
  25.     private boolean isPlaying;  
  26.  
  27.     @Override 
  28.     protected void onCreate(Bundle savedInstanceState) {  
  29.         // TODO Auto-generated method stub  
  30.         super.onCreate(savedInstanceState);  
  31.         setContentView(R.layout.activity_videoview);  
  32.  
  33.         seekBar = (SeekBar) findViewById(R.id.seekBar);  
  34.         et_path = (EditText) findViewById(R.id.et_path);  
  35.         vv_video = (VideoView) findViewById(R.id.vv_videoview);  
  36.  
  37.         btn_play = (Button) findViewById(R.id.btn_play);  
  38.         btn_pause = (Button) findViewById(R.id.btn_pause);  
  39.         btn_replay = (Button) findViewById(R.id.btn_replay);  
  40.         btn_stop = (Button) findViewById(R.id.btn_stop);  
  41.  
  42.         btn_play.setOnClickListener(click);  
  43.         btn_pause.setOnClickListener(click);  
  44.         btn_replay.setOnClickListener(click);  
  45.         btn_stop.setOnClickListener(click);  
  46.  
  47.         // 為進度條添加進度更改事件  
  48.         seekBar.setOnSeekBarChangeListener(change);  
  49.     }  
  50.  
  51.     private OnSeekBarChangeListener change = new OnSeekBarChangeListener() {  
  52.  
  53.         @Override 
  54.         public void onStopTrackingTouch(SeekBar seekBar) {  
  55.             // 當進度條停止修改的時候觸發  
  56.             // 取得當前進度條的刻度  
  57.             int progress = seekBar.getProgress();  
  58.             if (vv_video != null && vv_video.isPlaying()) {  
  59.                 // 設置當前播放的位置  
  60.                 vv_video.seekTo(progress);  
  61.             }  
  62.         }  
  63.  
  64.         @Override 
  65.         public void onStartTrackingTouch(SeekBar seekBar) {  
  66.  
  67.         }  
  68.  
  69.         @Override 
  70.         public void onProgressChanged(SeekBar seekBar, int progress,  
  71.                 boolean fromUser) {  
  72.  
  73.         }  
  74.     };  
  75.     private View.OnClickListener click = new View.OnClickListener() {  
  76.  
  77.         @Override 
  78.         public void onClick(View v) {  
  79.  
  80.             switch (v.getId()) {  
  81.             case R.id.btn_play:  
  82.                 play(0);  
  83.                 break;  
  84.             case R.id.btn_pause:  
  85.                 pause();  
  86.                 break;  
  87.             case R.id.btn_replay:  
  88.                 replay();  
  89.                 break;  
  90.             case R.id.btn_stop:  
  91.                 stop();  
  92.                 break;  
  93.             default:  
  94.                 break;  
  95.             }  
  96.         }  
  97.     };  
  98.  
  99.     protected void play(int msec) {  
  100.         Log.i(TAG, " 獲取視頻文件地址");  
  101.         String path = et_path.getText().toString().trim();  
  102.         File file = new File(path);  
  103.         if (!file.exists()) {  
  104.             Toast.makeText(this, "視頻文件路徑錯誤", 0).show();  
  105.             return;  
  106.         }  
  107.           
  108.         Log.i(TAG, "指定視頻源路徑");  
  109.         vv_video.setVideoPath(file.getAbsolutePath());  
  110.         Log.i(TAG, "開始播放");  
  111.         vv_video.start();  
  112.           
  113.         // 按照初始位置播放  
  114.         vv_video.seekTo(msec);  
  115.         // 設置進度條的最大進度為視頻流的最大播放時長  
  116.         seekBar.setMax(vv_video.getDuration());  
  117.  
  118.         // 開始線程,更新進度條的刻度  
  119.         new Thread() {  
  120.  
  121.             @Override 
  122.             public void run() {  
  123.                 try {  
  124.                     isPlaying = true;  
  125.                     while (isPlaying) {  
  126.                         // 如果正在播放,沒0.5.毫秒更新一次進度條  
  127.                         int current = vv_video.getCurrentPosition();  
  128.                         seekBar.setProgress(current);  
  129.  
  130.                         sleep(500);  
  131.                     }  
  132.                 } catch (Exception e) {  
  133.                     e.printStackTrace();  
  134.                 }  
  135.             }  
  136.         }.start();  
  137.         // 播放之後設置播放按鈕不可用  
  138.         btn_play.setEnabled(false);  
  139.  
  140.         vv_video.setOnCompletionListener(new OnCompletionListener() {  
  141.  
  142.             @Override 
  143.             public void onCompletion(MediaPlayer mp) {  
  144.                 // 在播放完畢被回調  
  145.                 btn_play.setEnabled(true);  
  146.             }  
  147.         });  
  148.  
  149.         vv_video.setOnErrorListener(new OnErrorListener() {  
  150.  
  151.             @Override 
  152.             public boolean onError(MediaPlayer mp, int what, int extra) {  
  153.                 // 發生錯誤重新播放  
  154.                 play(0);  
  155.                 isPlaying = false;  
  156.                 return false;  
  157.             }  
  158.         });  
  159.     }  
  160.  
  161.     /**  
  162.      * 重新開始播放  
  163.      */ 
  164.     protected void replay() {  
  165.         if (vv_video != null && vv_video.isPlaying()) {  
  166.             vv_video.seekTo(0);  
  167.             Toast.makeText(this, "重新播放", 0).show();  
  168.             btn_pause.setText("暫停");  
  169.             return;  
  170.         }  
  171.         isPlaying = false;  
  172.         play(0);  
  173.  
  174.     }  
  175.  
  176.     /**  
  177.      * 暫停或繼續  
  178.      */ 
  179.     protected void pause() {  
  180.         if (btn_pause.getText().toString().trim().equals("繼續")) {  
  181.             btn_pause.setText("暫停");  
  182.             vv_video.start();  
  183.             Toast.makeText(this, "繼續播放", 0).show();  
  184.             return;  
  185.         }  
  186.         if (vv_video != null && vv_video.isPlaying()) {  
  187.             vv_video.pause();  
  188.             btn_pause.setText("繼續");  
  189.             Toast.makeText(this, "暫停播放", 0).show();  
  190.         }  
  191.     }  
  192.  
  193.     /*  
  194.      * 停止播放  
  195.      */ 
  196.     protected void stop() {  
  197.         if (vv_video != null && vv_video.isPlaying()) {  
  198.             vv_video.stopPlayback();  
  199.             btn_play.setEnabled(true);  
  200.             isPlaying = false;  
  201.         }  
  202.     }  

 

  效果展示:

 

MediaController

  提到VideoView不得不再說一些MediaController。雖然VideoView為我們提供了方便的API用於播放、暫停、停止等操作,但是還是需要我們編碼完成,但是如果使用了MediaController的話,那麼這些操作都可以省去。

  MediaController可以用於配合VideoView播放一段視頻,它為VideoView提供一個懸浮的操作欄,在操作欄中可以對VideoView播放的視頻進行控制,默認情況下,會懸浮顯示三秒。它通過MediaController.setMediaPlayer()方法進行指定需要控制的VideoView,但是僅僅這樣是不夠的,MediaController的控制需要類似於雙向控制,MediaController指定控制的VideoView,VideoView還需要指定那個MediaController來控制它,這需要使用VideoView.setMediaController()方法。

  下面介紹一下MediaController的一些常用方法;

  • boolean isShowing():當前懸浮控制欄是否顯示。
  • void setMediaPlayer(MediaController.MediaPlayerControl player):設置控制的組件。
  • void setPrevNextListeners(View.OnClickListener next,View.OnClickListener prev):設置上一個視頻、下一個視頻的切換事件。

  通過上面的方法可以看出setMediaPlayer()並非指定的是一個VideoView,而是一個MediaPlayerControl接口,MediaPlayerControl接口內部定義了一些播放相關的播放、暫停、停止等操作,而VideoView實現了MediaPlayerControl。

  默認情況下,如果不通過setPrevNextListeners()設置切換視頻的監聽器,MediaController是不會顯示這兩個按鈕的。

MediaController簡單的Demo

  上面已經講過MediaController的一些內容,下面通過一個簡單的Demo來演示一下MediaController控制VideoView播放視頻。

  布局代碼:activity_controller.xml

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="match_parent" 
  4.     android:layout_height="match_parent" 
  5.     android:orientation="vertical" > 
  6.       
  7. <VideoView 
  8.         android:id="@+id/vv_video" 
  9.         android:layout_width="match_parent" 
  10.         android:layout_height="match_parent" /> 
  11. </LinearLayout> 

  實現代碼:ControllerActivity.java

  1. package cn.bgxt.videoviewdemo;  
  2.  
  3. import java.io.File;  
  4.  
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.MediaController;  
  10. import android.widget.Toast;  
  11. import android.widget.VideoView;  
  12.  
  13. public class ControllerActivity extends Activity {  
  14.     private VideoView vv_video;  
  15.     private MediaController mController;  
  16.       
  17.     @Override 
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_controller);  
  21.         vv_video=(VideoView) findViewById(R.id.vv_video);  
  22.         // 實例化MediaController  
  23.         mController=new MediaController(this);  
  24.         File file=new File("/sdcard/ykzzldx.mp4");  
  25.         if(file.exists()){  
  26.             // 設置播放視頻源的路徑  
  27.             vv_video.setVideoPath(file.getAbsolutePath());  
  28.             // 為VideoView指定MediaController  
  29.             vv_video.setMediaController(mController);  
  30.             // 為MediaController指定控制的VideoView  
  31.             mController.setMediaPlayer(vv_video);  
  32.             // 增加監聽上一個和下一個的切換事件,默認這兩個按鈕是不顯示的  
  33.             mController.setPrevNextListeners(new OnClickListener() {  
  34.                   
  35.                 @Override 
  36.                 public void onClick(View v) {                      
  37.                     Toast.makeText(ControllerActivity.this, "下一個",0).show();  
  38.                 }  
  39.             }, new OnClickListener() {  
  40.                   
  41.                 @Override 
  42.                 public void onClick(View v) {  
  43.                     Toast.makeText(ControllerActivity.this, "上一個",0).show();  
  44.                 }  
  45.             });  
  46.         }  
  47.     }  

效果展示:

  從上面展示的效果可以看出,MediaController不光為我們增加了控制欄來控制播放、暫停、快進、快退、切換上一視頻、切換下一視頻,還增加了進度條顯示。

 

  源碼下載

 

總結

  本文就講解了VideoView和MediaController的內容。雖然使用MediaController非常的方便,基本上所有的操作都幫我們封裝好了,但是封裝即表示不夠靈活,必須按照既定的規則去實現。所以一般專業的視頻播放應用,還是會使用SurfaceView去完成。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved