surfaceView初步学习,播放在线视频和本地视频
这里只基本介绍如何播放视频:surfaceview是利用双缓冲区的原理来使得用户可以流畅的观看视频的:
比如A、B缓冲区,先由A缓冲区填满推送到设备播放,然后再A播放的时候填满B缓冲区,等A播放完了就播放B缓冲区的内容,如此交换执行。
public class MainActivity extends ActionBarActivity { private SurfaceHolder holder; private SurfaceView sf; private MediaPlayer mediaplayer; private String path; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sf=(SurfaceView) findViewById(R.id.sf); holder= sf.getHolder(); // 这里是设置surfaceview不维护自己的缓冲区而是等待屏幕的渲染引擎将视频推送到用户面前 } public void start(View v) { mediaplayer =new MediaPlayer(); mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); // path="data/data/musics/oppo.3gp"; path="http://192.168.61.173:8080/mymusics/oppo.3gp"; try { mediaplayer.setDataSource(path); mediaplayer.setDisplay(holder); //设置视频在哪里播放,holder即surfaceview空间里。
// mediaplayer.prepareAsync(); // mediaplayer.setOnPreparedListener(new MypreparedListener()); mediaplayer.prepare(); mediaplayer.start(); } catch (Exception e) { e.printStackTrace(); } } class MypreparedListener implements OnPreparedListener { @Override public void onPrepared(MediaPlayer mp) { mediaplayer.start(); } } }
注意surfaceview在不可见时候为了节约系统资源,系统会销毁掉surferview的holder,当再次可见的时候新创建,因此在播放的时候如果按Home键,再进来的时候会发现只有声音而无图像了。总而言之我们可以根据holder的生命周期,在它销毁的时候记住视频播放的位置,然后进去的时候切换到播放的位置,具体看代码:
public class MainActivity extends ActionBarActivity { private SurfaceHolder holder; private SurfaceView sf; private MediaPlayer mediaplayer; private String path; private int position=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sf=(SurfaceView) findViewById(R.id.sf); holder= sf.getHolder(); holder.addCallback(new MyCallback()); //回调出holder的生命周期,相当于监听器 } class MyCallback implements Callback //实现生命周期的操作接口 { @Override public void surfaceCreated(SurfaceHolder holder) { System.out.println("on create!"); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("on change!"); } @Override public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("on destroy!"); position=mediaplayer.getCurrentPosition();//记下销毁的位置 } } public void start(View v) { mediaplayer =new MediaPlayer(); mediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC); path="data/data/musics/oppo.3gp"; // path="http://192.168.61.173:8080/mymusics/oppo.3gp"; try { mediaplayer.setDataSource(path); mediaplayer.setDisplay(holder); mediaplayer.prepare(); } catch (Exception e) { e.printStackTrace(); } mediaplayer.seekTo(position); // 跳转到position位置播放 mediaplayer.start(); } }