我们的司信项目又有了新的需求,就是要做会议室。然而需求却很纠结,要继续按照原来发语音消息那样的形式来实现这个会议的功能,还要实现语音播放的计时,暂停,语音的拼接,还要绘制频谱图等等。
如果是wav,mp3不论你怎么拼接,绘制频谱图,我也没有问题,网上都有现成的例子。然而这一次居然让用speex的音频做这一切。
于是看了司信之前的发语音消息部分speex的代码,天啊,人家录的时候这是实时录音实时编码的好不好,人家放的时候也是实时解码实时播放的好不
好。你这让我怎么通过
一个speex文件就得到全部的频谱图和时间啊,你让我怎么在播放的时候暂停,然后再按一下继续播放啊,这哪里是坑啊,这简直就是坑爹啊。
speex格式的文件是不能暂停的,也不能直接得到时间长度和频谱,因此只能转化成wav或者mp3格式的才可以。要想实现上面的功能就必须实现speex文件与正常音频格式的转换。
这里可能有些人对安卓的录音过程不太懂,先介绍一下(研究了这么久,就让我卖弄一下吧)
安卓录音的时候是使用AudioRecord来进行录制的(当然mediarecord也可以,mediarecord强大一些),录制后的数据称
为pcm,这就是raw(原始)数据,这些数据是没有任何文件头的,存成文件后用播放器是播放不出来的,需要加入一个44字节的头,就可以转变为wav格
式,这样就可以用播放器进行播放了。
怎么加头,代码在下边:
1 // 这里得到可播放的音频文件
2 private void copyWaveFile(String inFilename, String outFilename) {
3 FileInputStream in = null;
4 FileOutputStream out = null;
5 long totalAudioLen = 0;
6 long totalDataLen = totalAudioLen + 36;
7 long longSampleRate = AudioFileFunc.AUDIO_SAMPLE_RATE;
8 int channels = 2;
9 long byteRate = 16 * AudioFileFunc.AUDIO_SAMPLE_RATE * channels / 8;
10 byte[] data = new byte[bufferSizeInBytes];
11 try {
12 in = new FileInputStream(inFilename);
13 out = new FileOutputStream(outFilename);
14 totalAudioLen = in.getChannel().size();
15 totalDataLen = totalAudioLen + 36;
16 WriteWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate);
17 while (in.read(data) != -1) {
18 out.write(data);
19 }
20 in.close();
Last updated:2016-04-07