Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android使用MediaPlayer實現播放網絡視頻示例

Android使用MediaPlayer實現播放網絡視頻示例

編輯:Android開發實例

       上次講解了MediaPlayer播放網絡音頻,介紹了MediaPlayer關於網絡音頻的緩沖和進度條控制的方法,這次再講解MediaPlayer播放網絡視頻。播放網絡視頻比播放網絡音頻多需要一個SurfaceView而已,已經熟悉MediaPlayer播放網絡音頻之後,相信大家對播放網絡視頻也能很快地掌握。先來看看本文程序運行截圖:

本文程序的視頻來自http://daily3gp.com,大家可以替換程序中的視頻鏈接,試試其他影片。

main.xml的源碼如下:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_height="fill_parent" android:layout_width="fill_parent"> 
  4.     <SurfaceView android:id="@+id/surfaceView1" 
  5.         android:layout_height="fill_parent" android:layout_width="fill_parent"></SurfaceView> 
  6.     <LinearLayout android:layout_height="wrap_content" 
  7.         android:layout_width="fill_parent" android:layout_gravity="bottom" 
  8.         android:orientation="vertical"> 
  9.         <LinearLayout android:orientation="horizontal" 
  10.             android:layout_gravity="center_horizontal" android:layout_marginTop="4.0dip" 
  11.             android:layout_height="wrap_content" android:layout_width="wrap_content"> 
  12.             <Button android:layout_width="wrap_content" 
  13.                 android:layout_height="wrap_content" android:id="@+id/btnPlayUrl" 
  14.                 android:text="播放網絡視頻"></Button> 
  15.             <Button android:layout_height="wrap_content" android:id="@+id/btnPause" 
  16.                 android:text="暫停" android:layout_width="80dip"></Button> 
  17.             <Button android:layout_height="wrap_content" 
  18.                 android:layout_width="80dip" android:text="停止" android:id="@+id/btnStop"></Button> 
  19.         </LinearLayout> 
  20.         <LinearLayout android:orientation="horizontal" 
  21.             android:layout_width="fill_parent" android:layout_height="wrap_content" 
  22.             android:layout_marginBottom="20dip"> 
  23.             <SeekBar android:paddingRight="10dip" android:layout_gravity="center_vertical" 
  24.                 android:paddingLeft="10dip" android:layout_weight="1.0" 
  25.                 android:layout_height="wrap_content" android:layout_width="wrap_content" 
  26.                 android:id="@+id/skbProgress" android:max="100"></SeekBar> 
  27.         </LinearLayout> 
  28.     </LinearLayout> 
  29. </FrameLayout> 

Player.java是本文的核心,Player.java實現了“進度條更新”、“數據緩沖”、“SurfaceHolder生命周期”等功能,其中“SurfaceHolder生命周期”是視頻與音頻播放的最大區別,通過surfaceCreated()、surfaceDestroyed()、surfaceChanged()可以創建/釋放某些資源。下面這個地方需要注意一下:

  1. videoWidth = mediaPlayer.getVideoWidth(); 
  2.         videoHeight = mediaPlayer.getVideoHeight(); 
  3.         if (videoHeight != 0 && videoWidth != 0) { 
  4.             arg0.start(); 
  5.         } 

有些視頻是android播放器不能播放的,不能播放時videoHeight=0,videoWidth=0,以此來判斷是否播放視頻。

