Android多媒体功能开发(9)——使用SurfaceView控件+MediaPlayer类播放视频

使用SurfaceView控件+MediaPlayer类播放视频的主要原理是把MediaPlayer对象的显示控件设置为SurfaceView对象。播放控制都是针对MediaPlayer对象,用法与播放音频相同。主要流程和对应的代码如下图:

播放视频的流程只是比播放音频多了设置显示控件一步。

下面编写一个用SurfaceView+MediaPlayer播放视频的例子。例子使用资源ID方式作为MediaPlayer的视频源,所以需将视频文件demo.mp4复制到项目的res/raw目录下。应用的界面和对应的主要代码如下:


为MediaPlayer设置显示控件时需要注意:不能在onCreate中设置,因为SurfaceView控件还未准备好,需要延迟一段时间再设置。因此,这个例子中在PLAY按钮按下时再设置。

要通过下面的语句设置视频分辨率,不然会根据窗口尺寸拉伸:

surfaceView.getHolder().setFixedSize(1080, 720); 

视频显示尺寸(1080, 720)是根据SurfaceView在界面上尺寸和视频实际尺寸(640, 360)计算得出。

播放控制都是针对MediaPlayer对象,用法与播放音频相同。例子中还用SeekBar控件来显示播放进度,控制播放位置。

例子的完整代码如下:

public class MainActivity extends AppCompatActivity {
    SurfaceView surfaceView;
    MediaPlayer player;
    SeekBar seekBar;
    Handler handler;
    Runnable runnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
        setContentView(ll);

        Button btnPlay = new Button(this);
        btnPlay.setText("Play");
        ll.addView(btnPlay);
        btnPlay.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                player.setDisplay(surfaceView.getHolder());
                player.start();
                startTimer();
            }
        });
        Button btnStop = new Button(this);
        btnStop.setText("Stop");
        ll.addView(btnStop);
        btnStop.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                //player.stop();	// stop后player对象不能再播放
                player.pause();
                player.seekTo(0);
                stopTimer();
            }
        });
        Button btnPause = new Button(this);
        btnPause.setText("Pause");
        ll.addView(btnPause);
        btnPause.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                if(player.isPlaying()){
                    player.pause();
                    stopTimer();
                    ((Button)arg0).setText("Continue");
                } else {
                    player.start();
                    startTimer();
                    ((Button)arg0).setText("Pause");
                }
            }
        });
        Button btnReset = new Button(this);
        btnReset.setText("Reset");
        ll.addView(btnReset);
        btnReset.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View arg0) {
                //player.reset();	// reset后需要重新设置视频来源
                player.seekTo(0);
            }
        });

        player = MediaPlayer.create(this, R.raw.demo);
        surfaceView = new SurfaceView(this);
        surfaceView.getHolder().setFixedSize(1080, 720);
        //player.setDisplay(surfaceView.getHolder()); // 不能在此设置,因为surfaceView还未准备好,在play按钮按下时再设置即可
        ll.addView(surfaceView);

        seekBar = new SeekBar(this);
        seekBar.setMax(100);
        ll.addView(seekBar);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
            @Override
            public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
            }

            @Override
            public void onStartTrackingTouch(SeekBar arg0) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar arg0) {
                int pos = seekBar.getProgress() * player.getDuration() / seekBar.getMax();
                player.seekTo(pos);
            }
        });

        player.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
            @Override
            public void onCompletion(MediaPlayer arg0) {
                stopTimer();
            }
        });

        initTimer();
    }

    protected void onDestroy(){
        super.onDestroy();
        stopTimer();
        player.release();
    }

    void initTimer(){
        handler = new Handler();
        runnable = new Runnable(){
            @Override
            public void run() {
                int d = player.getDuration();
                int p = player.getCurrentPosition();
                seekBar.setProgress(p*seekBar.getMax()/d);
                handler.postDelayed(runnable, 1000);
            }
        };
    }
    void startTimer(){
        handler.postDelayed(runnable, 1000);
    }
    void stopTimer(){
        handler.removeCallbacks(runnable);
    }
}

例子中用到的主要的类有SurfaceView、MediaPlayer,接口有SurfaceHolder。

用到的SurfaceView类的方法有:

  • 构造函数SurfaceView(Context context),通过Context创建SurfaceView对象。
  • SurfaceHolder getHolder (),得到SurfaceHolder对象用于管理SurfaceView

用到的MediaPlayer类的新的方法是:

  • void setDisplay(SurfaceHolder sh),用于设置显示视频的UI控件SurfaceHolder。

用到的SurfaceHolder接口的方法有:

  • void setFixedSize(int width, int height),设置视频尺寸,用视频的实际尺寸即可
  • void setKeepScreenOn(boolean screenOn),设置视频播放时是否保持屏幕常亮

猜你喜欢

转载自blog.csdn.net/nanoage/article/details/127406767