Sometimes we get data that resembles an opened file and we can't handle it easily. An example of this is if you download a wav audio file directly into memory, so that the binary contents of the file are already stored in an object.
One way to handle it is to write the binary contents to an actual file on disk. However, this is inefficient.
Another way is to create a file-like object that can be dealt with as normal files.
In this example, we have the binary contents of a wav audio file and we would like to decode it to extract the audio array and sampling rate. We want to do this all in-memory without writing to disk.
We will be doing this using python.
We will need two dependencies:
iolibraries for creating file-like objectssoundfilefor decoding the data into audio array
import soundfile as sf
import ioLet's say we have a python object named binary_contents that contain the binary contents of the audio file.
One way to obtain this object is:
with open('avc.wav', 'rb') as audio_file:
bytes_data = audio_file.read()
print(type(bytes_data))
# <class 'bytes'>
print(bytes_data)
# b'RIFF2m\x0b\x00WAVEfmt \x12\x00\x00\x00\x03\x0 ...We see that binary_contens is of type <class 'bytes'>
To decode these contents, we can do:
file_like_object = io.BytesIO(bytes_data)
audio_array, sr = sf.read(file_like_object)
print(sr)
# 16000
print(audio_array)
# [0.0, 0.0, 0.0, 5.960464477539063e-08, -5.96, ...]We've now obtained the audio array as well as the sampling rate.
We can do this efficiently using the following function:
def read_audio_bytes(bytes_data):
file_like_object = io.BytesIO(bytes_data)
audio_array, sr = sf.read(file_like_object)
return {'array': audio_array, 'sampling_rate': sr}
# We can use this in pandas or polars dataframe:
res = read_audio_bytes(bytes_data)
df['audio_array'] = res['array']
df['audio_sampling_rate'] = res['sampling_rate']