Player.java源碼如下:

  1. package com.videoplayer; 
  2.  
  3.  
  4. import java.io.IOException; 
  5. import java.util.Timer; 
  6. import java.util.TimerTask; 
  7. import android.media.AudioManager; 
  8. import android.media.MediaPlayer; 
  9. import android.media.MediaPlayer.OnBufferingUpdateListener; 
  10. import android.media.MediaPlayer.OnCompletionListener; 
  11. import android.os.Handler; 
  12. import android.os.Message; 
  13. import android.util.Log; 
  14. import android.view.SurfaceHolder; 
  15. import android.view.SurfaceView; 
  16. import android.widget.SeekBar; 
  17.  
  18. public class Player implements OnBufferingUpdateListener, 
  19.         OnCompletionListener, MediaPlayer.OnPreparedListener, 
  20.         SurfaceHolder.Callback { 
  21.     private int videoWidth; 
  22.     private int videoHeight; 
  23.     public MediaPlayer mediaPlayer; 
  24.     private SurfaceHolder surfaceHolder; 
  25.     private SeekBar skbProgress; 
  26.     private Timer mTimer=new Timer(); 
  27.     public Player(SurfaceView surfaceView,SeekBar skbProgress) 
  28.     { 
  29.         this.skbProgress=skbProgress; 
  30.         surfaceHolder=surfaceView.getHolder(); 
  31.         surfaceHolder.addCallback(this); 
  32.         surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
  33.         mTimer.schedule(mTimerTask, 0, 1000); 
  34.     } 
  35.      
  36.     /******************************************************* 
  37.      * 通過定時器和Handler來更新進度條 
  38.      ******************************************************/ 
  39.     TimerTask mTimerTask = new TimerTask() { 
  40.         @Override 
  41.         public void run() { 
  42.             if(mediaPlayer==null) 
  43.                 return; 
  44.             if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false) { 
  45.                 handleProgress.sendEmptyMessage(0); 
  46.             } 
  47.         } 
  48.     }; 
  49.      
  50.     Handler handleProgress = new Handler() { 
  51.         public void handleMessage(Message msg) { 
  52.  
  53.             int position = mediaPlayer.getCurrentPosition(); 
  54.             int duration = mediaPlayer.getDuration(); 
  55.              
  56.             if (duration > 0) { 
  57.                 long pos = skbProgress.getMax() * position / duration; 
  58.                 skbProgress.setProgress((int) pos); 
  59.             } 
  60.         }; 
  61.     }; 
  62.     //***************************************************** 
  63.      
  64.     public void play() 
  65.     { 
  66.         mediaPlayer.start(); 
  67.     } 
  68.      
  69.     public void playUrl(String videoUrl) 
  70.     { 
  71.         try { 
  72.             mediaPlayer.reset(); 
  73.             mediaPlayer.setDataSource(videoUrl); 
  74.             mediaPlayer.prepare();//prepare之後自動播放 
  75.             //mediaPlayer.start(); 
  76.         } catch (IllegalArgumentException e) { 
  77.             // TODO Auto-generated catch block 
  78.             e.printStackTrace(); 
  79.         } catch (IllegalStateException e) { 
  80.             // TODO Auto-generated catch block 
  81.             e.printStackTrace(); 
  82.         } catch (IOException e) { 
  83.             // TODO Auto-generated catch block 
  84.             e.printStackTrace(); 
  85.         } 
  86.     } 
  87.  
  88.      
  89.     public void pause() 
  90.     { 
  91.         mediaPlayer.pause(); 
  92.     } 
  93.      
  94.     public void stop() 
  95.     { 
  96.         if (mediaPlayer != null) {  
  97.             mediaPlayer.stop(); 
  98.             mediaPlayer.release();  
  99.             mediaPlayer = null;  
  100.         }  
  101.     } 
  102.      
  103.     @Override 
  104.     public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
  105.         Log.e("mediaPlayer", "surface changed"); 
  106.     } 
  107.  
  108.     @Override 
  109.     public void surfaceCreated(SurfaceHolder arg0) { 
  110.         try { 
  111.             mediaPlayer = new MediaPlayer(); 
  112.             mediaPlayer.setDisplay(surfaceHolder); 
  113.             mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
  114.             mediaPlayer.setOnBufferingUpdateListener(this); 
  115.             mediaPlayer.setOnPreparedListener(this); 
  116.         } catch (Exception e) { 
  117.             Log.e("mediaPlayer", "error", e); 
  118.         } 
  119.         Log.e("mediaPlayer", "surface created"); 
  120.     } 
  121.  
  122.     @Override 
  123.     public void surfaceDestroyed(SurfaceHolder arg0) { 
  124.         Log.e("mediaPlayer", "surface destroyed"); 
  125.     } 
  126.  
  127.      
  128.     @Override 
  129.     /** 
  130.      * 通過onPrepared播放 
  131.      */ 
  132.     public void onPrepared(MediaPlayer arg0) { 
  133.         videoWidth = mediaPlayer.getVideoWidth(); 
  134.         videoHeight = mediaPlayer.getVideoHeight(); 
  135.         if (videoHeight != 0 && videoWidth != 0) { 
  136.             arg0.start(); 
  137.         } 
  138.         Log.e("mediaPlayer", "onPrepared"); 
  139.     } 
  140.  
  141.     @Override 
  142.     public void onCompletion(MediaPlayer arg0) { 
  143.         // TODO Auto-generated method stub 
  144.          
  145.     } 
  146.  
  147.     @Override 
  148.     public void onBufferingUpdate(MediaPlayer arg0, int bufferingProgress) { 
  149.         skbProgress.setSecondaryProgress(bufferingProgress); 
  150.         int currentProgress=skbProgress.getMax()*mediaPlayer.getCurrentPosition()/mediaPlayer.getDuration(); 
  151.         Log.e(currentProgress+"% play", bufferingProgress + "% buffer"); 
  152.          
  153.     } 
  154.  

