0

I want to convert a numpy array waveform into a wav-like object so that I can upload it to S3 without having to save the waveform to file locally. Imagine I have a numpy array waveform, y,

y, sr = librosa.load('something.wav', sr = 44100)

How can I convert this numpy array, y into a wav file-like object to upload to S3 using boto3's upload_fileobj method?

According to the boto3 docs, the file-like object must have the properties:

A file-like object to upload. At a minimum, it must implement the read method, and must return bytes.

This is how I would like to upload the file-like object:

import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')

# with open('filename', 'rb') as data:
#    bucket.upload_fileobj(data, 'mykey')
bucket.upload_fileobj(wav_object, 'something.wav')

TLDR:

I want a function that converts a numpy array into a wav-like object that implements the read method and returns bytes.

piccolo
  • 2,093
  • 3
  • 24
  • 56
  • Does this answer your question? [Writing WAV file using Python, Numpy array and WAVE module](https://stackoverflow.com/questions/40782159/writing-wav-file-using-python-numpy-array-and-wave-module) – tevemadar Jun 28 '22 at 08:45
  • Python has a built-in https://docs.python.org/3/library/wave.html module. – tevemadar Jun 28 '22 at 08:46
  • @tevemadar that link doesn't answer my question because my starting point is a numpy array - not a wave file. I want to go from np array --> wav-like object – piccolo Jun 28 '22 at 08:51
  • You'll have to scroll to the second answer, https://stackoverflow.com/a/64376061/7916438 – tevemadar Jun 28 '22 at 08:53
  • @tevemadar the second answer has `with wave.open("sound1.wav", "w") as f:` but I don't want to write to a file locally , I just want to return a file-like object. – piccolo Jun 28 '22 at 08:56
  • Based on the title, I thought the "file like object" part is clear. Anyway, if you don't want a file, just a buffer to write to, `io.BytesIO()`, and https://docs.python.org/3/library/io.html#io.BytesIO.getvalue when you're done. – tevemadar Jun 28 '22 at 09:00

1 Answers1

1

You can try like this:

import io 
from scipy.io.wavfile import write
import boto3

bytes_wav = bytes()
wav_object = io.BytesIO(bytes_wav)
write(wav_object, sr, y) # y is your numpy array


s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')

bucket.upload_fileobj(wav_object, 'something.wav')
MSS
  • 3,306
  • 1
  • 19
  • 50