Android使用SurfaceView实现视频播放

移动开发 Android
SurfaceView的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。

1.案例一

布局文件:

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3. android:orientation="vertical" android:layout_width="fill_parent"   
  4.  android:layout_height="fill_parent" android:weightSum="1">    
  5. <SurfaceView 
  6. android:layout_height="220dip"
  7. android:layout_gravity="center" 
  8. android:id="@+id/surface" 
  9. android:layout_weight="0.25" 
  10. android:layout_width="320dip">
  11. </SurfaceView>    
  12. <LinearLayout
  13. android:id="@+id/linearLayout1" 
  14. android:layout_height="wrap_content"
  15. android:layout_width="fill_parent">        
  16. <Button 
  17. android:text="播放" 
  18. android:id="@+id/button1" 
  19. android:layout_width="wrap_content" 
  20. android:layout_height="wrap_content">
  21. </Button>       
  22. <Button 
  23. android:text="暂停" 
  24. android:id="@+id/button2" 
  25. android:layout_width="wrap_content" 
  26. android:layout_height="wrap_content">
  27. </Button>       
  28. <Button 
  29. android:text="停止" 
  30. android:id="@+id/button3" 
  31. android:layout_width="wrap_content" 
  32. android:layout_height="wrap_content">
  33. </Button>   
  34. </LinearLayout>
  35. </LinearLayout> 

主程序:

 

  1. public class SurfaceActivity extends Activity implements SurfaceHolder.Callback {   
  2.       /** Called when the activity is first created. */    
  3.      MediaPlayer player;    
  4.      SurfaceView surface;     
  5.     SurfaceHolder surfaceHolder;     
  6.     Button play,pause,stop;     
  7.     @Override   
  8.       public void onCreate(Bundle savedInstanceState) {    
  9.         super.onCreate(savedInstanceState);        
  10.       setContentView(R.layout.main);         
  11.      play=(Button)findViewById(R.id.button1);        
  12.       pause=(Button)findViewById(R.id.button2);        
  13.       stop=(Button)findViewById(R.id.button3);         
  14.       surface=(SurfaceView)findViewById(R.id.surface);       
  15.         surfaceHolder=surface.getHolder();  //SurfaceHolder是SurfaceView的控制接口        
  16.       surfaceHolder.addCallback(this);   //因为这个类实现了SurfaceHolder.Callback接口,所以回调参数直接this         
  17.      surfaceHolder.setFixedSize(320220);  //显示的分辨率,不设置为视频默认         
  18.      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  //Surface类型          
  19.      play.setOnClickListener(new OnClickListener(){           
  20.         @Override           
  21.        public void onClick(View v) {               
  22.        player.start();           
  23.        }});        
  24.      pause.setOnClickListener(new OnClickListener(){       
  25.            @Override            
  26.       public void onClick(View v) {         
  27.              player.pause();           
  28.        }});         
  29.       stop.setOnClickListener(new OnClickListener(){       
  30.             @Override          
  31.         public void onClick(View v) {              
  32.        player.stop();          
  33.         }});    
  34.      }     
  35.      @Override    
  36.      public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {    
  37.      }     
  38.      @Override     
  39.     public void surfaceCreated(SurfaceHolder arg0) { 
  40.     //必须在surface创建后才能初始化MediaPlayer,否则不会显示图像      
  41.        player=new MediaPlayer();        
  42.       player.setAudioStreamType(AudioManager.STREAM_MUSIC);    
  43.        player.setDisplay(surfaceHolder);       
  44.       //设置显示视频显示在SurfaceView上           
  45.       try {               
  46.       player.setDataSource("/sdcard/3.mp4");         
  47.             player.prepare();             
  48.     } catch (Exception e) {             
  49.         e.printStackTrace();          
  50.        }    
  51.      }      
  52.     @Override     
  53.     public void surfaceDestroyed(SurfaceHolder arg0) {      
  54.        // TODO Auto-generated method stub   
  55.        }      
  56.     @Override    protected void onDestroy() {       
  57.       // TODO Auto-generated method stub       
  58.       super.onDestroy();        
  59.      if(player.isPlaying()){      
  60.        player.stop();        }      
  61.        player.release();       
  62.       //Activity销毁时停止播放,释放资源。不做这个操作,即使退出还是能听到视频播放的声音 
  63.         } 
  64.     }  

