pcm转wav、mp3

该代码段展示了如何使用lamejs库将PCM数据转换为MP3格式,以及将PCM数据转换为WAV格式。它包含了encodeMono函数用于MP3编码,pcmtoWav函数用于创建WAV头信息,最后是getPCM函数,用于从URL获取PCM数据并执行转换操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import lamejs from '@/utils/lame.all'
encodeMono(channels, sampleRate, samples) {
	console.log("开始转码为mp3 >>>>")
	var buffer = [];
	var mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
	var remaining = samples.length;
	var maxSamples = 1152;
	for (var i = 0; remaining >= maxSamples; i += maxSamples) {
		var mono = samples.subarray(i, i + maxSamples);
		var mp3buf = mp3enc.encodeBuffer(mono);
		if (mp3buf.length > 0) {
			buffer.push(new Int8Array(mp3buf));
		}
		remaining -= maxSamples;
	}
	
	var d = mp3enc.flush();
	if(d.length > 0){
		buffer.push(new Int8Array(d));
	}
	console.log('done encoding, size=', buffer.length);
	var blob = new Blob(buffer, {type: 'audio/mp3'});
	var bUrl = window.URL.createObjectURL(blob);
    this.mp3Url=bUrl
    console.log('转码完成');
    this.loading=false
}
pcmtoWav(pcmsrt, sampleRate, numChannels, bitsPerSample) {
  //参数->(pcm流,采样频率,声道数,采样位数)
  let header = {
    // OFFS SIZE NOTES
    chunkId: [0x52, 0x49, 0x46, 0x46], // 0    4    "RIFF" = 0x52494646
    chunkSize: 0, // 4    4    36+SubChunk2Size = 4+(8+SubChunk1Size)+(8+SubChunk2Size)
    format: [0x57, 0x41, 0x56, 0x45], // 8    4    "WAVE" = 0x57415645
    subChunk1Id: [0x66, 0x6d, 0x74, 0x20], // 12   4    "fmt " = 0x666d7420
    subChunk1Size: 16, // 16   4    16 for PCM
    audioFormat: 1, // 20   2    PCM = 1
    numChannels: numChannels || 1, // 22   2    Mono = 1, Stereo = 2...
    sampleRate: sampleRate || 16000, // 24   4    8000, 44100...
    byteRate: 0, // 28   4    SampleRate*NumChannels*BitsPerSample/8
    blockAlign: 0, // 32   2    NumChannels*BitsPerSample/8
    bitsPerSample: bitsPerSample || 16, // 34   2    8 bits = 8, 16 bits = 16
    subChunk2Id: [0x64, 0x61, 0x74, 0x61], // 36   4    "data" = 0x64617461
    subChunk2Size: 0, // 40   4    data size = NumSamples*NumChannels*BitsPerSample/8
  }
  function u32ToArray(i) {
    return [i & 0xff, (i >> 8) & 0xff, (i >> 16) & 0xff, (i >> 24) & 0xff]
  }
  function u16ToArray(i) {
    return [i & 0xff, (i >> 8) & 0xff]
  }  
  //let pcm = Base64.toUint8Array(pcmsrt)
  let pcm = new Uint8Array(pcmsrt)
  header.blockAlign = (header.numChannels * header.bitsPerSample) >> 3
  header.byteRate = header.blockAlign * header.sampleRate
  header.subChunk2Size = pcm.byteLength * (header.bitsPerSample >> 3)
  header.chunkSize = 36 + header.subChunk2Size

  let wavHeader = header.chunkId.concat(
    u32ToArray(header.chunkSize),
    header.format,
    header.subChunk1Id,
    u32ToArray(header.subChunk1Size),
    u16ToArray(header.audioFormat),
    u16ToArray(header.numChannels),
    u32ToArray(header.sampleRate),
    u32ToArray(header.byteRate),
    u16ToArray(header.blockAlign),
    u16ToArray(header.bitsPerSample),
    header.subChunk2Id,
    u32ToArray(header.subChunk2Size)
  )
  let wavHeaderUnit8 = new Uint8Array(wavHeader)

  let mergedArray = new Uint8Array(wavHeaderUnit8.length + pcm.byteLength)
  mergedArray.set(wavHeaderUnit8)
  mergedArray.set(pcm, wavHeaderUnit8.length)
  let blob = new Blob([mergedArray], { type: 'audio/wav' })
  let blobUrl = window.URL.createObjectURL(blob)
  console.log('blob',blob);
  this.audioSrc=blobUrl
  console.log('this.audioSrc',this.audioSrc);
  this.isSuccess=true
},

getPCM(url){
  // this.loading=true
  let data= fetch(url).then(res=>res.blob()
  
  ).then(res=>{
    // this.$http.get(this.url).then(res=>{
    console.log(res);
    // this.file=res.arrayBuffer()
   const file1=res
    let reader = new FileReader()
		reader.readAsArrayBuffer(file1)
		reader.onload =  ()=>{
			console.log(reader.result)
          this.pcmtoWav(reader.result)
         let samples = new Int16Array(reader.result)
         this.encodeMono(1, 16000, samples)
             //data = reader.result;
			 // 相当于请求下载pcm文件,转换为wav播放
	// console.log(pcmtoWav(reader.result))
         };
        //  this.loading=false
        })
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值