MediaPlayer播放網絡視頻

本文來自http://blog.csdn.net/hellogv/ ,引用必須註明出處!

       上次講解了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, 01000);   
    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.    
    155. }   

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.    
    82. }   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章