Android播放音频MediaPlayer的几种方式介绍

少年意气强不羁,虎胁插翼白日飞。这篇文章主要讲述Android播放音频MediaPlayer的几种方式介绍相关的知识,希望能为你提供帮助。
【Android播放音频MediaPlayer的几种方式介绍】接下来笔者介绍一下android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类:
1.使用MediaPlayer播放音频MediaPlayer的功能很强大,下面附上一张该类封装音频的生命周期图:

Android播放音频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)
Android播放音频MediaPlayer的几种方式介绍

文章图片
//如果从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() ;

Android播放音频MediaPlayer的几种方式介绍

文章图片
 
setDataSource(FileDescriptor fd)
Android播放音频MediaPlayer的几种方式介绍

文章图片
//需将资源文件放在assets文件夹 AssetFileDescriptor fd = getAssets().openFd("samsara.mp3"); mMediaPlayer.setDataSource(fd.getFileDescriptor()); //经过笔者的测试,发现这个方法有时候不能播放成功,尽量使用该方法的另一个重载方法 setDataSource(FileDescptor fd,long offset,long length) mMediaPlayer.prepare() ; Ps:此方法系统需大于等于android

Android播放音频MediaPlayer的几种方式介绍

文章图片
 
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的常用方法
Android播放音频MediaPlayer的几种方式介绍

文章图片
start(); //开始播放 pause(); //暂停播放 reset()//清空MediaPlayer中的数据 setLooping(boolean); //设置是否循环播放 seekTo(msec)//定位到音频数据的位置,单位毫秒 stop(); //停止播放 relase(); //释放资源

Android播放音频MediaPlayer的几种方式介绍

文章图片
 
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的几个重要的方法
Android播放音频MediaPlayer的几种方式介绍

文章图片
// 几个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()

Android播放音频MediaPlayer的几种方式介绍

文章图片
下面简单演示一下SoundPool如何播放音乐:
Android播放音频MediaPlayer的几种方式介绍

文章图片
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); SoundPool soundPool=newSoundPool(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); //暂停 }

Android播放音频MediaPlayer的几种方式介绍

文章图片
 
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. 获取实例
Android播放音频MediaPlayer的几种方式介绍

文章图片
//获取实例方法,均为RingtoneManager类提供//1.通过铃声uri获取 static Ringtone getRingtone(Context context, Uri ringtoneUri)//2.通过铃声检索位置获取 Ringtone getRingtone(int position)

Android播放音频MediaPlayer的几种方式介绍

文章图片
 
2. RingtoneManager几个重要的方法
Android播放音频MediaPlayer的几种方式介绍

文章图片
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)

Android播放音频MediaPlayer的几种方式介绍

文章图片
从api看,Ringtone和RingtoneManager还是比较简单的,不多做解释了,直接放上一段使用代码。
Android播放音频MediaPlayer的几种方式介绍

文章图片
/** * 播放来电铃声的默认音乐 */ 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(); }

Android播放音频MediaPlayer的几种方式介绍

文章图片
最后记得添加权限:
      < 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中播放音乐的几种方式 前言
前几天一直在研究Rxjava2,也写了记录了几篇博客,但因为工作任务原因,需要研究音频相关的知识,暂时放下Rxjava,本文的demo中,MediaPalyer 部分使用RxJava编写一点逻辑,其中涉及,RxJava2的被压、解除订阅等知识点,虽然简单,最起码没有丢了RxJava,后续Rxjava会继续研究,做记录.
andorid提供了对声音和视频处理的api包android.media.本文编写了针对这几种方式播放的Demo,文章最后贴出。
MediaPlayer播放音频
对于android音频的播放,这个类可能是大家最熟悉的了,从入门就一直想编写一个自己的音乐播放器,有木有?MediaPlayer确实强大,提供了对音频播放的各种控制,生命周期:

Android播放音频MediaPlayer的几种方式介绍

文章图片

