Androidx learning notes (78) — Video Player (MediaPlayer + SurfaceView)

SurfaceView

  • Double buffering technology
  • This component is a heavyweight component: it takes up more resources
    • As long as it is not visible, it will not be created. When it is visible, it will be created
    • As long as it is not visible, it will be destroyed

FFMPEG

  • open source and free audio and video codec

Vitamio

  • Encapsulates the FFMPEG video playback framework
  • All external APIs are javaApi
  • ul>

    SurfaceView

    • Requires high real-time update of the screen
    • Double buffering technology: memory There are two canvases in the middle. Canvas A is displayed on the screen, and Canvas B draws the next frame in the memory. After drawing, B is displayed on the screen, and A continues to draw the next frame in the memory.
    • the same goes for playing video Use MediaPlayer, but different from audio, you need to set which SurfaceView is displayed on

      SurfaceView sv = (SurfaceView) findViewById(R.id.sv);SurfaceHolder sh = sv.getHolder();M ediaPlayer player = new MediaPlayer();player.reset();try {player.setDataSource("sdcard/2.3gp"); player.setDisplay(sh); player.prepare();} catch (Exception e) {e. printStackTrace();}player.start();
    • SurfaceView is a heavyweight component and will be created only when it is visible li>
    • Set CallBack to SurfaceHolder, similar to listening, you can know the status of SurfaceView

      sh.addCallback(new Callback() {//Call @Override when SurfaceView is destroyed public void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub} //Call @Override public void surfaceCre when SurfaceView is created ated(SurfaceHolder holder) {// TODO Auto-generated method stub} @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// TODO Auto-generated method stub }});
    • Once the SurfaceView is invisible, it will be destroyed, once it is visible, it will be created, stop playing when it is destroyed, and start again when it is created again Play
    Layout file
     
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools " android:layout_width< /span>="match_parent " android:layout_height< /span>="match_parent " android:paddingBottom< /span>="@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 " > android :id="@+id/sv" android:layout_width="match_parent" android:layout_height="match_parent" />

    < br>
    java code
     
    make SurfaceView visible
    public class MainActivity extends Activity { private MediaPlayer player; static int currentPosition; @Override protected void< span class="pln" style="color:rgb(72,72,76)"> onCreate(< span class="typ" style="color:teal">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 MediaPl ayer();// 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(); //使用监听的方式 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 } }); }  }

    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一旦不可见,就会被销毁,一旦可见,就会被创建,销毁时停止播放,再次创建时再开始播放

    布局文件

            
    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" >  android:id="@+id/sv" android:layout_width="match_parent" android:layout_height="match_parent" /> 

           
    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" >  android:id="@+id/sv" android:layout_width= "match_parent" android:layout_height="match_parent" /> 

    java代码

            
    让SurfaceView可见
    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< span class="pln" style="color:rgb(72,72,76)"> 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(); //使用监听的方式 sh.addCallback(new Callback() { //surfaceView销毁时调用 @Override public void surfaceDestroyed(SurfaceHolder holder) { //每次surfaceview销毁时,同时停止播放视频 if(player != null){ currentPosition = player.getCurrentPosition(); player.stop(); player.re lease(); 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 } }); }  }

           
    让SurfaceView可见
    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();// }// run OnUiThread(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(); //使用监听的方式 sh.addCallback(new Callback() { //surfaceView销毁时调用 @Override public void surfaceDestroyed(SurfaceHolder holder) { //每次surfaceview销毁时,同时停止播放视频 if(player != null){ currentPosition = player.< span class="pln" style="color:rgb(72,72,76)">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.p rintStackTrace(); } } } //surfaceView结构改变时调用 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } }); }  }

    让SurfaceView可见

    让SurfaceView可见

Leave a Comment

Your email address will not be published.