MediaPlayer和AudioTrack播放Audio的区别与联系
1个回答
展开全部
播放声音可以用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播放音乐的示例,音乐文件是从数据库中取出的。
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
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) {
}
}
其中最大的区别是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播放音乐的示例,音乐文件是从数据库中取出的。
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
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) {
}
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询