Nodejs 代码生成一段音频
参考:https://www.zhihu.com/question/57929023
---
// riffID 4 Chunk ID: RIFF // cksize 4 Chunk size: 4 + 24 + (8 + M*Nc*Ns + (0 or 1) // WAVEID 4 WAVE ID: WAVE // ckID 4 Chunk ID: fmt // cksize 4 Chunk size: 16 // wFormatTag 2 WAVE_FORMAT_PCM // nChannels 2 Nc // nSamplesPerSec 4 F // nAvgBytesPerSec 4 F*M*Nc // nBlockAlign 2 M*Nc // wBitsPerSample 2 rounds up to 8*M // ckID 4 Chunk ID: data // cksize 4 Chunk size: M*Nc*Ns // sampled data M*Nc*Ns Nc*Ns channel-interleaved M-byte samples // pad byte 0 or 1 Padding byte if M*Nc*Ns is odd const fs = require('fs') function FormatChunk(channel = 1, frequency = 44100, avgFrequency = 44100) { this.fmtID = 'fmt '; this.wFormatTag = 0x0001; this.nChannels = channel; this.nSamplesPerSec = frequency; this.nAvgBytesPerSec = avgFrequency * channel; this.nBlockAlign = 1; this.wBitsPerSample = 8; this.bufferSize = 2 + 2 + 4 + 4 + 2 + 2; this.getBuffer = () => { const buffer = Buffer.alloc(this.bufferSize); let oft = 0; buffer.writeUInt8(this.wFormatTag, oft); oft += 2; buffer.writeUInt8(this.nChannels, oft); oft += 2; buffer.writeUInt32LE(this.nSamplesPerSec, oft); oft += 4; buffer.writeUInt32LE(this.nAvgBytesPerSec, oft); oft += 4; buffer.writeUInt8(this.nBlockAlign, oft); oft += 2; buffer.writeUInt8(this.wBitsPerSample, oft); return buffer; } } function Riff() { this.riffID = 'RIFF'; } function SampledData(frequency = 0) { this.dataID = "data"; this.sampled = Buffer.alloc(frequency * 4); for (let i = 0; i < frequency * 4; i++) { this.sampled.writeUInt8(i % 64 < 32 ? 0 : 255, i); } this.getBuffer = () => { return this.sampled; } this.bufferSize = frequency * 4; } function Wav() { this.waveID = 'WAVE'; this.frequency = 44100; this.Nc = 1; this.M = 1; //三大模块的数据 this.riff = new Riff(); this.formatChunk = new FormatChunk(1, this.frequency, this.frequency); this.sampledData = new SampledData(this.frequency); // 三大模块的字节大小 this.riffSize = 4 + 4 + 4 + this.formatChunk.bufferSize + 4 + 4 + this.sampledData.bufferSize; // 16 176400 176436 console.log(this.formatChunk.bufferSize, this.sampledData.bufferSize, this.riffSize); // 生成文件二进制 const fileBufferSize = 4 + 4 + 4 + 4 + 4 + this.formatChunk.bufferSize + 4 + 4 + this.sampledData.bufferSize; const fileBuffer = Buffer.alloc(fileBufferSize); let fileOft = 0; // ---------------- fileBuffer.write(this.riff.riffID, fileOft); fileOft += 4; fileBuffer.writeUInt32LE(this.riffSize, fileOft); fileOft += 4; fileBuffer.write(this.waveID, fileOft); fileOft += 4; // ---------- fileBuffer.write(this.formatChunk.fmtID, fileOft); fileOft += 4; fileBuffer.writeUInt32LE(this.formatChunk.bufferSize, fileOft); fileOft += 4; // --------- // console.log(fileBufferSize); const fmtBuffer = this.formatChunk.getBuffer(); fmtBuffer.copy(fileBuffer, fileOft); fileOft += this.formatChunk.bufferSize; // ----------- fileBuffer.write(this.sampledData.dataID, fileOft); fileOft += 4; fileBuffer.writeUInt32LE(this.sampledData.bufferSize, fileOft); fileOft += 4; const sampledDataBuffer = this.sampledData.getBuffer(); sampledDataBuffer.copy(fileBuffer, fileOft); return fileBuffer; } const fileBuffer = new Wav(); fs.writeFileSync('test.wav', fileBuffer);
--