Android中的多媒体
音频处理
MediaPlayer类
- 同一时间只能有一种音频播放
- prepare():准备就绪 通过流的操作来缓存
- reset():清空音乐缓存,为新的音乐播放做准备
- void setDataSource(…):动态的获取资源:指定相关联的音乐文件
- setOnCompletionListener():播放完成的事件监听 可以在这个方法中实现智能加载下一首播放 通过list来设置播放顺序
- setOnPreparedListener():prepare方法的事件监听 准备加载的时候做何处理
- setOnSeekCompleteListener():seek方法的事件监听 seekTo():相当于定位
缺点:
- 资源占用量高,延迟时间长
- 不支持多个音频同时播放
示例
- raw文件可以被R直接索引
- asset文件不能被直接索引需要获取输入流
代码思路
新建assets:
右击- folder-assetsfolder
新建后将mp3文件放入folder中
将文件图片放入mipmap中
xml文件添加按钮的时候播放和暂停可以是同一个按钮
所需对象:assetManager和mediaPlayer对象
还需要一个属性来记录当前位置(用来播放上一首下一首的时候做判别)
初始化
- mediaPlayer对象的初始化 new
- AssetManager 的对象获取 getAssets()
- 播放前要预加载第一首mp3
- 获取第一首mp3文件:使用AssetManager 的 openFD(参数是assets下的mp3文件名称) 返回值是AssetFileDescriptor类型
- 给mediaPlayer对象设置音频数据源为第一首mp3:setDataSource(AssetFileDescriptor对象)
- 给MediaPlayer注册播放完成监听器(提前注册,不能在切换的时候):顺序播放下一首
- 计算下一个音频文件id
- 注意边界,达到边界后重新从第一首播放
- 自定义函数loadMp3(int curId):给mediaPlayer加载音频数据源,步骤同 预加载 ,只需将id改为动态
- 重置一下,清除缓存 reset()
- 加载下一个音频文件
- 给MediaPlayer对象重新设置音频数据源
- 加载准备好
- 启动播放 start()
- 计算下一个音频文件id
监听事件处理
- on/pause:已经预加载过,不必再次加载
- 如果正在播放,则暂停,并切换图片
- 如果暂停,则转为播放:start:开始播放或继续播放
- stop:
- 如果没有停止播放,则停止
- 修改播放/暂停的按钮为准备播放
- 如果没有停止播放,则停止
- pre
- 修改当前音频文件的id
- 如果id小于1的时候,循环播放设置为id为最后一个
- 加载相应音频文件
- 开始播放
- 修改播放暂停按钮的图片为暂停播放
- 修改当前音频文件的id
- next
- 修改当前音频文件的id
- 如果id大于最后一个的时候,循环播放设置为id为第一个
- 加载相应音频文件
- 开始播放
- 修改播放暂停按钮的图片为暂停播放
- 修改当前音频文件的id
SoundPool类 设置音效
特点:
CPU占用量低
反应延迟小
可设置声音的品质、音量、播放比率等参数
常用api
- build():通过Builder对象构造SoundPool对象
- int load(…):加载声音,返回当前声音的ID 有重载
- int play(int soundID, float leftVolume, float rightVolume ,int priority, int loop, float rate)
声音id;左、右声道音量;优先级;是否循环(0:不循环,-1:循环);播放比率(0.5~2,正常比率为1)
代码思路
folder-raw resource folder:用于存放音效
- 先创建soundPool构造器对象new SoundPool.Builder() :是一个内部类
- 通过soundPool构造器对象创建soundPool对象 builder.build()
可选:设置允许容纳的最大音效流
- 加载音效文件,并保存返回的音效id 用循环实现
- 定义集合,用于存储生成的音效id
- 给soundPool对象注册加载音效完成时间监听器
- 获取资源文件id getResource().getIdentifier(“拼接的id”,“文件类型”,“包名”)
- 加载音效文件soundpool.load(cintext,id,priority)
- 添加到音效集合中
- 同时播放多个音效(设置监听器)
- 参数:id,leftVolume,rightVolume,priority,loop,rate
- 参数:id,leftVolume,rightVolume,priority,loop,rate
MediaPlayer和SoundPool
- mediaPlayer用于播放普通的音频文件,soundPool用于播放短促的音效
- 同一时刻MediaPlayer只能播放一个音频文件,SoundPool可以同时播放多个音效
- MediaPlayer占用内存资源大,有时间延迟,性能消比较大
soundPool性能比较高,效率比较快,速度快,资源内存占用小
MediaRecorder录制音频
不仅可以录制声音 还可以录制视频
在手机模拟器上无法实现,需要真机调试 调试的时候需要手动打开权限
代码
- 涉及到硬件就要添加权限:此处的权限是RECORD_AUDIO
- 需要定义音频的MediaRecorder属性
- 录制音频步骤-开始录制
- 初始化MediaRecorder对象 new
- 设置录制音频来源 recorder.setAudioSource
- 设置音频类型 recorder.setOutputFormat
- 设置音频编码方式(先设置音频格式后设置音频编码)recorder.setAudioEncoder()
- 设置音频输出路径以及音频名称 recorder.setOutputFile() 注意后缀名的类型
- 准备录制 recorder.prepare()
- 开始录制 recorder.start();
- 录制音频步骤-停止录制
- 先判断是否在录制
- 停止录制 recorder.stop()
- 释放资源 recorder.release
视频处理 - VideoView控件
- 将视频和控件关联之后可以实现自动播放
- 没有停止方法,播放完后自动停止
- 有暂停播放
代码思路
播放本地files目录下的视频文件:
- files右击-upload上传视频
- 获取视频文件
- File file = …
- 判断视频文件是否存在,存在的话再进行第三步
- 给视频播放设置视频源 vv.setVideoPath
- 创建系统内置的视频播放控制器
- MediaController controller = new …
- 设置给视频控件
- vv.setMediaController()
- 播放vv.start
- 暂停播放:vv.pause()
摄像头应用
需要添加权限
MediaStore.ACTION_IMAGE_CAPTURE
//调用系统摄像头拍照,注意需要添加允许操作摄像头权限
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
data.getExtras():获取到bundle对象
//在Activity的onActivityResult回调方法中获取拍照结果并显示
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
ivPhoto.setImageBitmap(photo);
}
}