Android 音频 Framework层 音频输出 Java API
来源:互联网 发布:js获取url 编辑:程序博客网 时间:2024/06/06 08:36
本文将介绍Android Framework层 Java API音频输出. Java层API在SDK坏境下就可以使用,并不详细讲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的状态
2:write 写入PCM数据,该方法是阻塞的,所以播放时需要在子线程中写入数据。
AudioTrack 几个比较重要的参数:
sampleRateInHz 采样率,每秒多少个采样
channelConfig 声道
audioFormat 格式
这三个参数是播放PCM数据比较重要的,后面的文章中会详细的介绍这些参数的作用。
总结:
1:一般应用开发使用MediaPlayer 就可以满足基本的需求。
2:针对低延迟的音频播放我们可以使用SoundPool,提升用户的体验,例如按键,不至于按键下去还没声音,Android老版本中SoundPool延迟也比较大,但新版本中Android已经有很大的改进。
3: AudioTrack 低级API,PCM数据播放。
- Android 音频 Framework层 音频输出 Java API
- Android 音频 Framework层 音频输入 录音 Java API
- Android jni层直接输出音频示例
- Android音频输出切换
- android 音频framework的分析
- android音频hal层简介
- Android java层音频相关的分析与理解(四)音频外设相关
- Android java层音频相关的分析与理解(四)音频外设相关
- Android java层音频相关的分析与理解(五)音频通路的切换
- Android 音频输出方式监听
- Android java层音频相关的分析与理解
- java与面向对象---2.8 捕获音频及输出音频
- 输出音频和捕获音频
- Android---处理音频输出的硬件
- Android Developers:处理音频输出的硬件
- Android---处理音频输出的硬件
- Android如何实现音频输出切换
- 【Android】Audio音频输出通道切换
- asp.net Calendar 日历控件简单用法
- IP协议字段的取值表
- 多线程2
- 《Career Cup Top 150 Questions and Answers》阅读笔记
- Android实现录音的方法(最重要的是对MediaRecorder的试用方法)
- Android 音频 Framework层 音频输出 Java API
- UML类图几种关系的总结
- JQuery DataTables插件中文文档
- Java常用类
- 小艹刘大cao瘤最有人性的设区
- css清除浮动
- eclipse中的git pull时出现 “the current branch is not configured.....”
- 警钟长鸣
- 64位 vs2010 和 opencv2.4.4 配置问题