转自http://blog.csdn.net/ameyume/article/details/7618820

播放声音可以用MediaPlayer和AudioTrack,两者都提供了java API供应用开发者使用。虽然都可以播放声音,但两者还是有很大的区别的。 其中最大的区别是MediaPlayer可以播放多种格式的声音文件,例如MP3,AAC,WAV,OGG,MIDI等。MediaPlayer会在framework层创建对应的音频解码器。 而AudioTrack只能播放已经解码的PCM流,如果是文件的话只支持wav格式的音频文件,因为wav格式的音频文件大部分都是PCM流。AudioTrack不创建解码器,所以只能播放不需要解码的wav文件。
当然两者之间还是有紧密的联系的,MediaPlayer在framework层还是会创建AudioTrack,把解码后的PCM数流传递给AudioTrack,AudioTrack再传递给AudioFlinger进行混音,然后才传递给硬件播放。 所以是MediaPlayer包含了AudioTRack。 通过查看API可以知道,MediaPlayer提供了5个setDataSource方法,分为三类,一类是传递播放文件的字符串路径作为参数,例如直接取sd卡里mp3文件的路径,一类是传递播放文件的FileDescriptor文件描述符作为播放的id,例例如从db中查询的音频文件的id,就可以直接赋给MediaPlayer进行播放。还有一类是Uri类型的资源文件,用于播放content uri文件。
下面是一个用MediaPlayer播放音乐的示例,音乐文件是从数据库中取出的。

  1. if (mMediaPlayer == null) {
  2. mMediaPlayer = new MediaPlayer(); // 创建MediaPlayer对象
  3. }
  4. mMediaPlayer.reset();
  5. String dataSource = getDataByPosition(mCursor, mPlayPosition);
  6. mMediaPlayer.setDataSource(dataSource); // 设置需要播放的数据源
  7. mMediaPlayer.prepare(); // 准备播放,如果是流媒体需要调用prepareAsync进行异步准备
  8. if (Common.PLAY_MODE_SINGLE_LOOP == mPlayMode) {
  9. mMediaPlayer.setLooping(true); // 单曲循环
  10. } else {
  11. mMediaPlayer.setLooping(false); // 不循环播放
  12. }
  13. mMediaPlayer.start(); // 开始播放,如果是播放流媒体,需要等到流媒体准备完成才能播放(在prepare的callback函数中调用start进行播放)
  14. // 根据位置来获取歌曲位置
  15. public String getDataByPosition(Cursor c, int position) {
  16. c.moveToPosition(position);
  17. int dataColumn = c.getColumnIndex(MediaStore.Audio.Media.DATA);
  18. String data = c.getString(dataColumn);
  19. return data;
  20. }
    if (mMediaPlayer == null) {
mMediaPlayer = new MediaPlayer(); // 创建MediaPlayer对象
} mMediaPlayer.reset();
String dataSource = getDataByPosition(mCursor, mPlayPosition);
mMediaPlayer.setDataSource(dataSource); // 设置需要播放的数据源
mMediaPlayer.prepare(); // 准备播放,如果是流媒体需要调用prepareAsync进行异步准备
if (Common.PLAY_MODE_SINGLE_LOOP == mPlayMode) {
mMediaPlayer.setLooping(true); // 单曲循环
} else {
mMediaPlayer.setLooping(false); // 不循环播放
}
mMediaPlayer.start(); // 开始播放,如果是播放流媒体,需要等到流媒体准备完成才能播放(在prepare的callback函数中调用start进行播放) // 根据位置来获取歌曲位置
public String getDataByPosition(Cursor c, int position) {
c.moveToPosition(position);
int dataColumn = c.getColumnIndex(MediaStore.Audio.Media.DATA);
String data = c.getString(dataColumn);
return data;
}

