13

Audio file is sent to us via API which is Base64 encoded PCM format. I need to convert it to PCM and then WAV for processing.

I was able to decode -> save to pcm -> read from pcm -> save as wav using the following code.

decoded_data = base64.b64decode(data, ' /')
with open(pcmfile, 'wb') as pcm:
    pcm.write(decoded_data)
with open(pcmfile, 'rb') as pcm:
    pcmdata = pcm.read()
with wave.open(wavfile, 'wb') as wav:
    wav.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
    wav.writeframes(pcmdata)

It'd be a lot easier if I could just decode the input string to binary and save as wav. So I did something like this in Convert string to binary in python

  decoded_data = base64.b64decode(data, ' /')
    ba = ' '.join(format(x, 'b') for x in bytearray(decoded_data))
    with wave.open(wavfile, 'wb') as wav:
        wav.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
        wav.writeframes(ba)

But I got error a bytes-like object is required, not 'str' at wav.writeframes.

Also tried base54.decodebytes() and got the same error.

What is the correct way to do this?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
ddd
  • 4,665
  • 14
  • 69
  • 125
  • @snakecharmerb I don't get error using this. But the output wav file is not right. It's supposed to be 5-second audio, but now it is 38 seconds. And the size is way too big. – ddd May 12 '18 at 13:49
  • @snakecharmerb unfortunately, still not right. The audio size is a lot smaller, but still too long. Plus when I play it, it does not sound right. – ddd May 13 '18 at 23:19
  • @ddd In your first example, what's the point of saving to and reading from a binary file? And why do you perform `ba = ' '.join(format(x, 'b') for x in bytearray(decoded_data))` in the second example? Why not use the `decoded_data` as is? Also do you have some example data? – a_guest Feb 07 '19 at 13:00

1 Answers1

10

I also faced a similar problem in a project of mine.

I was able to convert base64 string directly to wav :

import base64
encode_string = base64.b64encode(open("audio.wav", "rb").read())
wav_file = open("temp.wav", "wb")
decode_string = base64.b64decode(encode_string)
wav_file.write(decode_string)

First encode it into base64. Then create a file in wav format and write the decoded base64 string into that file.

I know this is a very late answer. Hope this helps.

BertMacklinFBI
  • 116
  • 2
  • 4