原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0519/500.html
接下来笔者先容一下Android中播放音频的几种体例,android.media包下面包含了Android开发中媒体类,固然笔者不会顺次去先容,下面先容几个音频播放中常用的类:
1.应用MediaPlayer播放音频
MediaPlayer的功效很壮大,下面附上一张该类封装音频的性命周期图:\MediaPlayer支持AAC、AMR、FLAC、MP3、MIDI、OGG、PCM等花样,MediaPlayer可以通过配置元数据和播放源来音频。
1.1播放Raw文件夹下面音频的元数据
//干脆建立,不必要配置setDataSource
MediaPlayer mMediaPlayer;
mMediaPlayer=MediaPlayer.create(this, R.raw.audio);
mMediaPlayer.start();
1.2通过配置播放源来播放音频文件
setDataSource(String path)
//要是从sd卡中加载音乐
//经过笔者的测试,必要加载sd卡的读权限,这里明明是从sd卡中读取文件
// <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
//而后便行使 Environment.getExternalStorageDirectory() 获取SD卡的根目次了,普通为/storage/emulated/0
//接下来把xxx.wav放到SD的根目次下,便获得文件的途径了 String path=Environment.getExternalStorageDirectory()+"/xxx.wav";
mMediaPlayer.setDataSource(path) ;
//要是从网页加载音乐,要是是从网页中加载辣么必要配置网页权限
//<uses-permission android:name="android.permission.INTERNET"/>
mMediaPlayer.setDataSource("http://..../xxx.mp3") ;
//需应用异步缓冲
mMediaPlayer.prepareAsync() ;
setDataSource(FileDescriptor fd)
//需将资源文件放在assets文件夹
AssetFileDescriptor fd = getAssets().openFd("samsara.mp3");
mMediaPlayer.setDataSource(fd.getFileDescriptor());//经过笔者的测试,发现这个要领偶然候不行播放胜利,尽管应用该要领的另一个重载要领 setDataSource(FileDescptor fd,long offset,long length)
mMediaPlayer.prepare() ;
Ps:此要领体系需大于即是android
setDataSource(Context context,Uri uri)
这个要领没甚么好说的,普通通过ContentProvider获取Android体系提供
的分享music获取uri,而后配置数据播放
setDataSource(FileDescptor fd,long offset,long length)
//需将资源文件放在assets文件夹
AssetFileDescriptor fd = getAssets().openFd("samsara.mp3");
mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
mMediaPlayer.prepare();
配置完数据源,不要忘记prepare(),尽管应用异步prepareAync(),如许不会壅闭UI线程。
1.3 MediaPlayer的常用要领
start();//开始播放
pause();//停息播放
reset()//清空MediaPlayer中的数据
setLooping(boolean);//配置是否轮回播放
seekTo(msec)//定位到音频数据的位置,单元毫秒
stop();//休止播放
relase();//开释资源
2.应用SoundPool播放音频
SoundPool支持多个音频文件同时播放(组合音频也是有上限的),延时短,对照适合急促、密集的场景,是游戏开发中音效播放的福音。
2.1 SoundPool实例化体例
1. new SoundPool(适合与5.0以下)
SoundPool(int maxStreams, int streamType, int srcQuality)
从android5.0开始此要领被标志为过期,略微说以下几个参数。
1.maxStreams :容许同时播放的流的最大值
2.streamType :音频流的范例形貌,
在Audiomanager中有品种型申明,游戏运用平时会应用流媒体音乐(AudioManager.STREAM_MUSIC)
3. srcQuality:采样率转化质量,默认值为0 。
2. SoundPool.Builder(从5.0开始支持)
//配置形貌音频流信息的属性
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() ;
2.2 SoundPool的几个紧张的要领
// 几个load要领和上文提到的MediaPlayer根基一致,这里的每个load都会回笼一个SoundId值,这个值可以用来播放和卸载音乐。
//------------------------------------------------------------
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(这个id来自load的回笼值); left/rightVolume:左右声道(默认1,1);loop:轮回次数(-1无尽轮回,0代表不轮回);rate:播放速度(1为尺度),该要领会回笼一个streamID,要是StreamID为0表示播放腐朽,否则为播放胜利
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)
//卸载指定音频,soundID来自load()要领的回笼值
final boolean unload(int soundID)
//停息所有音频的播放
final void autoPause()
//恢复所有停息的音频播放
final void autoResum()
下面简单演示一下SoundPool若何播放音乐:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SoundPool soundPool=new SoundPool(100,AudioManager.STREAM_MUSIC,0);//构建工具
int soundId=soundPool.load(context,R.raw.test,1);//加载资源,获得soundId
int streamId= soundPool.play(soundId, 1,1,1,-1,1);//播放,获得StreamId
// soundPool.stop(streamId);//停息
}
行使上头的播放体例可能会播放不胜利,这是由于把一段音频加载到内存在还必要一段时间,以是要是在Load要领后登时挪用play,可能会播放不胜利。对于这种的办理计划:
a.加载音频在OnCreate要领实现,播放在按钮中实现。
b.配置OnLoadCompleteListener监听。
栗子:
SoundPool soundPool=new SoundPool(100,AudioManager.STREAM_MUSIC,5);//构建工具
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(sampleId,1,1,1,0,1);//播放
}
});
soundPool.load(this,R.raw.victory,1);//加载资源
3.应用AudioTrack播放音频
AudioTrack属于更偏底层的音频播放,MediaPlayerService的里面即是应用了AudioTrack。
AudioTrack用于单个音频播放和经管,相比于MediaPlayer具备:精炼、高效的优点。
更适合及时发生播放数据的环境,如加密的音频,
MediaPlayer是走投无路的,AudioTrack却可以。
AudioTrack用于播放PCM(PCM无压缩的音频花样)音乐流的回放,
要是要播需放其它花样音频,必要相应的解码器,
这也是AudioTrack用的对照少的缘故,必要本人解码音频。
AudioTreack的2种播放形式
静态形式—static
静态的言下之意即是数据一次性交付给汲取方。甜头是简单高效,只必要进行一次操纵就实现了数据的传递;缺点固然也很明显,对于数据量较大的音频回放,显然它是无法胜任的,于是平时只用于播放铃声、体系提醒等对内存小的操纵
流形式streaming
流形式和网页上播放视频是相似的,即数据是根据必然纪律接续地传递给汲取方的。表面上它可用于任何音频播放的场景,但是我们普通在以下环境下接纳:
音频文件过大
音频属性要求高,好比采样率高、深度大的数据
音频数据是及时发生的,这种环境就只能用流形式了
通过write(byte[], int, int), write(short[], int, int)等要领推送解码数据到AudioTrack
4.应用Ringtone播放音频
Ringtone为铃声、关照和其余相似声响提供疾速播放的要领,这里还不得不提到一个经管类”RingtoneManager”,提供体系铃声列表检索要领,而且,Ringtone实例必要从RingtoneManager获取。
1. 获取实例
//获取实例要领,均为RingtoneManager类提供
//1.通过铃声uri获取
static Ringtone getRingtone(Context context, Uri ringtoneUri)
//2.通过铃声检索位置获取
Ringtone getRingtone(int position)
2. RingtoneManager几个紧张的要领
1. // 两个组织要领
RingtoneManager(Activity activity)
RingtoneManager(Context context)
2. // 获取指定声响范例(铃声、关照、闹铃等)的默认声响的Uri
static Uri getDefaultUri(int type)
3. // 获取体系所有Ringtone的cursor
Cursor getCursor()
4. // 获取cursor指定位置的Ringtone uri
Uri getRingtoneUri(int position)
5. // 校验指定Uri是否为默认铃声
static boolean isDefault(Uri ringtoneUri)
6. //获取指定uri的所属范例
static int getDefaultType(Uri defaultRingtoneUri)
7. //将指定Uri配置为指定声响范例的默认声响
static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri)
从api看,Ringtone和RingtoneManager照旧对照简单的,未几做注释了,干脆放上一段应用代码。
/**
* 播放回电铃声的默认音乐
*/
private void playRingtoneDefault(){
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE) ;
Ringtone mRingtone = RingtoneManager.getRingtone(this,uri);
mRingtone.play();
}
/**
* 随机播放一个Ringtone(有不妨提醒音、铃声等)
*/
private void ShufflePlayback(){
RingtoneManager manager = new RingtoneManager(this) ;
Cursor cursor = manager.getCursor();
int count = cursor.getCount() ;
int position = (int)(Math.random()*count) ;
Ringtone mRingtone = manager.getRingtone(position) ;
mRingtone.play();
}
末了记得增加权限:
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
其实,Rington这个类对照简单,只必要掌握,播放、休止(paly(),stop())等要领便了,而RingtoneManager却是对照紧张的。
5.总结
1.对于耽误度要求不高,而且有望能够更全面的掌握音乐的播放,MediaPlayer对照适合
2.声响短小,耽误度小,而且必要几种声响同时播放的场景,适合应用SoundPool
3.播扩大文件音乐,如WAV无损音频和PCM无压缩音频,可应用更底层的播放体例AudioTrack。它支持流式播放,可以读取(可来自内陆和网页)音频流,却播放耽误较小。
ps:据我测试AudioTrack干脆支持WAV和PCM,其余音频必要解码成PCM花样才气播放。(其余无损花样没有测试,有乐趣可以使本文提供的例子测试一下)
4. .jet的音频对照少见(有的游戏中在应用),可应用特地的播放器JetPlayer播放
5.对于体系类声响的播放和操纵,Ringtone更适合、
上篇:上一篇:Android Studio Design不表现layout控件
下篇:下一篇:android EditText光标地位(定位到末了)