android使用AudioTrack播放多个音频文件

时间:2021-07-15 03:57:41

因最近项目需要多个音频文件前后拼接播放,所幸较大致看了下android常用播放音频的几种方式。

MediaPlayer类--(常用于播放长音频)缺陷-音频播放前后延迟太高(实验前后拼接播放时间为10s,正常播放整段语音时间为6s)

 SoundPool类--(常用播放游戏,点击声音等短音频)缺陷-需要提前加载数据,没有播放完毕监听

  AudioTrack类--

MODE_STREAM流播放模式(可以边读取边播放,大音频必用):

 
/** * -- 流式播放音频(用于播放大音频) */ 
void palyStream() {        try {            mFile = getAssets().open("raw/" + rawFath);        } catch (Exception e) {        }        if (mTrack == null && mFile != null) {            try {                bufsize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);                mTrack = new AudioTrack(AudioManager.STREAM_MUSIC , 8000,  //每秒8K个点(采样率) AudioFormat.CHANNEL_OUT_STEREO, //双声道 AudioFormat.ENCODING_PCM_16BIT, //一个采样点16比特-2个字节(设置音频数据块是8位还是16-采样精度) bufsize,                        AudioTrack.MODE_STREAM);            } catch (Exception e) {            }        }        if (mTrack != null) {            mTrack.play();            int readResult = 0;            byte buffer[] = new byte[bufsize];            while (true) {                try {                    readResult = mFile.read(buffer, 0, bufsize);                } catch (IOException e1) {                }                if (readResult != -1) {                    // AudioTrack.PLAYSTATE_PAUSED(暂停状态), mTrack.write(buffer, 0, readResult);                } else {                    break;                }            }            // -- 输出流可以重复使用 try {// mFile.close(); mFile.reset();                readHeader(mFile);            } catch (IOException e) {                e.printStackTrace();            }            // -- 重置mTrack状态 mTrack.stop();            // -- 释放底层资源。// mTrack.release(); }    }
 MODE_STATIC 模式		
 
/** * -- 静态播放(需要提前获取输入流,延迟低,用于播放小音频) */
void palyStatic() {    try {        mFile = getAssets().open("raw/" + rawFath);    } catch (Exception e) {    }    if (mTrack == null && mFile != null) {        try {            readHeader(mFile);            mBuffer = new byte[1024 * 1024];            mLen = (short) mFile.read(mBuffer);            // AudioTrack.MODE_STREAM(不能重复播放) ;AudioTrack.MODE_STATIC(可以重复播放) mTrack = new AudioTrack(AudioManager.STREAM_MUSIC , 8000,  //每秒8K个点(采样率) AudioFormat.CHANNEL_OUT_STEREO, //双声道 AudioFormat.ENCODING_PCM_16BIT, //一个采样点16比特-2个字节(设置音频数据块是8位还是16-采样精度) mLen,                    AudioTrack.MODE_STREAM);        } catch (Exception e) {        }    }    if (mTrack != null) {        short written = (short) mTrack.write(mBuffer, 0, mLen);        mTrack.play();    }}
 
 
/** * -- 获取音频wav文件头信息 * @param wavStream * @throws IOException */public void readHeader(InputStream wavStream) throws IOException {    ByteBuffer buffer = ByteBuffer.allocate(44);    buffer.order(ByteOrder.LITTLE_ENDIAN);    wavStream.read(buffer.array(), buffer.arrayOffset(), buffer.capacity());    buffer.rewind();    buffer.position(buffer.position() + 20);    format = buffer.getShort();  // --格式 channels = buffer.getShort();  // --声道 rate = buffer.getInt(); // --采样率 buffer.position(buffer.position() + 6);    bits = buffer.getShort(); // --采样精度 while (buffer.getInt() != 0x61746164) { // "data" marker int size = buffer.getInt();        wavStream.skip(size);        buffer.rewind();        wavStream.read(buffer.array(), buffer.arrayOffset(), 8);        buffer.rewind();    }    dataSize = buffer.getInt();  // -- 数据长度 Log.d("TAG", "readHeader: format=" + format + "--channels=" + channels + "--rate=" + rate + "--bits=" + bits + "--dataSize=" + dataSize);}
源码下载:http://download.csdn.net/detail/w1027296673/9385585
--- 我这儿获取的采样率不可用。 使用这样播放节奏就感觉流程很多了。
 
打完收工--------------------