簡體   English   中英

將 LINEAR16 音頻編碼為 Twilio 媒體音頻/x-mulaw | 節點

[英]Encode LINEAR16 audio to Twilio media audio/x-mulaw | NodeJS

我一直在嘗試將 mulaw 媒體流傳輸回 Twilio。 要求是有效載荷必須編碼音頻/x-mulaw 采樣率為 8000 和 base64 編碼

我的輸入來自 LINEAR16 Google Docs 中的@google-cloud/text-to-speech

我試過波形文件

這就是我編碼來自@google-cloud/text-to-speech 的響應的方式

 const wav = new wavefile.WaveFile(speechResponse.audioContent)
    wav.toBitDepth('8')
    wav.toSampleRate(8000)
    wav.toMuLaw()

然后我通過 websocket 將結果發送回 twilio

twilioWebsocket.send(JSON.stringify({
      event: 'media',
      media: {
        payload: wav.toBase64(),
      },
      streamSid: meta.streamSid,
}))

問題是我們只在 twilio 調用的另一端出現隨機噪聲,似乎編碼不正確

其次,我通過保存在文件中檢查了@google-cloud/text-to-speech 輸出音頻,它是正確和清晰的

誰能幫我編碼

我也有同樣的問題。 錯誤在wav.toBase64() ,因為這包括 wav 標頭。 Twilio 媒體流需要原始音頻數據,您可以使用wav.data.samples獲得,因此您的代碼將是:

 const wav = new wavefile.WaveFile(speechResponse.audioContent)
    wav.toBitDepth('8')
    wav.toSampleRate(8000)
    wav.toMuLaw()

 const payload = Buffer.from(wav.data.samples).toString('base64');

我只是遇到了同樣的問題。 解決方案是,您需要手動將 LINEAR16 轉換為相應的 MULAW 編解碼器。

您可以使用音樂庫中的代碼。

我創建了一個函數來將一個線性 16 字節數組轉換為 mulaw:

short2ulaw(b: Buffer): Buffer {
    // Linear16 to linear8 -> buffer is half the size
    // As of LINEAR16 nature, the length should ALWAYS be even
    const returnbuffer = Buffer.alloc(b.length / 2)

    for (let i = 0; i < b.length / 2; i++) {
      // The nature of javascript forbids us to use 16-bit types. Every number is
      // A double precision 64 Bit number.
      let short = b.readInt16LE(i * 2)

      let sign = 0

      // Determine the sign of the 16-Bit byte
      if (short < 0) {
        sign = 0x80
        short = short & 0xef
      }

      short = short > 32635 ? 32635 : short

      const sample = short + 0x84
      const exponent = this.exp_lut[sample >> 8] & 0x7f
      const mantissa = (sample >> (exponent + 3)) & 0x0f
      let ulawbyte = ~(sign | (exponent << 4) | mantissa) & 0x7f

      ulawbyte = ulawbyte == 0 ? 0x02 : ulawbyte

      returnbuffer.writeUInt8(ulawbyte, i)
    }

    return returnbuffer
  }

現在您可以在原始 PCM (Linear16) 上使用它。 現在你只需要考慮在谷歌流的開頭去除字節,因為谷歌添加了一個 wav 標頭。 然后,您可以對生成的 base64 緩沖區進行編碼並將其發送到 twilio。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM