MediaPlay流程图
MediaPlayer播放音频
public class MusicService extends Service {
private MediaPlayer mediaPlayer;
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
@Override
public void onCreate() {
//1 初始化 mediaplayer
mediaPlayer = new MediaPlayer();
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
/**
* 音乐播放暂停的方法
*/
public void pause(){
//暂停
mediaPlayer.pause();
}
/**
* 音乐播放的方法
*/
public void play(){
//重置
mediaPlayer.reset();
//2 设置您播放的资源
try {
mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3");
//开始准备播放 ,异步准备,不会阻塞
mediaPlayer.prepareAsync();<pre name="code" class="java"> //mediaPlayer.prepare();//同步准备,会阻塞
//设置medialpayer 准备完成的监听mediaPlayer.setOnPreparedListener(new OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {//开始播放mediaPlayer.start();// 同步 seekbar 的进度 addSeekBar();}});} catch (Exception e) {e.printStackTrace();}}/** * 音乐继续播放的方法 */public void resume(){System.out.println("音乐继续播放");mediaPlayer.start(); //继续播放 }//同步seekbar的状态 public void addSeekBar(){//1获取到 播放 小苹果的总的时长 final int duration = mediaPlayer.getDuration();//定时器 Timer timer = new Timer();//要执行的任务TimerTask task = new TimerTask() {@Overridepublic void run() {//2获取到当前播放位置 int currentPosition = mediaPlayer.getCurrentPosition();//3 拿着handler 发送消息 Message msg = Message.obtain();//4把 duration 和 currentPosition 存到 msg里 Bundle bundle = new Bundle(); //创建一个bundle 对象 类似map 集合bundle.putInt("duration", duration);bundle.putInt("currentPosition", currentPosition);msg.setData(bundle);MainActivity.handler.sendMessage(msg);}}; //50毫秒之后执行 task period 每隔多长时间再次执行tasktimer.schedule(task, 50, 1000);}//改变播放的进度public void seekTo(int progress){mediaPlayer.seekTo(progress);}/** * 定义一个类 继承 Binder 对象 定义一个中间人对象 * */private class MyBinder extends Binder implements Iservice{@Overridepublic void callPause() {pause();}@Overridepublic void callPlay() {play();}@Overridepublic void callResume() {resume();}@Overridepublic void callSeekTo(int progress) {//调用改变进度的方法seekTo(progress);}}}
public class MainActivity extends Activity {
private Iservice iservice; //中间人对象
private MyConn conn;
private static SeekBar sb; //进度条
public static Handler handler = new android.os.Handler(){
public void handleMessage(android.os.Message msg) {
//获取发送的消息
Bundle data = msg.getData();
int duration = data.getInt("duration");
int currentPosition = data.getInt("currentPosition");
//更新seekbar 的进度
sb.setMax(duration);
sb.setProgress(currentPosition);
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到seekbar
sb = (SeekBar) findViewById(R.id.sb);
//1 我要通过startservice 方法 开启服务 目的是 为了让这个服务长期在后台运行
Intent intent = new Intent(MainActivity.this,MusicService.class);
//2开启服务
startService(intent);
//3 因为我想调用服务里面的方法 、 通过绑定服务服务 来获取 中间人对象 间接的调用服务里面的方法
conn = new MyConn();
bindService(intent, conn, BIND_AUTO_CREATE);
//设置sb拖动的监听
sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
//当seekbar 停止拖动
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//肯定服务里面还要有一个 改变进度的方法
int progress = seekBar.getProgress(); //拿到seekbar 当前的位置 传给服务里面的某个方法
iservice.callSeekTo(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
}
/**
* 播放音乐
* @param v
*/
public void play(View v){
iservice.callPlay();
}
/**
* 暂停播放音乐
* @param v
*/
public void pause(View v){
iservice.callPause();
}
/**
* 继续播放播放音乐
* @param v
*/
public void resume(View v){
iservice.callResume();
}
//定义绑定服务的接口
private class MyConn implements ServiceConnection{
//当服务被成功绑定的时候调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iservice = (Iservice) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
MediaPlayer播放视频到surfaceview
surfaceview控件
surfaceview表面视图
双缓冲区:使用两个线程协调工作;
surfaceview 重量级空间,当画面可见时,双缓冲器被创建,占用较高的cpu和内存资源。
当界面不可见时,双缓冲器占用释放。
surfaceview 是一个双缓冲的机制 提供一共一个表面 内部维护了2个线程
* surfaceview 它也可以在子线程更新ui
* surfaceview 他是一个重量级控件
* 普通的view都是 ondraw()的方法画出来的
代码
public class MainActivity extends Activity {
private MediaPlayer mediaPlayer;
private int currentPosition; // 保存进度条当前位置
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
// 得到surfaceview
SurfaceView sfvView = (SurfaceView) findViewById(R.id.sfv);
// SurfaceView使用SurfaceHolder将数据加载到缓冲区
// 通过SurfaceView得到holder
SurfaceHolder holder = sfvView.getHolder();
<span style="white-space:pre"> </span>//推送缓冲数据,api 13之前的版本上必须执行这行代码,13版本之后,播放器可以自动把
<span style="white-space:pre"> </span>//数据加载到缓冲区
<span style="white-space:pre"> </span>holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Suiface被销毁时调用
currentPosition = mediaPlayer.getCurrentPosition();
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.stop(); //停止播放
mediaPlayer.release(); // 释放资源
}
}
// SurfaceView创建完成调用
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 1 创建 MediaPlayer
try {
mediaPlayer = new MediaPlayer();
mediaPlayer
.setDataSource("http://192.168.0.107:8080/M2U05023.MPG");
// 异步准备
mediaPlayer.prepareAsync();
mediaPlayer.setDisplay(holder);//设置显示到holder
<span style="white-space:pre"> </span>
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start(); // 播放
mediaPlayer.seekTo(currentPosition);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
videoview播放视频
videoview继承了SurfaceView,封装了播放视频的方法,使播放视频简单了许多,但surfaceview和videoview只支持3gp和mp4格式
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath("http://192.168.12.36:8080/haha.avi");
vv.start();
}
}
使用vitamio框架播放视频
vitamio 支持大多数格式解码操作 vitamio 就是对VideoView的封装 ,是一个类库
使用ffmpeg解码
步骤
1 引入vitamio框架,(vitamio是一个类库,先导入到eclipse,然后再需要使用的项目中右键属性,android标签下add类库增加)
2 在布局中定义VideoView(vitamio中的VideoView)
<io.vov.vitamio.widget.VideoView
android:id="@+id/vv"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
3 mainactivity代码
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1 在使用vitamio框架之前 要先初始化vitamio 框架 初始viamio化框架
if (!LibsChecker.checkVitamioLibs(this)) {
return;
}
VideoView vv = (VideoView) findViewById(R.id.vv);
vv.setVideoPath("http://192.168.12.36:8080/haha.avi");
vv.start();
vv.setMediaController(new MediaController(this));
}
}
4 一定要在清单文件初始化InitActivity
<activity android:name="io.vov.vitamio.activity.InitActivity"></activity>
照相机照相
直接调用系统相机照相
public class MainActivity extends Activity {
private File file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//拍照
public void click(View v){
//1 开启意图
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
file = new File(Environment.getExternalStorageDirectory().getPath(),"paizhao.png");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); //把图片保存到sd卡
startActivityForResult(intent, 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(getApplicationContext(), file.getAbsolutePath(), 1).show();
super.onActivityResult(requestCode, resultCode, data);
}
}
录像机录像
直接调用系统相机录像
public class MainActivity extends Activity {
private File file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//拍照
public void click(View v){
//1 开启意图
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);
file = new File(Environment.getExternalStorageDirectory().getPath(),"luxiang.3gp");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); //把图片保存到sd卡
startActivityForResult(intent, 2);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Toast.makeText(getApplicationContext(), file.getAbsolutePath(), 1).show();
super.onActivityResult(requestCode, resultCode, data);
}
}