因最近项目需要多个音频文件前后拼接播放,所幸较大致看了下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--- 我这儿获取的采样率不可用。 使用这样播放节奏就感觉流程很多了。 打完收工--------------------