2.案例二

布局文件main.xml

 

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     
  3. android:orientation="vertical"     
  4. android:layout_width="fill_parent"     
  5. android:layout_height="fill_parent"     
  6. android:background="#ffffff"     
  7. <TextView   
  8.    android:layout_width="wrap_content"     
  9. android:layout_height="wrap_content"    
  10. android:text="@string/filename"     
  11. /> 
  12. <EditText  
  13. android:layout_width="fill_parent"     
  14. android:layout_height="wrap_content"    
  15. android:text="oppo.mp4"    
  16. android:id="@+id/filename"    
  17. /> 
  18. <LinearLayout     
  19. android:orientation="horizontal"    
  20. android:layout_width="fill_parent"  
  21. android:layout_height="wrap_content"    
  22. >     
  23. <ImageButton  
  24. android:layout_width="wrap_content"  
  25. android:layout_height="fill_parent"      
  26. android:src="@drawable/play"     
  27.    android:id="@+id/play"    
  28. />    
  29. <ImageButton  
  30. android:layout_width="wrap_content"   
  31. android:layout_height="fill_parent"     
  32.    android:src="@drawable/pause"         
  33. android:id="@+id/pause"     
  34. />    
  35. <ImageButton   
  36. android:layout_width="wrap_content"   
  37. android:layout_height="fill_parent"     
  38.    android:src="@drawable/stop"      
  39. android:id="@+id/stop"    
  40. />   
  41. <ImageButton  
  42. android:layout_width="wrap_content"   
  43. android:layout_height="fill_parent"    
  44. android:src="@drawable/reset"       
  45. android:id="@+id/reset"   
  46. /> 
  47. </LinearLayout> 
  48. <SurfaceView  
  49. android:layout_width="fill_parent"      
  50. android:layout_height="fill_parent"      
  51. android:id="@+id/surfaceview"   
  52. /> 
  53. </LinearLayout> 

