Android 音频 Framework层 音频输出 Java API

来源:互联网 发布:js获取url 编辑:程序博客网 时间:2024/06/06 08:36

本文将介绍Android Framework Java API音频输出. JavaAPISDK坏境下就可以使用,并不详细讲API


输出主要的类:

MediaPlayer

SoundPool

AudioTrack


1、 MediaPlayer

MediaPlayer 是Android系统多媒体播放的类,即可以播放音频也可以播放视频,我们在这里主要讲解的是播放音频,下面播放音频播放Demo:

public class MediaPlayerActivity extends Activity implements OnPreparedListener {private MediaPlayer mMediaPlayer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);try {mMediaPlayer = new MediaPlayer();mMediaPlayer.setDataSource(Config.URI_MP3);mMediaPlayer.setOnPreparedListener(this);mMediaPlayer.prepareAsync();} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onPrepared(MediaPlayer mp) {mp.start();}@Overrideprotected void onDestroy() {super.onDestroy();if (mMediaPlayer != null) {mMediaPlayer.release();}}}

MediaPlayer 播放主要四个步骤:

1、 设置DataSource 即我们的数据源,可以是文件地址,也可以是网络地址。

2、 设置OnPreparedListener 这是音频准备,可以播放的一个回调。

3、 调用prepareAsync方式,该方法是让MediaPlayer 准备播放,该方法是异步的,准备好之后回调OnPreparedListener。

4、 在onPrepared 之后调用start方法即可以播放音乐。

注意:当我们的MediaPlayer不使用时一定需要调用release方法,不然系统资源无法释放,释放时在主线程释放,不然会引发内存溢出(这就不详细介绍)

MediaPlayer 其他常用API:


        setOnInfoListener  监听MediaPlayer状态. 

        下面是两个常用的状态,可以使得我们开发应用时,给用户更好的体验,当音乐是网络文件时,网络不好的情况下,可以给用户提示正在缓冲状态。

        MediaPlayer.MEDIA_INFO_BUFFERING_START 缓冲开始

        MediaPlayer.MEDIA_INFO_BUFFERING_END 缓冲结束

        注意:上面2个状态,部分设备会有问题,由于手机产商修改则不支持。


        setOnErrorListener 错误的监听,监听播放失败,可以在该方法友好的处理播放失败出错的逻辑。


        setOnBufferingUpdateListener 监听缓冲的进度,在界面上显示缓冲进度,部分设备也会有问题,Android 实现是比较乱的。


MediaPlayer生命周期

        MediaPlayer 维护了一个状态,状态之间转换是有限定的,下面是Android官方图,看图就能完全了解状态之间的切换,如果状态之间非法切换,会抛出异常。

 




MediaPlayer 对音频格式的支持:

  支持常用格式mp3、3gp、mp4 ,下面是Android doc的截图,详细介绍了Android标准支持格式,以及版本之间的差异。

        docs 文件 /sdk/docs/guide/appendix/media-formats.html 这是本地下载的docs. 该文档版本为API 21, 如需查看最新的支持格式,请到官网查看最新文档.


        不同的手机产商会支持更多的格式,例如小米4手机支持APE,Android 标准不支持,有些设备可以万能格式支持,例如盒子设备,底层使用FFmpeg 库解码,我们开发尽量使用标准支持的,可以更好的适配设备以及兼容性。

2、SoundPool


主要是播放低延迟的音频,多次循环。例如Android系统中按键声音,游戏中子弹声音等音频播放。

下面是SoundPool Demo 

public class SoundPoolActivity extends Activity implements OnLoadCompleteListener {private SoundPool mSoundPool;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);int maxStreams = 1;int streamType = AudioManager.STREAM_MUSIC;int srcQuality = 0;mSoundPool = new SoundPool(maxStreams, streamType, srcQuality);String path = Config.URI_ALARM;int priority = 0;mSoundPool.load(path, priority);mSoundPool.setOnLoadCompleteListener(this);}@Overridepublic void onLoadComplete(SoundPool soundPool, int sampleId, int status) {float leftVolume = 1.0f;float rightVolume = 1.0f;int priority = 1;int loop = 0;float rate = 1.0f;mSoundPool.play(sampleId, leftVolume, rightVolume, priority, loop, rate);}@Overrideprotected void onDestroy() {super.onDestroy();if (mSoundPool != null) {mSoundPool.release();}}}

SoundPool 主要步骤

1:load 音频文件 异步,加载完毕OnLoadCompleteListener回调,相当于的MediaPlayer.prepareAsync方法。

2:load 完毕调用play方法即可播放音频.  sampleId代表load 文件的ID.


SoundPool 对文件大小是有限制的,最大是1M,注意是音频文件解压之后的大小,一般音频文件都压缩了。 

SoundPool 支持的格式和MediaPlayer一样,请参考MediaPlayer.

3:AudioTrack

AudioTrack 即音轨,比较低级的API,播放音频PCM数据,在实际使用中主要在自己解码然后播放音频,例如,软解码,解码之后拿到的是PCM数据,就可以用AudioTrack播放。

下面是Demo:

public class AudioTrackActivity extends Activity implements Runnable {private Thread mPlaybackThread;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mPlaybackThread = new Thread(this);mPlaybackThread.start();}@Overridepublic void run() {int streamType = AudioManager.STREAM_MUSIC;int sampleRateInHz = 44100;int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;int audioFormat = AudioFormat.ENCODING_PCM_16BIT;int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat) * 2;int mode = AudioTrack.MODE_STREAM;AudioTrack audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig,audioFormat, bufferSizeInBytes, mode);BufferedInputStream bis = null;try {audioTrack.play();bis = new BufferedInputStream(new FileInputStream(Config.URI_PCM));byte[] buffer = new byte[bufferSizeInBytes];int len = 0;while ((len = bis.read(buffer)) != -1 && !isFinishing()) {audioTrack.write(buffer, 0, len); }} catch (Exception e) {e.printStackTrace();} finally {if (bis != null) {try {bis.close();} catch (IOException e) {}}audioTrack.release();}}}

上面的代码是从文件中读取PCM数据,AudioTrack 主要2个步骤:
        1:play 开始播放,
改变AudioTrack的状态
        2write 写入PCM数据,该方法是阻塞的,所以播放时需要在子线程中写入数据

AudioTrack 几个比较重要的参数:
        sampleRateInHz 采样率,每秒多少个采样
        channelConfig 声道
        audioFormat 格式
这三个参数是播放PCM数据比较重要的,后面的文章中会详细的介绍这些参数的作用。


总结:

        1:一般应用开发使用MediaPlayer 就可以满足基本的需求。

        2:针对低延迟的音频播放我们可以使用SoundPool,提升用户的体验,例如按键,不至于按键下去还没声音,Android老版本中SoundPool延迟也比较大,但新版本中Android已经有很大的改进。

        3: AudioTrack 低级API,PCM数据播放。




1 0