
前几天一直在研究RxJava2,也写了记录了几篇博客,但由于工作任务缘由,需要探究音频相关的常识,暂时放下Rxjava,本文的demo中,MediaPalyer 部分使用RxJava编写一点逻辑,其中涉及,RxJava2的被压、解除订阅等知识点,虽然简单,最至少没有丢了RxJava,后续Rxjava会再次研究,做记录.
andorid提供了对声音和视频处理的api包android.media.本文编写了对于这几种方式播放的Demo,文章最终贴出。
对于android音频的播放,这个类也许是你们最熟知的了,从入门就经常想编写一个自己的音乐播放器,有木有?MediaPlayer确实强大,提供了对音频播放的各类控制,生命周期:
1. MediaPlayer支持:AAC、AMR、FLAC、MP3、MIDI、OGG、PCM等格式
2. 播放Raw下的元数据
//直接创建,不需要设置setDataSource
mMediaPlayer=MediaPlayer.create(this, R.raw.audio);
mMediaPlayer.start();
3. MediaPlayer设置播放源的4中形式
//从sd卡中加载音乐
mMediaPlayer.setDataSource("../music/samsara.mp3") ;
//从网路加载音乐
mMediaPlayer.setDataSource("http://..../xxx.mp3") ;
//需使用异步缓冲
mMediaPlayer.prepareAsync() ;
//需将资源文件放在assets文件夹
AssetFileDescriptor fd = getAssets().openFd("samsara.mp3");
mMediaPlayer.setDataSource(fd)
mMediaPlayer.prepare() ;
Ps:此方法系统需大于等于android
这个方法没什么好说的,一般通过ContentProvider获取Android系统提供
的共享music获取uri,然后设置数据播放

//需将资源文件放在assets文件夹
AssetFileDescriptor fd = getAssets().openFd("samsara.mp3");
mMediaPlayer.setDataSource(fd, fd.getStartOffset(), fd.getLegth())
mMediaPlayer.prepare() ;
4. 注意点
资源占用量较高、延迟时间较长、不支持多个音频同时播放等
//创建播放时间格式化工具
mFormat = new SimpleDateFormat("mm:ss");
//创建MediaPlayer和设置
mPlayer = new MediaPlayer() ;
mSeekBar.setOnSeekBarChangeListener(new MySeekBarChangeListener());
mPlayer.setOnPreparedListener(new MyOnPrepareListener());
mPlayer.setOnCompletionListener(new MyOnCompletionListener());
/**
* 从assets资源文件夹中播放
* @param name
*/
private void playSoundFromA(String name) {
if (mPlayer.isPlaying()) {
mPlayer.stop();
}
// 设置当前播放歌曲的名字
title.setText(names[current]);
mPlayer.reset();
AssetFileDescriptor afd = getAssetFileDescriptor(name);
try {
mPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
hasResource = true;
mPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
SoundPool支持多个音频文件同时播放(组合音频也是有上限的),延时短,比较合适短促、密集的画面,是游戏开发中音效播放的福音。
SoundPool(int maxStreams, int streamType, int srcQuality)
从android5.0开始此方法被标记为过时,稍微说以下几个参数。
1.maxStreams :允许同时播放的流的最大值
2.streamType :音频流的类型描述,
在Audiomanager中有种类型声明,游戏应用通常会使用流媒体音乐。
3. srcQuality:采样率转化质量
//设置描述音频流信息的属性
AudioAttributes abs = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build() ;
SoundPool mSoundPoll = new SoundPool.Builder()
.setMaxStreams(100) //设置允许同时播放的流的最大值
.setAudioAttributes(abs) //完全可以设置为null
.build() ;
// 几个load方法和上文提到的MediaPlayer基本一致,不做多的解释
//------------------------------------------------------------
int load(AssetFileDescriptor afd, int priority)
int load(Context context, int resId, int priority)
int load(String path, int priority)
int load(FileDescriptor fd, long offset, long length, int priority)
//-------------------------------------------------------------
// 通过流id暂停播放
final void pause(int streamID)
// 播放声音,soundID:音频id; left/rightVolume:左右声道(默认1,1);loop:循环次数(-1无限循环);rate:播放速率(1为标准)
final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)
//释放资源(很重要)
final void release()
//恢复播放
final void resume(int streamID)
//设置指定id的音频循环播放次数
final void setLoop(int streamID, int loop)
//设置加载(因为加载是异步的,需要加载,完成后再播放)
void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener)
//设置优先级(同时播放个数超过最大值时,优先级低的先被移除)
final void setPriority(int streamID, int priority)
//设置指定音频的播放速率,0.5~2.0(rate>1:加快播放,反之慢速播放)
final void setRate(int streamID, float rate)
//停止指定音频播放
final void stop(int streamID)
//卸载指定音频
final boolean unload(int soundID)
//暂停所有音频的播放
final void autoPause()
//恢复所有暂停的音频播放
final void autoResum()
以上方式基本上是SoundPool的所有办法了,也都很常用。
看了Sounpool的api,是不是感觉对 streamID 和 soundID 一脸懵逼?
1. soundID:加载音乐资源时的返回值,int load(String path, int priority),这个int返回值就是soundID

2. streamID:播放时返回的值,即play()方法的返回值
这两个值都很重要,需要缓存下来
注:我把SoundPool做了简单封装,SoundPoolUtil,会在文末上传,
有兴趣可下载看一下,时间比较急,还有很多不足的地方
//初始化SoundPool
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
AudioAttributes aab = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build() ;
mSoundPool = new SoundPool.Builder()
.setMaxStreams(10)
.setAudioAttributes(aab)
.build() ;
}else{
mSoundPool = new SoundPool(60, AudioManager.STREAM_MUSIC,8) ;
}
mSoundPool = new SoundPool(60, AudioManager.STREAM_MUSIC,8) ;
//设置资源加载
mSoundPool.setOnLoadCompleteListener(new MyOnLoadCompleteListener());
//加载资源
/**
* 加载指定路径列表的资源
* @param map
*/
public void loadR(Map<String, String> map){
Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry : entries){
String key = entry.getKey() ;
if(checkSoundPool()){
if(!idCache.containsKey(key)){
idCache.put(key, mSoundPool.load(entry.getValue(),1)) ;
}
}
}
}
/**
* 播放指定音频,并返用于停止、暂停、恢复的StreamId
* @param name
* @param times
* @return
*/
public int play(String name, int times){
return this.play(name,1,1,1,times,1) ;
}
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-120691-1.html
他在体制内演讲