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

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

注: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. tomcat源码解读(2)–容器责任链模式的实现

    责任链模式:责任链模式可以用在这样的场景,当一个request过来的时候,需要对这个request做一系列的加工,使用责任链模式可以使每个加工组件化,减少耦合.也可以使用在当一个request过来的时 ...

  2. php Zend Opcache,xcache,eAccelerator缓存优化详解及对比

    XCACHE XCache 是一个开源的 opcode 缓存器/优化器, 这意味着他能够提高您服务器上的 PHP 性能. 他通过把编译 PHP 后的数据缓冲到共享内存从而避免重复的编译过程, 能够直接 ...

  3. VS2005打开VS2008 VS2010 VS2012

    我用vs2005较多,但网上找的代码经常是08 10 或者2012的,总结了以下技巧可以打开工程比较小巧的高版本代码. <1>用记事本打开解决方案文件“解决方案名.sln”,然后修改最上面 ...

  4. what is WLAN ? when and why we need use it ?

    无线局域网络(Wireless Local Area Networks: WLAN)是相当便利的数据传输系统,它利用射频(Radio Frequency: RF)的技术,取代旧式碍手碍脚的双绞铜线(C ...

  5. wpf 实现全屏与取消全屏

    /// <summary> /// 全屏 /// </summary> public void ToFullscreen() { //存储窗体信息 m_WindowState ...

  6. 1006. Sign In and Sign Out

    #include <stdio.h> #include <algorithm> #include <iostream> #include <string.h& ...

  7. Telerik 控件事例(鼠标拖动行,拖动列,设置行对齐,行宽,是否显示)

    People.cs using System;using System.Collections.Generic;using System.Data;using System.Linq;using Sy ...

  8. JS两种声明函数的方法以及调用顺序

    两种声明方法: 1. var a = function () {...}; 2. function a() {...}; 第一种方式必须先声明后调用,而第二种方式函数调用在声明之前之后都可以. //第 ...

  9. [转]深度理解依赖注入(Dependence Injection)

    http://www.cnblogs.com/xingyukun/archive/2007/10/20/931331.html 前面的话:提到依赖注入,大家都会想到老马那篇经典的文章.其实,本文就是相 ...

  10. 1042: [HAOI2008]硬币购物 - BZOJ

    Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法.Input 第一行 ...