Android音视频之AudioTrack播放音频(二)
讲了如何录制wav音频文件,本篇就来讲讲如何播放wav文件,这里就是使用audiotrack来播放音频,确切的说是播放pcm格式数据,使用audiotrack播放也没什么难度,主要就是将数据写入到audiotrack中就可以了,先贴代码
package cn.sskbskdrin.record.audio; import android.media.audiomanager; import android.media.audiotrack; import java.io.filenotfoundexception; import java.io.ioexception; import java.io.randomaccessfile; /** * @author sskbskdrin * @date 2019/april/3 */ public class audiotrackmanager { private audiotrack audiotrack; private boolean playing = false; public audioparams 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 = new audiotrack(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(); return params; } public static audioparams readwavheader(randomaccessfile file) throws ioexception { 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 new audioparams(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方法跳转到指定位置,可实现播放、暂停、继续播放的功能。
上一篇: The Scope Chain
推荐阅读
-
Android提高之MediaPlayer音视频播放
-
Android提高之MediaPlayer播放网络音频的实现方法
-
Android音视频之AudioTrack播放音频(二)
-
Android 之 使用SoundPool播放音频
-
Android 之 使用MediaPlayer播放音频
-
Android 之 使用SoundPool播放音频
-
Android提高之MediaPlayer音视频播放
-
Android提高之MediaPlayer播放网络音频的实现方法
-
Android音视频之AudioTrack播放音频(二)
-
Android使用AudioRecord和AudioTrack完成音频的采集和播放以及使用MediaCodec完成硬编和硬解