AudioTrack播放声音时不能直接把wav文件传递给AudioTrack进行播放,必须传递buffer,通过write函数把需要播放的缓冲区buffer传递给AudioTrack,然后才能播放。
AudioTrack使用的例子参考下面: 此示例转自:http://samyou.iteye.com/blog/1125872

  1. public class AndroidTest extends Activity implements View.OnClickListener,SurfaceHolder.Callback
  2. {
  3. private SurfaceHolder surfaceHolder = null;
  4. private SurfaceView surfaceView = null;
  5. private AudioTrack audioTrack = null;
  6. private Thread writePCMThread = null;
  7. private File audioFile = null;
  8. private FileInputStream fileInputStream = null;
  9. private byte buffer[] = new byte[16*10000];
  10. // The Handler that gets information back from the other threads
  11. private final Handler msgHandler = new Handler()
  12. {
  13. public void handleMessage(Message msg)
  14. {
  15. switch (msg.what)
  16. {
  17. default:
  18. break;
  19. }
  20. }
  21. };
  22. /** Called when the activity is first created. */
  23. @Override
  24. public void onCreate(Bundle savedInstanceState) {
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.main);
  27. surfaceView = (SurfaceView) findViewById(R.id.surface);
  28. SurfaceHolder surfaceHolder = surfaceView.getHolder();
  29. surfaceHolder.addCallback(this);
  30. surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  31. findViewById(R.id.button1).setOnClickListener(this);
  32. findViewById(R.id.button2).setOnClickListener(this);
  33. }
  34. public void finish() {
  35. super.finish();
  36. System.out.println("finish");
  37. try {
  38. writePCMThread.interrupt();
  39. } catch (Exception e) {
  40. }
  41. try {
  42. fileInputStream.close();
  43. } catch (Exception e) {
  44. }
  45. try {
  46. audioTrack.stop();
  47. audioTrack.release();
  48. } catch (Exception e) {
  49. }
  50. }
  51. protected void onResume()
  52. {
  53. super.onResume();
  54. System.out.println("back on!!!!!!!!!!!");
  55. initAudioTrack();
  56. audioFile = new File(Environment.getExternalStorageDirectory(),"test.wav");
  57. System.out.println(audioFile.length());
  58. try {
  59. fileInputStream = new FileInputStream(audioFile);
  60. fileInputStream.skip(0x2c);
  61. } catch (Exception e) {
  62. }
  63. writePCMThread = new Thread(new Runnable(){
  64. public void run() {
  65. try
  66. {
  67. while(fileInputStream.read(buffer)>=0)
  68. {
  69. System.out.println("write pcm data");
  70. audioTrack.write(buffer, 0, buffer.length);
  71. }
  72. }
  73. catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. }
  77. });
  78. }
  79. private void initAudioTrack()
  80. {
  81. int minBufferSize = AudioTrack.getMinBufferSize(0xac44, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
  82. System.out.println("minBufferSize = "+minBufferSize);
  83. audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 0xac44,
  84. AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize*2,AudioTrack.MODE_STREAM);
  85. audioTrack.setStereoVolume(1.0f, 1.0f);// 设置当前音量大小
  86. System.out.println("initAudioTrack over");
  87. audioTrack.play();
  88. }
  89. public void onClick(View v)
  90. {
  91. switch (v.getId()) {
  92. case R.id.button1:
  93. writePCMThread.start();
  94. break;
  95. case R.id.button2:
  96. break;
  97. default:
  98. break;
  99. }
  100. }
  101. public void surfaceCreated(SurfaceHolder holder) {
  102. System.out.println("surfaceCreated()");
  103. this.surfaceHolder = holder;
  104. }
  105. public void surfaceDestroyed(SurfaceHolder holder) {
  106. }
  107. public void surfaceChanged(SurfaceHolder holder, int format, int width,
  108. int height) {
  109. this.surfaceHolder = holder;
  110. }
  111. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  112. }
  113. }