都很熟悉了,讲几个重点,其余不啰嗦了1. MediaPlayer支持:AAC、AMR、FLAC、MP3、MIDI、OGG、PCM等格式
2. 播放Raw下的元数据
//直接创建,不需要设置setDataSource mMediaPlayer=MediaPlayer.create(this, R.raw.audio); mMediaPlayer.start();

  • 1
  • 2
  • 3
  • 4
3. MediaPlayer设置播放源的4中方式
  • setDataSource (String path)
//从sd卡中加载音乐 mMediaPlayer.setDataSource("../music/samsara.mp3") ; //从网路加载音乐 mMediaPlayer.setDataSource("http://..../xxx.mp3") ; //需使用异步缓冲 mMediaPlayer.prepareAsync() ;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • setDataSource (FileDescriptor fd)
//需将资源文件放在assets文件夹 AssetFileDescriptor fd = getAssets().openFd("samsara.mp3"); mMediaPlayer.setDataSource(fd) mMediaPlayer.prepare() ; Ps:此方法系统需大于等于android

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • setDataSource (Context context, Uri uri)
这个方法没什么好说的,一般通过ContentProvider获取Android系统提供 的共享music获取uri,然后设置数据播放

  • 1
  • 2
  • setDataSource (FileDescriptor fd, long offset, long length)
//需将资源文件放在assets文件夹 AssetFileDescriptor fd = getAssets().openFd("samsara.mp3"); mMediaPlayer.setDataSource(fd, fd.getStartOffset(), fd.getLegth()) mMediaPlayer.prepare() ;

  • 1
  • 2
  • 3
  • 4
  • 5
4. 注意点
  • 设置完数据源,不要忘记prepare(),尽量使用异步prepareAync(),这样不会阻塞UI线程。
  • 播放完毕即使释放资源

    mediaPlayer.stop();
    mediaPlayer.release();
    mediaPlayer = null;
不足
资源占用量较高、延迟时间较长、不支持多个音频同时播放等
  • ### MeidaPlayer demo片段
//创建播放时间格式化工具 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(); }}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
SoundPool播放音频
SoundPool支持多个音频文件同时播放(组合音频也是有上限的),延时短,比较适合短促、密集的场景,是游戏开发中音效播放的福音。
SoundPool实例化方式 1. new SoundPool(适用与5.0以下)
SoundPool(int maxStreams, int streamType, int srcQuality) 从android5.0开始此方法被标记为过时,稍微说以下几个参数。 1.maxStreams :允许同时播放的流的最大值2.streamType :音频流的类型描述, 在Audiomanager中有种类型声明,游戏应用通常会使用流媒体音乐。 3. srcQuality:采样率转化质量

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
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() ;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
3. 几个重要的方法
// 几个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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
以上方法基本上是SoundPool的所有方法了,也都很常用。
4. 区分2个概念
看了Sounpool的api,是不是感觉对 streamID 和 soundID 一脸懵逼?
1. soundID:加载音乐资源时的返回值,int load(String path, int priority),这个int返回值就是soundID
2. streamID:播放时返回的值,即play()方法的返回值
这两个值都很重要,需要缓存下来
5. SoundPool Demo片段
注:我把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) ; }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
AudioTrack播放音频
AudioTrack属于更偏底层的音频播放,MediaPlayerService的内部就是使用了AudioTrack。AudioTrack用于单个音频播放和管理,相比于MediaPlayer具有:精炼、高效的优点。 更适合实时产生播放数据的情况,如加密的音频, MediaPlayer是束手无策的,AudioTrack却可以。AudioTrack用于播放PCM(PCM无压缩的音频格式)音乐流的回放, 如果需要播放其它格式音频,需要响应的解码器, 这也是AudioTrack用的比较少的原因,需要自己解码音频。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
AudioTreack的2种播放模式静态模式—static
静态的言下之意就是数据一次性交付给接收方。好处是简单高效,只需要进行一次操作就完成了数据的传递; 缺点当然也很明显,对于数据量较大的音频回放,显然它是无法胜任的,因而通常只用于播放铃声、系统提醒等对内存小的操作
流模式streaming
流模式和网络上播放视频是类似的,即数据是按照一定规律不断地传递给接收方的。理论上它可用于任何音频播放的场景,不过我们一般在以下情况下采用:
  • 音频文件过大
  • 音频属性要求高,比如采样率高、深度大的数据
  • 音频数据是实时产生的,这种情况就只能用流模式了
