• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

【Android】播放音频的几种

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0519/500.html

接下来笔者先容一下Android中播放音频的几种体例,android.media包下面包含了Android开发中媒体类,固然笔者不会顺次去先容,下面先容几个音频播放中常用的类:

1.应用MediaPlayer播放音频

MediaPlayer的功效很壮大,下面附上一张该类封装音频的性命周期图:\MediaPlayer支持AACAMRFLACMP3MIDIOGGPCM等花样,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:采样率转化质量,默认值为

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,要是StreamID0表示播放腐朽,否则为播放胜利

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用的对照少的缘故,必要本人解码音频。

 

AudioTreack2种播放形式
静态形式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. // 获取体系所有Ringtonecursor

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看,RingtoneRingtoneManager照旧对照简单的,未几做注释了,干脆放上一段应用代码。

复制代码

/**

 * 播放回电铃声的默认音乐

*/

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干脆支持WAVPCM,其余音频必要解码成PCM花样才气播放。(其余无损花样没有测试,有乐趣可以使本文提供的例子测试一下)
4. .jet
的音频对照少见(有的游戏中在应用),可应用特地的播放器JetPlayer播放
5.对于体系类声响的播放和操纵,Ringtone更适合、

 

 

上篇:上一篇:Android Studio Design不表现layout控件
下篇:下一篇:android EditText光标地位(定位到末了)