Android播放视频之MediaPlayer和SurfaceView

通过前面一文Android播放视频之VideoView可以知道,Android播放视频是通过MediaPlayer加SurfaceView来实现的,VideoView能够播放视频是因为它将MediaPlayer已经封装在内部了,我们调用VideoView的start(),pause(),seekTo()等函数其实都是在调用MediaPlayer的相关函数。

关于Mediaplayer这个类概况,参考官方文档:https://developer.android.com/reference/android/media/MediaPlayer.html

Mediaplayer可以播放音频文件,播放音频文件就不需要图像输出了,所以不用SurfaceView,直接播放即可。

MediaPlayer播放视频文件,需要有输出图像数据,就需要结合SurfaceView。

所以如果想定制个性化的视频播放器,则可以使用MediaPlayer和SurfaceView来实现。

MediaPlayer的使用重点是要管理好MediaPlayer生命周期的每个状态,在某些状态下,有些操作不能执行,否则就会发生error。

下面就一个简单的demo,看看MediaPlayer的使用。

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cj.com.mediaplayerdemo2.MainActivity">
    <SurfaceView
        android:id="@+id/surfaceview"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <CheckBox
                android:checked="true"
                android:background="@drawable/checkbox_drawable"
                android:button="@null"
                android:layout_centerHorizontal="true"
                android:id="@+id/play_or_pause"
                android:layout_width="50dp"
                android:layout_height="50dp" />
            <Button
                android:layout_marginLeft="20dp"
                android:background="@drawable/btn_playback_pre"
                android:id="@+id/pre"
                android:layout_width="50dp"
                android:layout_height="50dp" />

            <Button
                android:layout_marginRight="20dp"
                android:layout_alignParentRight="true"
                android:background="@drawable/btn_playback_next"
                android:id="@+id/next"
                android:layout_width="50dp"
                android:layout_height="50dp" />
        </RelativeLayout>

        <LinearLayout
            android:id="@+id/ll"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/tv1"
                android:layout_marginLeft="5dp"
                android:text="00:00"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <SeekBar
                android:layout_weight="1"
                android:id="@+id/seek_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
            <TextView
                android:id="@+id/tv2"
                android:layout_marginRight="5dp"
                android:text="00:08"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>

    </LinearLayout>

</LinearLayout>
实际效果:


protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        playOrPause = (CheckBox) findViewById(R.id.play_or_pause);
        pre = (Button) findViewById(R.id.pre);
        next = (Button) findViewById(R.id.next);
        currentTime = (TextView) findViewById(R.id.tv1);
        sumTime = (TextView) findViewById(R.id.tv1);
        progressBar = (SeekBar) findViewById(R.id.seek_bar);
        ll = (LinearLayout) findViewById(R.id.ll);
        ll.setVisibility(View.INVISIBLE);
        surfaceHolder = surfaceView.getHolder();

        playOrPause.setOnCheckedChangeListener(this);
        surfaceHolder.addCallback(this);
        initMediaPlayer();
    }

    private void initMediaPlayer() {
        Log.d(TAG,"initMediaPlayer");
        try {
            mediaPlayer = new MediaPlayer();//idle 状态
            mediaPlayer.setDataSource(path);//initialized状态
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mediaPlayer.setDisplay(holder);
            mediaPlayer.prepare();//prepared状态
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

mediaPlayer.setDisplay(holder);这句代码很关键

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(buttonView.getId() == R.id.play_or_pause){
            if(isChecked){//暂停
                currentPosition = mediaPlayer.getCurrentPosition();
                mediaPlayer.pause();
            }else {//播放
                mediaPlayer.seekTo(currentPosition);
                mediaPlayer.start();
                ll.setVisibility(View.VISIBLE);
                //设置时间相关参数
            }
        }
    }

调用start()函数开始播放,设置进度条及当前时间就没去做了,前面一文已经处理过了,可以去看看。

退出的时候,别忘了释放MediaPlayer资源

 protected void onDestroy() {
        super.onDestroy();
        if(mediaPlayer.isPlaying()){
            mediaPlayer.stop();
        }
        mediaPlayer.release();
        mediaPlayer = null;
    }

这个demo只是简单的描述了使用MediaPlayer播放视频的过程。

关于MediaPlayer的状态图解析,

参考http://www.csdn123.com/html/topnews201408/88/1288.htm。能看官方英文文档当然最好了。






你可能感兴趣的:(mediaplayer,SurfaceView)