主程序VodeoPlayActivity.java

 

  1. public class VodeoPlayActivity extends Activity {   
  2.   /** Called when the activity is first created. */    
  3.   private EditText filenamEditText;  
  4.   private MediaPlayer mediaPlayer;    
  5.   private String filename;    
  6.   private SurfaceView surfaceView;    
  7.   private final static String TAG="VodeoPlayActivity";  
  8.   private int prosition=0;        
  9.   @Override    
  10.   public void onCreate(Bundle savedInstanceState) {    
  11.   super.onCreate(savedInstanceState);     
  12.   setContentView(R.layout.main);        
  13.   filenamEditText=(EditText) this.findViewById(R.id.filename);    
  14.   surfaceView=(SurfaceView)this.findViewById(R.id.surfaceview);       
  15.   surfaceView.getHolder().setFixedSize(176144);//设置分辨率       
  16.   surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置surfaceview不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前     
  17.   surfaceView.getHolder().addCallback(new SurceCallBack());//对surface对象的状态进行监听      
  18.   mediaPlayer=new MediaPlayer();           
  19.   ButtonOnClikListiner buttonOnClikListinero=new ButtonOnClikListiner();      
  20.   ImageButton start=(ImageButton) this.findViewById(R.id.play);         
  21.   ImageButton pause=(ImageButton) this.findViewById(R.id.pause);        
  22.   ImageButton stop=(ImageButton) this.findViewById(R.id.stop);        
  23.   ImageButton replay=(ImageButton) this.findViewById(R.id.reset);      
  24.   start.setOnClickListener(buttonOnClikListinero);     
  25.   pause.setOnClickListener(buttonOnClikListinero);     
  26.   stop.setOnClickListener(buttonOnClikListinero);      
  27.   replay.setOnClickListener(buttonOnClikListinero);    
  28.   }      
  29.   private final class ButtonOnClikListiner implements View.OnClickListener{      
  30.   @Override    
  31.   public void onClick(View v) {    
  32.   if(Environment.getExternalStorageState()==Environment.MEDIA_UNMOUNTED){       
  33.   Toast.makeText(VodeoPlayActivity.this"sd卡不存在", Toast.LENGTH_SHORT).show();             
  34.   return;       
  35.   }         
  36.   filename=filenamEditText.getText().toString();         
  37.   switch (v.getId()) {         
  38.   case R.id.play:             
  39.   play();                
  40.   break;          
  41.   case R.id.pause:          
  42.   if(mediaPlayer.isPlaying()){       
  43.   mediaPlayer.pause();            
  44.   }else{                   
  45.   mediaPlayer.start();         
  46.   }                 
  47.   break;          
  48.   case R.id.reset:         
  49.   if(mediaPlayer.isPlaying()){    
  50.   mediaPlayer.seekTo(0);             
  51.   }else{              
  52.   play();              
  53.   }               
  54.   break;            
  55.   case R.id.stop:          
  56.   if(mediaPlayer.isPlaying()){    
  57.   mediaPlayer.stop();             
  58.   }               
  59.   break;            
  60.   }        
  61.   }      
  62.   }       
  63.   private void play() {     
  64.   try {                
  65.   File file=new File(Environment.getExternalStorageDirectory(),filename);        
  66.   mediaPlayer.reset();//重置为初始状态         
  67.   mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置音乐流的类型            
  68.   mediaPlayer.setDisplay(surfaceView.getHolder());//设置video影片以surfaceviewholder播放       
  69.   mediaPlayer.setDataSource(file.getAbsolutePath());//设置路径             
  70.   mediaPlayer.prepare();//缓冲                
  71.   mediaPlayer.start();//播放            
  72.   } catch (Exception e) {         
  73.   Log.e(TAG, e.toString());                
  74.   e.printStackTrace();            
  75.   }     
  76.   }      
  77.   private final class SurceCallBack implements SurfaceHolder.Callback{    
  78.   /**         * 画面修改         */        
  79.   @Override        
  80.   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  81.   // TODO Auto-generated method stub                
  82.   }       
  83.   /**         * 画面创建         */     
  84.   @Override        
  85.   public void surfaceCreated(SurfaceHolder holder) {           
  86.   if(prosition>0&&filename!=null){            
  87.   play();               
  88.   mediaPlayer.seekTo(prosition);            
  89.   prosition=0;            }          
  90.   }      
  91.   /**         * 画面销毁         */        
  92.   @Override        
  93.   public void surfaceDestroyed(SurfaceHolder holder) {      
  94.   if(mediaPlayer.isPlaying()){        
  95.   prosition=mediaPlayer.getCurrentPosition();          
  96.   mediaPlayer.stop();         
  97.   }        
  98.   }    
  99.   } 
  100.   } 

 

责任编辑:张叶青 来源: Devin Zhang博客园
相关推荐

2014-10-20 09:55:02

2024-03-14 08:24:25

MediaCodec解码播放Android

2022-08-26 12:13:08

APIjavascript视频

2022-03-06 20:02:21

监听视频播放

2011-07-20 16:21:20

iPhone 视频 播放器

2011-08-17 14:57:31

iPhone应用视频播放

2021-08-30 07:49:32

Javascript西瓜视频

2022-06-20 05:59:35

5G技术音视频技术安卓系统

2021-08-25 07:43:17

AndroidSurfaceViewTextureView

2021-03-17 15:49:03

鸿蒙HarmonyOS应用

2021-08-26 07:38:41

AndroidMediaPlayerTextureView

2023-08-26 19:07:40

VLC旋转视频

2021-10-29 07:49:23

Python弹幕播放

2022-08-16 17:37:06

视频播放器鸿蒙

2011-08-10 15:58:58

iPhone视频

2022-04-26 14:33:21

鸿蒙操作系统

2022-04-15 11:30:59

代码,Python保存视频

2013-05-20 17:48:20

2013-05-21 13:33:02

Android游戏开发异步音乐播放

2011-06-13 10:44:44

Qt Flash
点赞
收藏

51CTO技术栈公众号