audiotrack java_Android音视频之AudioTrack播放音频(二)

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

packagecn.sskbskdrin.record.audio;importandroid.media.AudioManager;importandroid.media.AudioTrack;importjava.io.FileNotFoundException;importjava.io.IOException;importjava.io.RandomAccessFile;/***@authorsskbskdrin

* @date 2019/April/3*/

public classAudioTrackManager {privateAudioTrack audioTrack;private boolean playing = false;publicAudioParams playWav(String filepath, AudioRecordManager.RecordCallback callback) {

RandomAccessFile file= null;

AudioParams params= null;try{

file= new RandomAccessFile(filepath, "r");

params=readWavHeader(file);

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}if (params == null) {return null;

}int simpleRate =params.simpleRate;int channelConfig =params.getOutChannelConfig();int audioFormat =params.getEncodingFormat();int minBufSize =AudioTrack.getMinBufferSize(simpleRate, channelConfig, audioFormat);

audioTrack= newAudioTrack(AudioManager.STREAM_MUSIC, simpleRate, channelConfig, audioFormat, minBufSize,

AudioTrack.MODE_STREAM);final RandomAccessFile finalFile =file;new Thread(() ->{

playing= true;

audioTrack.play();byte[] buffer = new byte[minBufSize];try{

finalFile.seek(44);while(playing) {int read =finalFile.read(buffer);if (read > 0) {

audioTrack.write(buffer,0, read);

}else{

finalFile.close();

playing= false;

audioTrack.stop();

audioTrack.release();

}if (callback != null) {

callback.onRecord(buffer, read);

}

}

}catch(IOException e) {

e.printStackTrace();

}

}).start();returnparams;

}public static AudioParams readWavHeader(RandomAccessFile file) throwsIOException {

file.seek(22);byte channelCount =file.readByte();

file.seek(24);int sampleRate = file.readByte() & 0xff;

sampleRate|= (file.readByte() & 0xff) << 8;

sampleRate|= (file.readByte() & 0xff) << 16;

sampleRate|= (file.readByte() & 0xff) << 24;

file.seek(34);byte bits =file.readByte();return newAudioParams(sampleRate, channelCount, bits);

}

}

播放的方法,是传入文件路径,AudioRecordManager.RecordCallback可以为空。先是通过readWavHeader()方法读取wav文件的文件头信息,返回AudioParams,这个类是我前一篇文章有列出来,可以得到一些需要的数据。

关于读数据头部信息,可以参考这里,读取重要数据。

AudioTrack.getMinBufferSize(simpleRate, channelConfig, audioFormat)可以获取最小缓存大小。

AudioTrack的构造方法中,第一个参数为播放流的类型,有下面几种

AudioManager.STREAM_MUSIC //音乐

AudioManager.STREAM_VOICE_CALL //电话

AudioManager.STREAM_RING //铃声

AudioManager.STREAM_ALARM //闹钟

AudioManager.STREAM_NOTIFICATION //通知

最后了个参数是流写入的方式,有两种

AudioTrack.MODE_STREAM // 流写入

AudioTrack.MODE_STATIC //静态写入

AudioTrack.MODE_STREAM看名字大概就能知道是流的方式写入,边写边播。

AudioTrack.MODE_STATIC就是一次写完,然后播放,这种方式更适合比较短的声音播放,比如通知声音

开始播放时,先调用AudioTrack.play(),然后从wav文件的数据块开始读,即第44个字节开始,读完调用audioTrack.write写入pcm数据。当读不到数据时,停止AudioTrack,释放资源即可。

通过RandomAccessFile方式读取文件,可以记录读取的位置,并通过seek方法跳转到指定位置,可实现播放、暂停、继续播放的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值