您的当前位置:首页正文

Android多媒体应用开发

来源:华拓网

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播放声音的步骤:

  1. 调用SoundPool.Builder的构造器创建SoundPool.Builder对象,并可通过该Builder对象为SoundPool设置属性。
  2. 调用SoundPool的构造器创建SoundPool对象。
  3. 调用SoundPool对象的load()方法从指定资源、文件中加载声音。
  4. 调用SoundPool的play()方法播放声音。

VideoView播放视频

Android提供了VideoView组件用于播放视频。应用步骤如下所示:

  1. 在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件;
  2. 调用VideoView的如下两个方法来加载指定视频:
  • setVideoPath(String path):加载path文件所代表的视频;
  • setVideoURI(Uri , uri):加载uri所对应的视频;
  1. 调用VideoView的start()、stop()、pause()方法来控制视频播放。
    与VideoView一起结合使用的还有一个MediaController类,其作用是提供一个友好的图形控制界面,通过该控制界面来控制视频的播放。

使用MediaPlayer和SurfaceView播放视频

MediaPlayer主要用于播放音频,需要借助于SurfaceView来显示MediaPlayer播放的图像输出。其应用步骤如下:

  1. 创建MediaPlayer对象,并让它加载指定的视频文件;
  2. 在界面布局文件中定义SurfaceView组件,或在程序中创建SurfaceView组件,并为SurfaceView的SurfaceHolder添加Callback监听器。
  3. 调用MediaPlayer对象的setDisplay(SurfaceHolder sh)方法将所播放的视频图像输出到指定的SurfaceView组件。
  4. 调用MediaPlayer对象的start()、stop()和pause()方法控制视频的播放。

使用MediaRecorder录制音频

Android中提供了MediaRecorder类来录制音频,其应用步骤如下所示:

  1. 创建MediaRecorder对象。
  2. 调用MediaRecorder对象的setAudioSource()方法设置声音来源,一般传入MediaRecorder.AudioSource.MIC参数指定录制来自麦克风的声音。
  3. 调用MediaRecorder对象的setOutputFormat()方法设置所录制的音频文件格式。
  4. 调用MediaRecorder对象的setAudioEncoder()、setAudioEncodingBitRate(int bitRate)、setAudioSamplingRate(int samplingRate)方法设置所录制的声音编码格式、编码位率、采样率等,这些参数将可以控制所录制的声音品质、文件大小。
  5. 调用MediaRecorder的setOutputFile(String path)方法设置所录制的音频文件的保存位置。
  6. 调用MediaRecorder的prepare()方法准备录制。
  7. 调用MediaRecorder对象的是start()方法开始录制。
  8. 录制完成,调用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控制拍照的步骤如下:

  1. 调用CameraManager的openCamera(String cameraId , CameraDevice.StateCallback callback , Handler handler)方法打开指定摄像头。一参数表示要打开的摄像头ID;而参数用于监听摄像头的状态;三参数表示执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。
  2. 当摄像头被打开之后,程序即可获取CameraDevice(根据摄像头ID获取了指定摄像头设备,然后调用CameraDevice的createCaptureSession(List< Surface > outputs , CameraCaptureSession.StateCallback callback , Handler handler )方法来创建CameraCaptureSession。一参数是一个List集合,封装了所有需要从该摄像头获取图片的Surface,二参数用于监听CameraCaptureSession的创建工程,三参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。)
  3. 调用CameraDevice的createCaptureRequest(int templateType)方法创建CaptureRequest.Builder,这个方法支持TEMPLATE_PREVIEW(预览)、TEMPLATE_RECORD(拍摄视频)、TEMPLATE_STILL_CAPTURE(拍照)等参数。
  4. 通过上步骤所返回的CaptureRequest.Builder设置拍照的各种参数,比如对焦模式、曝光模式等。
  5. 调用CaptureRequest.Builder的build()方法就可以得到CaptureRequest对象,接下来通过CameraCaptureSession的setRepeatingRequest()方法开始预览,或调用capture()方法拍照。

录制视频短片

MediaRecorder除了可用于录制音频之外,还可以用于录制视频。其录制视频的步骤和录制音频的步骤基本相同。

  1. 创建MediaRecorder对象。
  2. 调用MediaRecorder对象的setAudioSource()方法设置声音来源,一般传入MediaRecorder.AudioSource.MIC参数指定录制来自麦克风的声音 ;调用MediaRecorder对象的setVideoSource()方法设置图像来源
  3. 调用MediaRecorder对象的setOutputFormat()方法设置所录制的视频频文件格式。
  4. 调用MediaRecorder对象的setAudioEncoder()、setAudioEncodingBitRate(int bitRate)、setAudioSamplingRate(int samplingRate)方法设置所录制的视频编码格式、编码位率、采样率等,这些参数将可以控制所录制的视频品质、文件大小。
  5. 调用MediaRecorder的setOutputFile(String path)方法设置所录制的视频文件的保存位置。
  6. 调用MediaRecorder的setPreviewDiaplay(Surface sv)方法设置使用哪个SurfaceView来显示视频预览。
  7. 调用MediaRecorder的prepare()方法准备录制。
  8. 调用MediaRecorder对象的是start()方法开始录制。
  9. 录制完成,调用MediaRecorder对象的stop()方法停止录制,并调用release()方法释放资源。

Android 5.0新增的屏幕捕捉

Android 5.0新增了MediaProjectionManager管理器,这个管理器可以非常方便地实现屏幕捕捉功能,应用步骤如下:

  1. 以MEDIA_PROJECTION_SERVICE为参数,调用Context.getSystemService()方法即可获取MediaProjectionManager实例。
  2. 调用MediaProjectionManager对象的createScreenCaptureIntent()方法创建一个屏幕捕捉的Intent。
  3. 调用startActivityForResult()方法启动上步骤得到的Intent,这样就可以启动捕捉的Intent。
  4. 重写onActivityResult()方法,在这个方法中通过MediaProjectionManager对象来获取MediaProjection对象,在该对象中即可获取被捕获的屏幕。

好吧,到这里吧!

我的微信公众号.jpg