通过write(byte[], int, int), write(short[], int, int) write(float[], int, int, int)等方法推送解码数据到AudioTrack

  • 1
  • 2
  • 3
使用Demo
private void jetPlayStream(){ new Thread(new Runnable() { @RequiresApi(api = Build.VERSION_CODES.M) @Override public void run() { // 获取最小缓冲区 int bufSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); // 实例化AudioTrack(设置缓冲区为最小缓冲区的2倍,至少要等于最小缓冲区) AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufSize*2, AudioTrack.MODE_STREAM); // 设置音量 audioTrack.setVolume(2f) ; // 设置播放频率 audioTrack.setPlaybackRate(10) ; audioTrack.play(); // 获取音乐文件输入流 InputStream is = getResources().openRawResource(R.raw.zbc); byte[] buffer = new byte[bufSize*2] ; int len ; try { while((len=is.read(buffer,0,buffer.length)) != -1){ System.out.println("读取数据中..."); // 将读取的数据,写入Audiotrack audioTrack.write(buffer,0,buffer.length) ; } is.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
更深入的研究,请参考以下博客
http://blog.csdn.net/edmond999/article/details/18600323
http://blog.csdn.net/conowen/article/details/7799155/
AsyncPlayer播放音频
1.介绍
从名字就可看出AsyncPlayer属于异步播放器,官方给出的说明是:所有工作都在子线程进行,不影响调用线程任何操作。
AsyncPlayer就是对MediaPlayer的一次简单的封装,对MediaPlaer所有的操作都在新开线程中执行。
AsyncPlayer只适合简单的异步播放,不能控制进度,只能开始或停止播放。如果播放在此调用play()方法,AsyncPlayer会停止当前播放,开始新的播放。
播放源码
/** *内部线程类 **/ private final class Thread extends java.lang.Thread {public void run() { while (true) { Command cmd = null; synchronized (mCmdQueue) {//取出链表中新加入的cmd cmd = mCmdQueue.removeFirst(); }switch (cmd.code) { case PLAY: if (mDebug) Log.d(mTag, "PLAY"); //调用MediaPlayer播放 startSound(cmd); break; } .... } } } private void startSound(Command cmd) { // Preparing can be slow, so if there is something else // is playing, let it continue until we\'re done, so if (mDebug) Log.d(mTag, "Starting playback"); MediaPlayer player = new MediaPlayer(); player.setAudiostreamType(cmd.stream); player.setDataSource(cmd.context, cmd.uri); player.setLooping(cmd.looping); player.prepare(); player.start(); ....}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
2.简单demo
十分简单,不再贴出,可以在文末Demo中看到

  • 1
JetPlayer播放音频
Jet是由OHA联盟成员SONiVOX开发的一个交互音乐引擎。其包括两部分:JET播放器和JET引擎。JET常用于控制游戏的声音特效,采用MIDI(Musical Instrument Digital Interface)格式。
ps:以后遇到手机中的”.jet”文件,就只到它究竟是什么东东了。。。
  • 获取实例
//获取JetPlayer播放器 JetPlayer mJet = JetPlayer.getJetPlayer() ;

  • 1
  • 2
  • 3
  • 几个重要方法
// 清空分段队列,并清除所有要进行播放的剪辑。 1. boolean clearQueue()//每次播放前,记得做一次清空操作// 加载jet文件的方法 2. <

    推荐阅读