背景:公司有个文章转语音的需求,调用的是腾讯的tts接口,但是接口有限制,每次只能请求110个字,文章字数有800字以上,所以开始采用的是字符串拆分,分别请求,返回的base64音频直接拼接,浏览器可以正常播放,但此时有个问题,下载下来只有一段;原因是tts接口返回mp3格式的时候会带有文件头,不能直接拼接
解决方案:
返回pcm格式的音频(这个是不带文件头的),然后拼接。
但是pcm格式的音频无法播放,需要转化成可播放的音频格式,这里转的是wav格式。
代码如下:
/**
dst:二进制字符串
numchannel:1=单声道,2=多声道
saplerate:采样率 8000/16000
*/
func PcmToWav(dst string, numchannel int, saplerate int) (resDst string) {
byteDst := []byte(dst)
longSampleRate := saplerate
byteRate := 16 * saplerate * numchannel / 8
totalAudioLen := len(byteDst)
totalDataLen := totalAudioLen + 36
var header = make([]byte, 44)
// RIFF/WAVE header
header[0] = 'R'
header[1] = 'I'
header[2] = 'F'
header[3] = 'F'
header[4] = byte(totalDataLen & 0xff)
header[5] = byte((totalDataLen >> 8) & 0xff)
header[6] = byte((totalDataLen >> 16) & 0xff)
header[7] = byte((totalDataLen >> 24) & 0xff)
//WAVE
header[8] = 'W'
header[9] = 'A'
header[10] = 'V'
header[11] = 'E'
// 'fmt ' chunk
header[12] = 'f'
header[13] = 'm'
header[14] = 't'
header[15] = ' '
// 4 bytes: size of 'fmt ' chunk
header[16] = 16
header[17] = 0
header[18] = 0
header[19] = 0
// format = 1
header[20] = 1
header[21] = 0
header[22] = byte(numchannel)
header[23] = 0
header[24] = byte(longSampleRate & 0xff)
header[25] = byte((longSampleRate >> 8) & 0xff)
header[26] = byte((longSampleRate >> 16) & 0xff)
header[27] = byte((longSampleRate >> 24) & 0xff)
header[28] = byte(byteRate & 0xff)
header[29] = byte((byteRate >> 8) & 0xff)
header[30] = byte((byteRate >> 16) & 0xff)
header[31] = byte((byteRate >> 24) & 0xff)
// block align
header[32] = byte(2 * 16 / 8)
header[33] = 0
// bits per sample
header[34] = 16
header[35] = 0
//data
header[36] = 'd'
header[37] = 'a'
header[38] = 't'
header[39] = 'a'
header[40] = byte(totalAudioLen & 0xff)
header[41] = byte((totalAudioLen >> 8) & 0xff)
header[42] = byte((totalAudioLen >> 16) & 0xff)
header[43] = byte((totalAudioLen >> 24) & 0xff)
headerDst := string(header)
resDst = headerDst + dst
return
}
实际上pcm格式的文件无法播放的原因就是没有文件头,这里转化操作就是给它拼上一个文件头。。。。