Android使用SurfaceView實(shí)現(xiàn)視頻播放
作者:佚名
SurfaceView的特性是:可以在主線程之外的線程中向屏幕繪圖上。這樣可以避免畫(huà)圖任務(wù)繁重的時(shí)候造成主線程阻塞,從而提高了程序的反應(yīng)速度。在游戲開(kāi)發(fā)中多用到SurfaceView,游戲中的背景、人物、動(dòng)畫(huà)等等盡量在畫(huà)布canvas中畫(huà)出。
1.案例一
布局文件:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="fill_parent"
- android:layout_height="fill_parent" android:weightSum="1">
- <SurfaceView
- android:layout_height="220dip"
- android:layout_gravity="center"
- android:id="@+id/surface"
- android:layout_weight="0.25"
- android:layout_width="320dip">
- </SurfaceView>
- <LinearLayout
- android:id="@+id/linearLayout1"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent">
- <Button
- android:text="播放"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- </Button>
- <Button
- android:text="暫停"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- </Button>
- <Button
- android:text="停止"
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- </Button>
- </LinearLayout>
- </LinearLayout>
主程序:
- public class SurfaceActivity extends Activity implements SurfaceHolder.Callback {
- /** Called when the activity is first created. */
- MediaPlayer player;
- SurfaceView surface;
- SurfaceHolder surfaceHolder;
- Button play,pause,stop;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- play=(Button)findViewById(R.id.button1);
- pause=(Button)findViewById(R.id.button2);
- stop=(Button)findViewById(R.id.button3);
- surface=(SurfaceView)findViewById(R.id.surface);
- surfaceHolder=surface.getHolder(); //SurfaceHolder是SurfaceView的控制接口
- surfaceHolder.addCallback(this); //因?yàn)檫@個(gè)類實(shí)現(xiàn)了SurfaceHolder.Callback接口,所以回調(diào)參數(shù)直接this
- surfaceHolder.setFixedSize(320, 220); //顯示的分辨率,不設(shè)置為視頻默認(rèn)
- surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //Surface類型
- play.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- player.start();
- }});
- pause.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- player.pause();
- }});
- stop.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View v) {
- player.stop();
- }});
- }
- @Override
- public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
- }
- @Override
- public void surfaceCreated(SurfaceHolder arg0) {
- //必須在surface創(chuàng)建后才能初始化MediaPlayer,否則不會(huì)顯示圖像
- player=new MediaPlayer();
- player.setAudioStreamType(AudioManager.STREAM_MUSIC);
- player.setDisplay(surfaceHolder);
- //設(shè)置顯示視頻顯示在SurfaceView上
- try {
- player.setDataSource("/sdcard/3.mp4");
- player.prepare();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder arg0) {
- // TODO Auto-generated method stub
- }
- @Override protected void onDestroy() {
- // TODO Auto-generated method stub
- super.onDestroy();
- if(player.isPlaying()){
- player.stop(); }
- player.release();
- //Activity銷毀時(shí)停止播放,釋放資源。不做這個(gè)操作,即使退出還是能聽(tīng)到視頻播放的聲音
- }
- }
2.案例二
布局文件main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#ffffff"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/filename"
- />
- <EditText
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="oppo.mp4"
- android:id="@+id/filename"
- />
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- >
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:src="@drawable/play"
- android:id="@+id/play"
- />
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:src="@drawable/pause"
- android:id="@+id/pause"
- />
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:src="@drawable/stop"
- android:id="@+id/stop"
- />
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:src="@drawable/reset"
- android:id="@+id/reset"
- />
- </LinearLayout>
- <SurfaceView
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:id="@+id/surfaceview"
- />
- </LinearLayout>
主程序VodeoPlayActivity.java
- public class VodeoPlayActivity extends Activity {
- /** Called when the activity is first created. */
- private EditText filenamEditText;
- private MediaPlayer mediaPlayer;
- private String filename;
- private SurfaceView surfaceView;
- private final static String TAG="VodeoPlayActivity";
- private int prosition=0;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- filenamEditText=(EditText) this.findViewById(R.id.filename);
- surfaceView=(SurfaceView)this.findViewById(R.id.surfaceview);
- surfaceView.getHolder().setFixedSize(176, 144);//設(shè)置分辨率
- surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//設(shè)置surfaceview不維護(hù)自己的緩沖區(qū),而是等待屏幕的渲染引擎將內(nèi)容推送到用戶面前
- surfaceView.getHolder().addCallback(new SurceCallBack());//對(duì)surface對(duì)象的狀態(tài)進(jìn)行監(jiān)聽(tīng)
- mediaPlayer=new MediaPlayer();
- ButtonOnClikListiner buttonOnClikListinero=new ButtonOnClikListiner();
- ImageButton start=(ImageButton) this.findViewById(R.id.play);
- ImageButton pause=(ImageButton) this.findViewById(R.id.pause);
- ImageButton stop=(ImageButton) this.findViewById(R.id.stop);
- ImageButton replay=(ImageButton) this.findViewById(R.id.reset);
- start.setOnClickListener(buttonOnClikListinero);
- pause.setOnClickListener(buttonOnClikListinero);
- stop.setOnClickListener(buttonOnClikListinero);
- replay.setOnClickListener(buttonOnClikListinero);
- }
- private final class ButtonOnClikListiner implements View.OnClickListener{
- @Override
- public void onClick(View v) {
- if(Environment.getExternalStorageState()==Environment.MEDIA_UNMOUNTED){
- Toast.makeText(VodeoPlayActivity.this, "sd卡不存在", Toast.LENGTH_SHORT).show();
- return;
- }
- filename=filenamEditText.getText().toString();
- switch (v.getId()) {
- case R.id.play:
- play();
- break;
- case R.id.pause:
- if(mediaPlayer.isPlaying()){
- mediaPlayer.pause();
- }else{
- mediaPlayer.start();
- }
- break;
- case R.id.reset:
- if(mediaPlayer.isPlaying()){
- mediaPlayer.seekTo(0);
- }else{
- play();
- }
- break;
- case R.id.stop:
- if(mediaPlayer.isPlaying()){
- mediaPlayer.stop();
- }
- break;
- }
- }
- }
- private void play() {
- try {
- File file=new File(Environment.getExternalStorageDirectory(),filename);
- mediaPlayer.reset();//重置為初始狀態(tài)
- mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//設(shè)置音樂(lè)流的類型
- mediaPlayer.setDisplay(surfaceView.getHolder());//設(shè)置video影片以surfaceviewholder播放
- mediaPlayer.setDataSource(file.getAbsolutePath());//設(shè)置路徑
- mediaPlayer.prepare();//緩沖
- mediaPlayer.start();//播放
- } catch (Exception e) {
- Log.e(TAG, e.toString());
- e.printStackTrace();
- }
- }
- private final class SurceCallBack implements SurfaceHolder.Callback{
- /** * 畫(huà)面修改 */
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- // TODO Auto-generated method stub
- }
- /** * 畫(huà)面創(chuàng)建 */
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- if(prosition>0&&filename!=null){
- play();
- mediaPlayer.seekTo(prosition);
- prosition=0; }
- }
- /** * 畫(huà)面銷毀 */
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- if(mediaPlayer.isPlaying()){
- prosition=mediaPlayer.getCurrentPosition();
- mediaPlayer.stop();
- }
- }
- }
- }
責(zé)任編輯:張葉青
來(lái)源:
Devin Zhang博客園