test_videoplayer.java是主程序,負責調用Player類,其中關鍵部分是SeekBarChangeEvent這個SeekBar拖動的事件:SeekBar的Progress是0~SeekBar.getMax()之內的數,而MediaPlayer.seekTo()的參數是0~MediaPlayer.getDuration()之內數,所以MediaPlayer.seekTo()的參數是(progress/seekBar.getMax())*MediaPlayer.getDuration()。

 

test_videoplayer.java源碼如下:

  1. package com.videoplayer; 
  2.  
  3. import android.app.Activity; 
  4. import android.content.pm.ActivityInfo; 
  5. import android.net.Uri; 
  6. import android.os.Bundle; 
  7. import android.util.Log; 
  8. import android.view.SurfaceView; 
  9. import android.view.View; 
  10. import android.view.View.OnClickListener; 
  11. import android.widget.Button; 
  12. import android.widget.SeekBar; 
  13.  
  14. public class test_videoplayer extends Activity { 
  15.     private SurfaceView surfaceView; 
  16.     private Button btnPause, btnPlayUrl, btnStop; 
  17.     private SeekBar skbProgress; 
  18.     private Player player; 
  19.  
  20.     /** Called when the activity is first created. */ 
  21.     @Override 
  22.     public void onCreate(Bundle savedInstanceState) { 
  23.         super.onCreate(savedInstanceState); 
  24.         setContentView(R.layout.main); 
  25.         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
  26.         surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView1); 
  27.  
  28.         btnPlayUrl = (Button) this.findViewById(R.id.btnPlayUrl); 
  29.         btnPlayUrl.setOnClickListener(new ClickEvent()); 
  30.  
  31.         btnPause = (Button) this.findViewById(R.id.btnPause); 
  32.         btnPause.setOnClickListener(new ClickEvent()); 
  33.  
  34.         btnStop = (Button) this.findViewById(R.id.btnStop); 
  35.         btnStop.setOnClickListener(new ClickEvent()); 
  36.  
  37.         skbProgress = (SeekBar) this.findViewById(R.id.skbProgress); 
  38.         skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent()); 
  39.         player = new Player(surfaceView, skbProgress); 
  40.  
  41.     } 
  42.  
  43.     class ClickEvent implements OnClickListener { 
  44.  
  45.         @Override 
  46.         public void onClick(View arg0) { 
  47.             if (arg0 == btnPause) { 
  48.                 player.pause(); 
  49.             } else if (arg0 == btnPlayUrl) { 
  50.                 String url="http://daily3gp.com/vids/family_guy_penis_car.3gp"; 
  51.                 player.playUrl(url); 
  52.             } else if (arg0 == btnStop) { 
  53.                 player.stop(); 
  54.             } 
  55.  
  56.         } 
  57.     } 
  58.  
  59.     class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener { 
  60.         int progress; 
  61.  
  62.         @Override 
  63.         public void onProgressChanged(SeekBar seekBar, int progress, 
  64.                 boolean fromUser) { 
  65.             // 原本是(progress/seekBar.getMax())*player.mediaPlayer.getDuration() 
  66.             this.progress = progress * player.mediaPlayer.getDuration() 
  67.                     / seekBar.getMax(); 
  68.         } 
  69.  
  70.         @Override 
  71.         public void onStartTrackingTouch(SeekBar seekBar) { 
  72.  
  73.         } 
  74.  
  75.         @Override 
  76.         public void onStopTrackingTouch(SeekBar seekBar) { 
  77.             // seekTo()的參數是相對與影片時間的數字,而不是與seekBar.getMax()相對的數字 
  78.             player.mediaPlayer.seekTo(progress); 
  79.         } 
  80.     } 
  81.  

 

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