Android中SurfaceView视频播放实现代码
- 作者: 神奇段哥
- 来源: 51数据库
- 2020-08-17
SurfaceView的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。
1.案例一
布局文件:
<?xml?version="1.0"?encoding="utf-8"?> <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"? android:orientation="vertical"?android:layout_width="fill_parent" ?? ?android:layout_height="fill_parent"?android:weightSum="1"> ? ? <SurfaceView? android:layout_height="220dip" android:layout_gravity="center"? android:id="@+id/surface"? android:layout_weight="0.25"? android:layout_width="320dip"> </SurfaceView> ? ? <LinearLayout android:id="@+id/linearLayout1"? android:layout_height="wrap_content" android:layout_width="fill_parent"> ? ? ? ? <Button? android:text="播放"? android:id="@+id/button1"? android:layout_width="wrap_content"? android:layout_height="wrap_content"> </Button> ? ? ?? <Button? android:text="暂停"? android:id="@+id/button2"? android:layout_width="wrap_content"? android:layout_height="wrap_content"> </Button> ? ? ?? <Button? android:text="停止"? android:id="@+id/button3"? android:layout_width="wrap_content"? android:layout_height="wrap_content"> </Button> ?? </LinearLayout> </LinearLayout>
主程序:
public?class?SurfaceActivity?extends?Activity?implements?SurfaceHolder.Callback?{ ??
? ? ? /**?Called?when?the?activity?is?first?created.?*/ ? ?
? ? ?MediaPlayer?player; ? ?
? ? ?SurfaceView?surface; ? ??
? ? SurfaceHolder?surfaceHolder; ? ??
? ? Button?play,pause,stop; ? ??
? ? @Override ??
? ? ? public?void?onCreate(Bundle?savedInstanceState)?{ ? ?
? ? ? ? super.onCreate(savedInstanceState); ? ? ? ?
? ? ? setContentView(R.layout.main); ? ? ? ??
? ? ?play=(Button)findViewById(R.id.button1); ? ? ? ?
? ? ? pause=(Button)findViewById(R.id.button2); ? ? ? ?
? ? ? stop=(Button)findViewById(R.id.button3); ? ? ? ??
? ? ? surface=(SurfaceView)findViewById(R.id.surface); ? ? ??
? ? ? ? surfaceHolder=surface.getHolder();//SurfaceHolder是SurfaceView的控制接口 ? ? ? ?
? ? ? surfaceHolder.addCallback(this);?//因为这个类实现了SurfaceHolder.Callback接口,所以回调参数直接this ? ? ? ??
? ? ?surfaceHolder.setFixedSize(320,?220);//显示的分辨率,不设置为视频默认 ? ? ? ??
? ? ?surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//Surface类型 ? ? ? ? ?
? ? ?play.setOnClickListener(new?OnClickListener(){ ? ? ? ? ??
? ? ? ? @Override ? ? ? ? ??
? ? ? ?public?void?onClick(View?v)?{ ? ? ? ? ? ? ??
? ? ? ?player.start(); ? ? ? ? ??
? ? ? ?}}); ? ? ? ?
? ? ?pause.setOnClickListener(new?OnClickListener(){ ? ? ??
? ? ? ? ? ?@Override ? ? ? ? ? ?
? ? ? public?void?onClick(View?v)?{ ? ? ? ??
? ? ? ? ? ? ?player.pause(); ? ? ? ? ??
? ? ? ?}}); ? ? ? ??
? ? ? stop.setOnClickListener(new?OnClickListener(){ ? ? ??
? ? ? ? ? ? @Override ? ? ? ? ?
? ? ? ? public?void?onClick(View?v)?{ ? ? ? ? ? ? ?
? ? ? ?player.stop(); ? ? ? ? ?
? ? ? ? }}); ? ?
? ? ?} ? ??
? ? ?@Override ? ?
? ? ?public?void?surfaceChanged(SurfaceHolder?arg0,?int?arg1,?int?arg2,?int?arg3)?{ ? ?
? ? ?} ? ??
? ? ?@Override ? ??
? ? public?void?surfaceCreated(SurfaceHolder?arg0)?{?
? ? //必须在surface创建后才能初始化MediaPlayer,否则不会显示图像 ? ? ?
? ? ? ?player=new?MediaPlayer(); ? ? ? ?
? ? ? player.setAudioStreamType(AudioManager.STREAM_MUSIC); ? ?
? ? ? ?player.setDisplay(surfaceHolder); ? ? ??
? ? ? //设置显示视频显示在SurfaceView上 ? ? ? ? ??
? ? ? try?{ ? ? ? ? ? ? ??
? ? ? player.setDataSource("/sdcard/3.mp4"); ? ? ? ??
? ? ? ? ? ? player.prepare(); ? ? ? ? ? ??
? ? }?catch?(Exception?e)?{ ? ? ? ? ? ??
? ? ? ? e.printStackTrace(); ? ? ? ? ?
? ? ? ?} ? ?
? ? ?} ? ? ?
? ? @Override ? ??
? ? public?void?surfaceDestroyed(SurfaceHolder?arg0)?{ ? ? ?
? ? ? ?//?TODO?Auto-generated?method?stub ??
? ? ? ?} ? ? ?
? ? @Override????protected?void?onDestroy()?{ ? ? ??
? ? ? //?TODO?Auto-generated?method?stub ? ? ??
? ? ? super.onDestroy(); ? ? ? ?
? ? ?if(player.isPlaying()){ ? ? ?
? ? ? ?player.stop();????????} ? ? ?
? ? ? ?player.release(); ? ? ??
? ? ? //Activity销毁时停止播放,释放资源。不做这个操作,即使退出还是能听到视频播放的声音?
? ? ? ? }?
? ? }
2.案例二
布局文件main.xml
<?xml?version="1.0"?encoding="utf-8"?>? <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android" ? ?? android:orientation="vertical" ? ?? android:layout_width="fill_parent" ? ?? android:layout_height="fill_parent" ? ?? android:background="#ffffff" ? ?? >? <TextView ?? ? ?android:layout_width="wrap_content" ? ?? android:layout_height="wrap_content" ? ? android:text="@string/filename" ? ?? />? <EditText ? android:layout_width="fill_parent" ? ?? android:layout_height="wrap_content" ? ? android:text="oppo.mp4" ? ? android:id="@+id/filename" ? ? />? <LinearLayout ? ?? android:orientation="horizontal" ? ? android:layout_width="fill_parent" ? android:layout_height="wrap_content" ? ? > ? ?? <ImageButton ? android:layout_width="wrap_content" ? android:layout_height="fill_parent" ? ? ? android:src="@drawable/play" ? ?? ? ?android:id="@+id/play" ? ? /> ? ? <ImageButton ? android:layout_width="wrap_content" ?? android:layout_height="fill_parent" ? ?? ? ?android:src="@drawable/pause" ? ? ? ?? android:id="@+id/pause" ? ?? /> ? ? <ImageButton ?? android:layout_width="wrap_content" ?? android:layout_height="fill_parent" ? ?? ? ?android:src="@drawable/stop" ? ? ? android:id="@+id/stop" ? ? /> ?? <ImageButton ? android:layout_width="wrap_content" ?? android:layout_height="fill_parent" ? ? android:src="@drawable/reset" ? ? ?? android:id="@+id/reset" ?? />? </LinearLayout>? <SurfaceView ? android:layout_width="fill_parent" ? ? ? android:layout_height="fill_parent" ? ? ? android:id="@+id/surfaceview" ?? />? </LinearLayout>
主程序VodeoPlayActivity.java
public?class?VodeoPlayActivity?extends?Activity?{ ??
? /**?Called?when?the?activity?is?first?created.?*/ ? ?
? private?EditText?filenamEditText; ?
? private?MediaPlayer?mediaPlayer; ? ?
? private?String?filename; ? ?
? private?SurfaceView?surfaceView; ? ?
? private?final?static?String?TAG="VodeoPlayActivity"; ?
? private?int?prosition=0; ? ? ? ?
? @Override ? ?
? public?void?onCreate(Bundle?savedInstanceState)?{ ? ?
? super.onCreate(savedInstanceState); ? ??
? setContentView(R.layout.main); ? ? ? ?
? filenamEditText=(EditText)?this.findViewById(R.id.filename); ? ?
? surfaceView=(SurfaceView)this.findViewById(R.id.surfaceview); ? ? ??
? surfaceView.getHolder().setFixedSize(176,?144);//设置分辨率 ? ? ??
? surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置surfaceview不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前 ? ??
? surfaceView.getHolder().addCallback(new?SurceCallBack());//对surface对象的状态进行监听 ? ? ?
? mediaPlayer=new?MediaPlayer(); ? ? ? ? ??
? ButtonOnClikListiner?buttonOnClikListinero=new?ButtonOnClikListiner(); ? ? ?
? ImageButton?start=(ImageButton)?this.findViewById(R.id.play); ? ? ? ??
? ImageButton?pause=(ImageButton)?this.findViewById(R.id.pause); ? ? ? ?
? ImageButton?stop=(ImageButton)?this.findViewById(R.id.stop); ? ? ? ?
? ImageButton?replay=(ImageButton)?this.findViewById(R.id.reset); ? ? ?
? start.setOnClickListener(buttonOnClikListinero); ? ??
? pause.setOnClickListener(buttonOnClikListinero); ? ??
? stop.setOnClickListener(buttonOnClikListinero); ? ? ?
? replay.setOnClickListener(buttonOnClikListinero); ? ?
? } ? ? ?
? private?final?class?ButtonOnClikListiner?implements?View.OnClickListener{ ? ? ?
? @Override ? ?
? public?void?onClick(View?v)?{ ? ?
? if(Environment.getExternalStorageState()==Environment.MEDIA_UNMOUNTED){ ? ? ??
? Toast.makeText(VodeoPlayActivity.this,?"sd卡不存在",?Toast.LENGTH_SHORT).show(); ? ? ? ? ? ??
? return; ? ? ??
? } ? ? ? ??
? filename=filenamEditText.getText().toString(); ? ? ? ??
? switch?(v.getId())?{ ? ? ? ??
? case?R.id.play: ? ? ? ? ? ??
? play(); ? ? ? ? ? ? ? ?
? break; ? ? ? ? ?
? case?R.id.pause: ? ? ? ? ?
? if(mediaPlayer.isPlaying()){ ? ? ??
? mediaPlayer.pause(); ? ? ? ? ? ?
? }else{ ? ? ? ? ? ? ? ? ??
? mediaPlayer.start(); ? ? ? ??
? } ? ? ? ? ? ? ? ??
? break; ? ? ? ? ?
? case?R.id.reset: ? ? ? ??
? if(mediaPlayer.isPlaying()){ ? ?
? mediaPlayer.seekTo(0); ? ? ? ? ? ??
? }else{ ? ? ? ? ? ? ?
? play(); ? ? ? ? ? ? ?
? } ? ? ? ? ? ? ??
? break; ? ? ? ? ? ?
? case?R.id.stop: ? ? ? ? ?
? if(mediaPlayer.isPlaying()){ ? ?
? mediaPlayer.stop(); ? ? ? ? ? ??
? } ? ? ? ? ? ? ??
? break; ? ? ? ? ? ?
? } ? ? ? ?
? } ? ? ?
? } ? ? ??
? private?void?play()?{ ? ??
? try?{ ? ? ? ? ? ? ? ?
? File?file=new?File(Environment.getExternalStorageDirectory(),filename); ? ? ? ?
? mediaPlayer.reset();//重置为初始状态 ? ? ? ??
? mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//设置音乐流的类型 ? ? ? ? ? ?
? mediaPlayer.setDisplay(surfaceView.getHolder());//设置video影片以surfaceviewholder播放 ? ? ??
? mediaPlayer.setDataSource(file.getAbsolutePath());//设置路径 ? ? ? ? ? ??
? mediaPlayer.prepare();//缓冲 ? ? ? ? ? ? ? ?
? mediaPlayer.start();//播放 ? ? ? ? ? ?
? }?catch?(Exception?e)?{ ? ? ? ??
? Log.e(TAG,?e.toString()); ? ? ? ? ? ? ? ?
? e.printStackTrace(); ? ? ? ? ? ?
? } ? ??
? } ? ? ?
? private?final?class?SurceCallBack?implements?SurfaceHolder.Callback{ ? ?
? /**?????????*?画面修改?????????*/ ? ? ? ?
? @Override ? ? ? ?
? public?void?surfaceChanged(SurfaceHolder?holder,?int?format,?int?width, int?height)?{ ?
? //?TODO?Auto-generated?method?stub ? ? ? ? ? ? ? ?
? } ? ? ??
? /**?????????*?画面创建?????????*/ ? ??
? @Override ? ? ? ?
? public?void?surfaceCreated(SurfaceHolder?holder)?{ ? ? ? ? ??
? if(prosition>0&&filename!=null){ ? ? ? ? ? ?
? play(); ? ? ? ? ? ? ??
? mediaPlayer.seekTo(prosition); ? ? ? ? ? ?
? prosition=0;????????????} ? ? ? ? ?
? } ? ? ?
? /**?????????*?画面销毁?????????*/ ? ? ? ?
? @Override ? ? ? ?
? public?void?surfaceDestroyed(SurfaceHolder?holder)?{ ? ? ?
? if(mediaPlayer.isPlaying()){ ? ? ? ?
? prosition=mediaPlayer.getCurrentPosition(); ? ? ? ? ?
? mediaPlayer.stop(); ? ? ? ??
? } ? ? ? ?
? } ? ?
? }?
? }
推荐阅读
热点文章
android中Bitmap用法(显示,保存,缩放,旋转)实例分析
12
android 仿微信聊天气泡效果实现思路
1
Android的尺度,drawable-xxxxxxx
2
Codeforces Round #656 (Div. 3) (C、D题)
1
Android之handler异步消息处理机制解析
6
GridView中图片显示出现上下间距过大,左右图片显示类似瀑布流的问题
0
AsyncTask的简单使用
5
两个简单Fragment之间的通信(三种方式)
18
uboot修改设置boot参数命令
41
android中实现从相册中一次性获取多张图片与拍照,并将选中的图片显示出来
2
