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
- 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
- 对画面的实时更新要求较高
- 双缓冲技术:内存中有两个画布,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一旦不可见,就会被销毁,一旦可见,就会被创建,销毁时停止播放,再次创建时再开始播放
ul>
SurfaceView
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
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.resetmake SurfaceView visible(); 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
布局文件
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代码
public class MainActivity extends Activity { private MediaPlayer player; static span>int currentPosition; @Override protected void onCreate(Bundle savedInstanceState) {让SurfaceView可见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销毁时调用 @Overridepublic 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 } }); } }
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();让SurfaceView可见// } // // }// });// // }// };// t.start(); //使用监听的方式 sh.addCallback(new span>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可见