js转化pcm到wav格式与播放
前面我们已经实现了js录制pcm编码的功能了,但是很遗憾,浏览器并不能播放pcm音频,但可以支持与他比较相近的wav格式的文件,来琢磨下这两者的转化吧。 wavWaveform Audio File Format,是微软与IBM公司所开发在个人计算机存储音频流的编码格式。 wav可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被pcm编码处理的wav。但这不表示wav只能使用pcm编码,mp3编码同样也可以运用在wav中。简单来说,pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。 wav是一种无损的音频文件格式,由于此音频格式未经过压缩,所以在音质方面不会出现失真的情况,但文件的体积因而在众多音频格式中较为大。 一般情况下,wav数据实际上就是裸数据pcm外面包了一层文件头。在前面的文章中,我们已经拿到了pcm数据了,只要在其前部增加44个字节的wav头就行了。 wav头先上这张图吧, ChunkID偏移量0,占用了4字节,大端字节序,表示资源交换文件标识符,一般固定是”RIFF”。 ChunkSize偏移量4,占用4字节,小端字节序,下个地址开始到文件尾总字节数,即文件大小-8。 Format偏移量8,占用4字节,大端字节序,表示wav文件标志,一般固定为”WAVE”。 Subchunk1 ID偏移量12,占用4字节,大端字节序,表示波形格式标志,一般固定为”fmt “,注意最后有空格。 Subchunk1 Size偏移量16,占用4字节,小端字节序,表示过滤字节,一般为 0x10 = 16。 AudioFormat偏移量20,占用2字节,小端字节序,表示格式类别,1是PCM形式采样数据,故此处填1。 Num Channels偏移量22,占用2字节,小端字节序,表示声道数。 SampleRate偏移量24,占用4字节,小端字节序,表示采样率。 ByteRate偏移量28,占用4字节,小端字节序,表示波特率,即声道数 × 采样频率 × 采样位数 / 8。 BlockAlign偏移量32,占用2字节,小端字节序,声道数 × 采样位数 / 8。 Bits Per Sample偏移量34,占用2字节,小端字节序,采样位数. Subchunk2 Id偏移量36,占用4字节,大端字节序,数据标识符,一般固定为”data”。 Subchunk2 Size偏移量40,占用4字节,小端字节序,表示采样数据总数,即数据总大小-44。 data偏移量44,小端字节序,pcm数据。 js拼装给pcm的数据加上wav头就可以播放了,简单的处理如下: // 资源交换文件标识符 writeString(data,offset,'RIFF'); offset += 4; // 下个地址开始到文件尾总字节数,即文件大小-8 data.setUint32(offset,36 + bytes.byteLength,true); offset += 4; // WAV文件标志 writeString(data,'WAVE'); offset += 4; // 波形格式标志 writeString(data,'fmt '); offset += 4; // 过滤字节,一般为 0x10 = 16 data.setUint32(offset,16,true); offset += 4; // 格式类别 (PCM形式采样数据) data.setUint16(offset,1,true); offset += 2; // 声道数 data.setUint16(offset,channelCount,true); offset += 2; // 采样率,每秒样本数,表示每个通道的播放速度 data.setUint32(offset,sampleRate,true); offset += 4; // 波形数据传输率 (每秒平均字节数) 声道数 × 采样频率 × 采样位数 / 8 data.setUint32(offset,channelCount * sampleRate * (sampleBits / 8),true); offset += 4; // 快数据调整数 采样一次占用字节数 声道数 × 采样位数 / 8 data.setUint16(offset,channelCount * (sampleBits / 8),true); offset += 2; // 采样位数 data.setUint16(offset,sampleBits,true); offset += 2; // 数据标识符 writeString(data,'data'); offset += 4; // 采样数据总数,即数据总大小-44 data.setUint32(offset,bytes.byteLength,true); offset += 4; // 给wav头增加pcm体 for (let i = 0; i < bytes.byteLength; ++i) { data.setUint8(offset,bytes.getUint8(i,true),true); offset++; } 给pcm嵌入上wav头,那么浏览器就可以播放了。 播放createBufferSource方式该方法在web Audio学习与音频播放中就有了,将二进制传入就会被转成audioBuffer,这儿不多说了。 audio方式可以创建audio标签,外加window.createObjectURL方法返回资源路径给audio标签,再通过audio的播放就ok了。 总结到这,录音功能也算差不多完成了,当然还有很多细节待完善的,以及一些小功能可以开发。 本篇对应的demo请查看:js转化pcm到wav格式与播放。完整的录音插件请查看:recorder。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |