Android多媒体应用开发
音频和视频的播放
1.使用MediaPlayer播放音频
当程序控制MediaPlayer对象装载音频完成之后,程序可以调用MediaPlayer的如下方法进行播放控制:
- start():开始或恢复播放。
- stop():停止播放。
- pause():暂停播放。
为了让MediaPlayer来装载指定音频文件,MediaPlayer提供了如下简单的静态方法:
- static MediaPlayer create(Context context , Uri uri):从指定Uri来装载音频文件,并返回新创建的MediaPlayer对象。
- static MediaPlayer create(Context context , int resid):从resid资源ID对应的资源文件中装载音频文件,并返回新创建的MediaPlayer对象。
如果程序需要使用MediaPlayer循环播放多个音频文件,使用MediaPlayer的静态create()方法就不合适了,需要通过如下方法来装载指定的音频文件:
- setDataSource(String path):指定装载path路径所代表的文件。
- setDataSource(FileDescriptor fd,long offset,long length):指定装载fd所代表的文件中从offset开始、长度为length的文件内容。
- setDataSource(FileDescriptor fd):指定装载FD所代表的文件。
- setDataSource(Context context,Uri uri):指定装载uri所代表的文件。
执行完setDataSource()方法之后,MediaPlayer并未真正去装载这些音频文件,还需要调用prepare()
方法去准备音频,让MediaPlayer真正去装载音频文件。
MediaPlayer还提供了如下绑定事件监听器的方法:
- setOnCompletionListener(MediaPlayer.OnCompletionListener listener):为MediaPlayer的播放完成事件绑定事件监听器。
- setOnErrorListener(MediaPlayer.OnErrorListener listener):为MediaPlayer的播放错误事件绑定事件监听器。
- setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当MediaPlayer调用prepare()方法时触发该监听器。
- setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener):当MediaPlayer调用seek()方法时触发该监听器。
使用MediaPlayer播放不同来源的音频文件
1.播放应用的资源文件
- 调用MediaPlayer的create(Context context , int resid)方法装载指定的资源文件。
- 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
MediaPlayer mPlayer = MediaPlayer.create(this , R.raw.song) ;
mPlayer . start() ;
2.播放应用的原始资源文件
- 调用Context的getAssets()方法获取应用AssetManager。
- 调用AssetManager对象的openFd(String name)方法打开指定的原始资源,这个方法返回一个AssetFileDescriptor对象。
- 调用AssetFileDescriptor的getFileDescriptor()、getStartOffset()和getLength()方法来获取音频文件的FileDescriptor、开始位置、长度等。
- 创建MediaPlayer对象(或者利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDataSource(FileDescriptor fd,long offset,long length)方法来装载音频资源。
- 调用MediaPlayer对象的prepare()方法准备音频。
- 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
AssetManager am = getAssets();
//打开指定音乐文件
try {
AssetFileDescriptor afd = am.openFd(music);
MediaPlayer mPlayer = new MediaPlayer();
//使用MediaPlayer装载指定的声音文件
mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
//准备声音
mPlayer.prepare();
//播放
mPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
3.播放外部存储器上的音频文件
- 创建MediaPlayer对象(或利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDataSource(String path)方法装载指定的音频文件。
- 调用MediaPlayer对象的prepare()方法准备音频。
- 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
MediaPlayer mediaPlayer = new MediaPlayer();
try {
//使用MediaPlayer装载指定的音频文件
mediaPlayer.setDataSource(music);
//准备声音
mediaPlayer.prepare();
//播放
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
4.播放来自网络的音频文件
第一种方式:
- 调用MediaPlayer的静态create(Context context , Uri uri)方法;
- 调用MediaPlayer的setDataSource(Context context , Uri uri)方法装载指定Uri对应的音频文件。
第二种方式:
- 根据网络上的音频文件所在的位置创建Uri对象。
- 创建MediaPlayer对象(或利用已有的MediaPlayer对象),并调用MediaPlayer对象的setDataSource(String path)方法装载Uri对应的音频文件。
- 调用MediaPlayer对象的prepare()方法准备音频。
- 调用MediaPlayer的start()、pause()、stop()等方法控制播放即可。
Uri uri =
MediaPlayer mediaPlayer = new MediaPlayer();
try {
//使用MediaPlayer根据Uri来装载指定的音频文件
mediaPlayer.setDataSource(this,uri);
//准备声音
mediaPlayer.prepare();
//播放
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
MediaPlayer提供了prepare()和prepareAsync()两种方法准备声音,区别在于prepareAsync()方法是异步的,不会阻塞当前UI线程。
MediaPlayer的状态图如下所示:
MediaPlayer状态图.jpg音乐控制特效
常用的AudioEffect及其子类如下所示:
- AcousticEchoCanceler:取消回声控制器。
- AutomaticGainControl:自动增益控制器。
- NoiseSuppressor:噪音压制控制器。
- BassBoost:重低音控制器。
- Equalizer:均衡控制器。
- PresetReverb:预设音场控制器。
- Visualizer:示波器。
使用SoundPool播放音效
MediaPlayer的缺点:
- 资源占用量较高,延迟时间较长。
- 不支持多个音频同时播放。
SoundPool的优势:
- CPU资源占用量低,反应延时小。
Android系统为SoundPool提供了一个Builder内部类,用于创建SoundPool。创建好对象之后,就可调用load()方法来加载声音了。如下就是load()方法和播放指定声音的方法:
- int load(Context context , int resId , int priority):从resId所对应的资源加载声音。
- int load(FileDescriptor fd , long offset , long length , int priority):加载fd所对应的文件中从offset开始、长度为length的声音。
- int load(AssetFileDescripyor afd , int priority):从afd所对应的文件中加载声音。
- int load(String path , int priority):从path所对应的文件去加载声音。
- int play(int soundID , float leftVolume , float rightVolume , int priority , int loop , float rate):该方法的第一个参数指定播放哪个声音;leftVolume、rightVolume指定左、右的音量;priority指定播放声音的优先级,数值越大,优先级越高;loop指定是否循环,0为不循环,-1为循环;rate指定播放的比率,数值可从0.5到2,1为正常比率。
使用SoundPool播放声音的步骤:
- 调用SoundPool.Builder的构造器创建SoundPool.Builder对象,并可通过该Builder对象为SoundPool设置属性。
- 调用SoundPool的构造器创建SoundPool对象。
- 调用SoundPool对象的load()方法从指定资源、文件中加载声音。
- 调用SoundPool的play()方法播放声音。
VideoView播放视频
Android提供了VideoView组件用于播放视频。应用步骤如下所示:
- 在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件;
- 调用VideoView的如下两个方法来加载指定视频:
- setVideoPath(String path):加载path文件所代表的视频;
- setVideoURI(Uri , uri):加载uri所对应的视频;
- 调用VideoView的start()、stop()、pause()方法来控制视频播放。
与VideoView一起结合使用的还有一个MediaController类,其作用是提供一个友好的图形控制界面,通过该控制界面来控制视频的播放。
使用MediaPlayer和SurfaceView播放视频
MediaPlayer主要用于播放音频,需要借助于SurfaceView来显示MediaPlayer播放的图像输出。其应用步骤如下:
- 创建MediaPlayer对象,并让它加载指定的视频文件;
- 在界面布局文件中定义SurfaceView组件,或在程序中创建SurfaceView组件,并为SurfaceView的SurfaceHolder添加Callback监听器。
- 调用MediaPlayer对象的setDisplay(SurfaceHolder sh)方法将所播放的视频图像输出到指定的SurfaceView组件。
- 调用MediaPlayer对象的start()、stop()和pause()方法控制视频的播放。
使用MediaRecorder录制音频
Android中提供了MediaRecorder类来录制音频,其应用步骤如下所示:
- 创建MediaRecorder对象。
- 调用MediaRecorder对象的setAudioSource()方法设置声音来源,一般传入MediaRecorder.AudioSource.MIC参数指定录制来自麦克风的声音。
- 调用MediaRecorder对象的setOutputFormat()方法设置所录制的音频文件格式。
- 调用MediaRecorder对象的setAudioEncoder()、setAudioEncodingBitRate(int bitRate)、setAudioSamplingRate(int samplingRate)方法设置所录制的声音编码格式、编码位率、采样率等,这些参数将可以控制所录制的声音品质、文件大小。
- 调用MediaRecorder的setOutputFile(String path)方法设置所录制的音频文件的保存位置。
- 调用MediaRecorder的prepare()方法准备录制。
- 调用MediaRecorder对象的是start()方法开始录制。
- 录制完成,调用MediaRecorder对象的stop()方法停止录制,并调用release()方法释放资源。
MediaRecorder的状态图如下所示:
MediaRecorder.gif控制摄像头拍照
使用Android5.0的Camera v2拍照
Android 5.0对拍照API进行了全新的设计,新增了全新设计得Camera v2 API,主要如下所示:
- CameraManager:摄像头管理器。这是一个全新的系统管理器,专门用于检测系统摄像头、打开系统摄像头。调用其getCameraCharacteristics(String)方法就可以获取指定摄像头的相关特性。
- CameraCharacteristics:摄像头特性。用于描述特定摄像头所支持的各种特性。
- CameraDevice:代表系统摄像头。
- CameraCaptureSession:当程序需要预览、拍照时,都需要先通过该类的实例创建Session。而且不管预览还是拍照,也都是由该对象的方法进行控制的,其中控制预览的方法为setRepeatingRequest();控制拍照的方法是capture()。
- CameraRequest和CameraRequest.Builder:当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest代表了一次捕获请求,用于描述捕获图片的各种参数设置,比如对焦模式、曝光模式.....总之程序需要对照片所做的各种控制,都通过CameraRequest参数进行设置。CameraRequest.Builder负责生成CameraRequest对象。
使用Camera v2控制拍照的步骤如下:
- 调用CameraManager的openCamera(String cameraId , CameraDevice.StateCallback callback , Handler handler)方法打开指定摄像头。一参数表示要打开的摄像头ID;而参数用于监听摄像头的状态;三参数表示执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。
- 当摄像头被打开之后,程序即可获取CameraDevice(根据摄像头ID获取了指定摄像头设备,然后调用CameraDevice的createCaptureSession(List< Surface > outputs , CameraCaptureSession.StateCallback callback , Handler handler )方法来创建CameraCaptureSession。一参数是一个List集合,封装了所有需要从该摄像头获取图片的Surface,二参数用于监听CameraCaptureSession的创建工程,三参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。)
- 调用CameraDevice的createCaptureRequest(int templateType)方法创建CaptureRequest.Builder,这个方法支持TEMPLATE_PREVIEW(预览)、TEMPLATE_RECORD(拍摄视频)、TEMPLATE_STILL_CAPTURE(拍照)等参数。
- 通过上步骤所返回的CaptureRequest.Builder设置拍照的各种参数,比如对焦模式、曝光模式等。
- 调用CaptureRequest.Builder的build()方法就可以得到CaptureRequest对象,接下来通过CameraCaptureSession的setRepeatingRequest()方法开始预览,或调用capture()方法拍照。
录制视频短片
MediaRecorder除了可用于录制音频之外,还可以用于录制视频。其录制视频的步骤和录制音频的步骤基本相同。
- 创建MediaRecorder对象。
- 调用MediaRecorder对象的setAudioSource()方法设置声音来源,一般传入MediaRecorder.AudioSource.MIC参数指定录制来自麦克风的声音 ;
调用MediaRecorder对象的setVideoSource()方法设置图像来源
。 - 调用MediaRecorder对象的setOutputFormat()方法设置所录制的视频频文件格式。
- 调用MediaRecorder对象的setAudioEncoder()、setAudioEncodingBitRate(int bitRate)、setAudioSamplingRate(int samplingRate)方法设置所录制的视频编码格式、编码位率、采样率等,这些参数将可以控制所录制的视频品质、文件大小。
- 调用MediaRecorder的setOutputFile(String path)方法设置所录制的视频文件的保存位置。
- 调用MediaRecorder的setPreviewDiaplay(Surface sv)方法设置使用哪个SurfaceView来显示视频预览。
- 调用MediaRecorder的prepare()方法准备录制。
- 调用MediaRecorder对象的是start()方法开始录制。
- 录制完成,调用MediaRecorder对象的stop()方法停止录制,并调用release()方法释放资源。
Android 5.0新增的屏幕捕捉
Android 5.0新增了MediaProjectionManager管理器,这个管理器可以非常方便地实现屏幕捕捉功能,应用步骤如下:
- 以MEDIA_PROJECTION_SERVICE为参数,调用Context.getSystemService()方法即可获取MediaProjectionManager实例。
- 调用MediaProjectionManager对象的createScreenCaptureIntent()方法创建一个屏幕捕捉的Intent。
- 调用startActivityForResult()方法启动上步骤得到的Intent,这样就可以启动捕捉的Intent。
- 重写onActivityResult()方法,在这个方法中通过MediaProjectionManager对象来获取MediaProjection对象,在该对象中即可获取被捕获的屏幕。