Androidx学习笔记(78)--- 视频播放器(MediaPlayer+SurfaceView)

来源:互联网 发布:distinct在MySQL的用法 编辑:程序博客网 时间:2024/05/29 16:48

SurfaceView

  • 双缓冲技术
  • 该组件是重量级组件:占用资源比较多
    • 只要不可见,就不会创建,可见时,才会创建
    • 只要不可见,就会销毁

FFMPEG

  • 开源免费的音视频编解码器

Vitamio

  • 封装了FFMPEG的视频播放框架
  • 对外提供的api全部都是javaApi

SurfaceView

  • 对画面的实时更新要求较高
  • 双缓冲技术:内存中有两个画布,A画布显示至屏幕,B画布在内存中绘制下一帧画面,绘制完毕后B显示至屏幕,A在内存中继续绘制下一帧画面
  • 播放视频也是用MediaPlayer,不过跟音频不同,要设置显示在哪个SurfaceView

    SurfaceView sv = (SurfaceView) findViewById(R.id.sv);SurfaceHolder sh = sv.getHolder();MediaPlayer player = new MediaPlayer();player.reset();try {    player.setDataSource("sdcard/2.3gp");    player.setDisplay(sh);    player.prepare();} catch (Exception e) {    e.printStackTrace();}player.start();
  • SurfaceView是重量级组件,可见时才会创建
  • 给SurfaceHolder设置CallBack,类似于侦听,可以知道SurfaceView的状态

    sh.addCallback(new Callback() {    //SurfaceView销毁时调用    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        // TODO Auto-generated method stub    }    //SurfaceView创建时调用    @Override    public void surfaceCreated(SurfaceHolder holder) {        // TODO Auto-generated method stub    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width,            int height) {        // TODO Auto-generated method stub    }});
  • SurfaceView一旦不可见,就会被销毁,一旦可见,就会被创建,销毁时停止播放,再次创建时再开始播放

布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
 
<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
 
</RelativeLayout>


java代码
public class MainActivity extends Activity {
private MediaPlayer player;
static int currentPosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SurfaceView sv = (SurfaceView) findViewById(R.id.sv);
//拿到surfaceview的控制器
final SurfaceHolder sh = sv.getHolder();
//使用固定的等待时间 让SurfaceView可见---不合理的
//Thread t = new Thread(){
//@Override
//public void run() {
//// TODO Auto-generated method stub
//try {
//sleep(200);
//} catch (InterruptedException e) {
//// TODO Auto-generated catch block
//e.printStackTrace();
//}
//runOnUiThread(new Runnable() {
//@Override
//public void run() {
//MediaPlayer player = new MediaPlayer();
//player.reset();
//try {
//player.setDataSource("sdcard/2.3gp");
//player.setDisplay(sh);
//player.prepare();
//player.start();
//} catch (Exception e) {
//// TODO Auto-generated catch block
//e.printStackTrace();
//}
//
//}
//});
//
//}
//};
//t.start();
//使用监听的方式 让SurfaceView可见
sh.addCallback(new Callback() {
//surfaceView销毁时调用
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//每次surfaceview销毁时,同时停止播放视频
if(player != null){
currentPosition = player.getCurrentPosition();
player.stop();
player.release();
player = null;
}
}
//surfaceView创建时调用
@Override
public void surfaceCreated(SurfaceHolder holder) {
//每次surfaceView创建时才去播放视频
if(player == null){
player = new MediaPlayer();
player.reset();
try {
player.setDataSource("sdcard/2.3gp");
player.setDisplay(sh);
player.prepare();
player.start();
player.seekTo(currentPosition);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//surfaceView结构改变时调用
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
});
}
 
 
}
0 0
原创粉丝点击