public class AndroidTest extends Activity implements View.OnClickListener,SurfaceHolder.Callback
{
private SurfaceHolder surfaceHolder = null;
private SurfaceView surfaceView = null;
private AudioTrack audioTrack = null;
private Thread writePCMThread = null;
private File audioFile = null;
private FileInputStream fileInputStream = null;
private byte buffer[] = new byte[16*10000]; // The Handler that gets information back from the other threads
private final Handler msgHandler = new Handler()
{
public void handleMessage(Message msg)
{
switch (msg.what)
{
default:
break;
}
}
}; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
surfaceView = (SurfaceView) findViewById(R.id.surface);
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
} public void finish() {
super.finish();
System.out.println("finish");
try {
writePCMThread.interrupt();
} catch (Exception e) {
}
try {
fileInputStream.close();
} catch (Exception e) {
}
try {
audioTrack.stop();
audioTrack.release();
} catch (Exception e) {
}
} protected void onResume()
{
super.onResume();
System.out.println("back on!!!!!!!!!!!");
initAudioTrack();
audioFile = new File(Environment.getExternalStorageDirectory(),"test.wav");
System.out.println(audioFile.length());
try {
fileInputStream = new FileInputStream(audioFile);
fileInputStream.skip(0x2c);
} catch (Exception e) {
} writePCMThread = new Thread(new Runnable(){
public void run() {
try
{
while(fileInputStream.read(buffer)>=0)
{
System.out.println("write pcm data");
audioTrack.write(buffer, 0, buffer.length);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}); } private void initAudioTrack()
{
int minBufferSize = AudioTrack.getMinBufferSize(0xac44, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
System.out.println("minBufferSize = "+minBufferSize);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 0xac44,
AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize*2,AudioTrack.MODE_STREAM);
audioTrack.setStereoVolume(1.0f, 1.0f);// 设置当前音量大小
System.out.println("initAudioTrack over");
audioTrack.play();
} public void onClick(View v)
{
switch (v.getId()) {
case R.id.button1:
writePCMThread.start();
break;
case R.id.button2:
break;
default:
break;
} } public void surfaceCreated(SurfaceHolder holder) {
System.out.println("surfaceCreated()");
this.surfaceHolder = holder;
} public void surfaceDestroyed(SurfaceHolder holder) {
} public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
this.surfaceHolder = holder;
} public void onActivityResult(int requestCode, int resultCode, Intent data) {
} }

注:PCM和WAV

以下摘自:http://www.erji.net/read.php?tid=227570

简单来说,pcm是一种数据编码格式,CD唱盘上刻录的就直接用pcm格式编码的数据文件; wav是一种声音文件格式,wav里面包含的声音数据可以是采用pcm格式编码的声音数据,也可以是采用其它格式编码的声音数据,但目前一般采用pcm编码的声音数据 两者区别就是这些

pcm是一个通信上的概念,脉冲编码调制。wav是媒体概念,体现的是封装。wav文件可以封装pcm编码信息,也可以封装其他编码格式,例如mp3等。

MediaPlayer和AudioTrack播放Audio的区别与联系的更多相关文章

  1. Android 音视频开发(三):使用 AudioTrack 播放PCM音频

    一.AudioTrack 基本使用 AudioTrack 类可以完成Android平台上音频数据的输出任务.AudioTrack有两种数据加载模式(MODE_STREAM和MODE_STATIC),对 ...

  2. 使用AudioTrack播放PCM音频数据(android)

    众所周知,Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer实现的.MediaPl ...

  3. Android音视频之AudioTrack播放音频(二)

    前一篇讲了如何录制wav音频文件,本篇就来讲讲如何播放wav文件,这里就是使用AudioTrack来播放音频,确切的说是播放pcm格式数据,使用AudioTrack播放也没什么难度,主要就是将数据写入 ...

  4. android开发之MediaPlayer+Service MP3播放器

    import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.Lis ...

  5. Android开发 MediaPlayer入门_播放本地视频

    前言 MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频.(如果你嫌MediaPlayer还是太麻烦可以试试选择Vi ...

  6. Android音频: 怎样使用AudioTrack播放一个WAV格式文件?

    翻译 By Long Luo 原文链接:Android Audio: Play a WAV file on an AudioTrack 译者注: 1. 因为这是技术文章,所以有些词句使用原文,表达更准 ...

  7. 【Android 多媒体应用】使用MediaCodec解码使用AudioTrack播放音频数据

    1.MainActivity.java import android.app.Activity; import android.os.Bundle; import android.os.Environ ...

  8. audio 基本功能实现(audio停止播放,audio如何静音,audio音量控制等)

    audio最简单原始的播放.暂停.停止.静音.音量大小控制的功能,注意某些浏览器会有权限无法自动播放噢(video也会如此) <!doctype html> <html> &l ...

  9. Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例

    前言:前面一篇我们介绍MediaPlayer相关方法,有人说,没有实际例子,看得不是很明白,今天在分析MediaPlayer时,顺带一个播放网络视频例子.可以自行试试.今天分析的都是下几篇介绍各个模块 ...

随机推荐

  1. c#中const与readonly区别

    const 的概念就是一个包含不能修改的值的变量.常数表达式是在编译时可被完全计算的表达式.因此不能从一个变量中提取的值来初始化常量.如果 const int a = b+1;b是一个变量,显然不能再 ...

  2. IE11下ASP.NET Forms身份认证无法保存Cookie的问题

    IE11下ASP.NET Forms身份认证无法保存Cookie的问题 折腾了三四天,今天才找到资料,解决了. 以下会转贴,还没来得及深究,先放着,有空再学习下. ASP.NET中使用Forms身份认 ...

  3. 由于Linux操作平台屡次受到黑客的“青睐”,LINUX公司也越来越注重产品的安全问题。

    Guardian Digital公司和安全管理服务提供商(MSSP)Guardent公司推出的新产品将提高开放式源代码和Linux产品的安全性能. Guardian Digital公司将于本月底在纽约 ...

  4. Spark Streaming揭秘 Day32 WAL框架及实现

    Spark Streaming揭秘 Day32 WAL框架及实现 今天会聚焦于SparkStreaming中非常重要的数据安全机制WAL(预写日志). 设计要点 从本质点说,WAL框架是一个存储系统, ...

  5. N皇后问题2

    Description Examine the  checkerboard below and note that the six checkers are arranged on the board ...

  6. 十六、mysql 分区之 简单sql优化2

    .索引的分类 B-Tree 基本支持 HASH 只有memory支持 R-Tree myisam支持 Full-text myisam支持(全文索引) .Memory引擎下只有“=”条件才会使用索引 ...

  7. [译] ASP.NET 生命周期 – ASP.NET 上下文对象(六)

    使用 HttpApplication 对象 ASP.NET 框架中的许多类都提供了许多很方便的属性可以直接映射到 HttpContext 类中定义的属性.这种交叠有一个很好的例子就是 HttpAppl ...

  8. 【BZOJ 2878】 [Noi2012]迷失游乐园

    Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环( ...

  9. google calendar api v3

    google api for .net nuget Install-Package Google.Apis.Calendar.v3 oauth2 for asp.net http://www.code ...

  10. multimap和multiset 认知和使用

    之前只是在C++ Primer里面看过关联容器,可能因为没有实际用过,只是看看,所以导致用的时候并不熟悉: 在这之前,map和set的特性应该要了解,map是关联数组,也就是由键值对组成的,而set只 ...