I’ve built a streamlit app for classification of music genre. It’s working good on wav format audio so how to make prediction using MP3 files. Also how to save the uploaded audio file using streamlit for further use.
Hi @harish_natarajan
To convert mp3 to wav use the following code,
from pydub import AudioSegment
sound = AudioSegment.from_mp3("/path/to/file.mp3")
sound.export("/output/path/file.wav", format="wav")
Hope this helps.
Thanks @sree369nidhi it worked I saved the audio file in wav format gave the path to that model and then deleted the file using os library. Thanks for your help. I’ll share the link of my deployed app soon.
Regards
Harish
Hi everyone! I’m having the same issue, but I’m having trouble saving the uploaded file from streamlit so I can pass it to AudioSegment. It looks like AudioSegment/ ffmpeg cannot interpret the UploadedFile object, so variations of this code don’t seem to work. It’s my first time working with audio and with the file uploader from streamlit, I am also having trouble saving the uploaded file from streamlit so I can get it’s path. Could you guys give me some tips on how to do that?
uploaded_file = st.file_uploader(“Upload File”)
test = AudioSegment.from_ogg(uploaded_file)
Best regards
Hey @JLiporace
Can you provide link to your GitHub repo so that it would be easier to resolve your query?
Thanks for the reply. Actually I have just started this specific application and as this uploading step was the very first I was just doing some concept proofs locally. I can create a repo and link here soon, but the test code I was using was just the following snippet for now:
import streamlit as st
from pydub import AudioSegment
uploaded_file = st.file_uploader(“Upload File”)
if uploaded_file is not None:
test = AudioSegment.from_ogg(uploaded_file)
I also tried saving the uploaded_file locally so I could them pass the path to AudioSegment, but I’m getting this error:
import streamlit as st
from pydub import AudioSegment
uploaded_file = st.file_uploader("Insert File")
with open('myfile.wav', mode='bx') as f:
f.write(uploaded_file)
I thought UploadedFile was already a bytes-like object, so I’m having some trouble in that sense.
@Hey JLiporace
You could try to use
file_var = AudioSegment.from_ogg(uploaded_file)
file_var.export('filename.wav', format='wav')
Instead of using context manager (with statement)
Also there is a type parameter for file_uploader so you could specify the extension such as ‘ogg’, ‘mp3’ inside a list
Happy streamliting!
@sree369nidhi @harish_natarajan
I did see your app. Great work!
I am uploading mp3 files on my app
st.subheader("Choose a mp3 file that you extracted from the work site")
uploaded_file = st.file_uploader("Select file from your directory")
if uploaded_file is not None:
audio_bytes = uploaded_file.read()
st.audio(audio_bytes, format='audio/mp3')
I want to convert this mp3 to wav which I can using pydub but how do I find the name of the mp3 or the path from the ‘uploaded_file’ object?
I think there you can use uploaded_file.name to get name of the uploaded file. I guess it’s there since July 2020 update of streamlit. You can try this out and let me know if it works
Happy streamliting
@harish_natarajan Thanks! That works!
My other problem is when I would be deploying my app on heroku or EC2, I would need to create the .wav file from .mp3 on the file and keep the .wav file somewhere till I read in librosa.
Is there a way that can be accomplished?
e.g. in your app as well, you are reading the mp3 file and then creating a spectrogram(maybe through librosa), from where did you read this wav file?
Right now the code looks like:
datapath = ‘/Users/prashantmudgal/Documents/Sound_app/data/’
def identify():
st.set_option(‘deprecation.showfileUploaderEncoding’, False)
st.subheader(“Choose a mp3 file that you extracted from the work site”)
uploaded_file = st.file_uploader(“Select”)
if uploaded_file is not None:
audio_bytes = uploaded_file.read()
st.audio(audio_bytes, format=‘audio/mp3’)
sound = AudioSegment.from_mp3(datapath+uploaded_file.name)
sound.export(datapath+uploaded_file.name[:-4]+’.wav’, format=“wav”)
wav_file = datapath+uploaded_file.name[:-4]+’.wav’
y, sr = librosa.load(wav_file)
When the app would be deployed then the datapath would change.
I’m glad that worked for you. For my application I stored the file in the same directory where my app resides. So even when I deployed the app it would work.
Regards
Harish
I am trying to download uploaded tif files, but it keeps giving saying that it can’t accept the UploadedFile type. Does anyone know what might be the problem?
@Sarang_Goel Are you working with Geospatial data? TIFF files are generally huge.
oh i had this problem a very long time ago and for some reason i did something and it worked, so I dont really have this problem anymore.
example of upload and save wav/mp3 file
import pydub
from pathlib import Path
def upload_and_save_wavfiles(save_dir: str) -> List[Path]:
""" limited 200MB, you could increase by `streamlit run foo.py --server.maxUploadSize=1024` """
uploaded_files = st.file_uploader("upload", type=['wav', 'mp3'] accept_multiple_files=True)
save_paths = []
for uploaded_file in uploaded_files:
if uploaded_file is not None:
if uploaded_file.name.endswith('wav'):
audio = pydub.AudioSegment.from_wav(uploaded_file)
file_type = 'wav'
elif uploaded_file.name.endswith('mp3'):
audio = pydub.AudioSegment.from_mp3(uploaded_file)
file_type = 'mp3'
save_path = Path(save_dir) / uploaded_file.name
save_paths.append(save_path)
audio.export(save_path, format=file_type)
return save_paths
def display_wavfile(wavpath):
audio_bytes = open(wavpath, 'rb').read()
file_type = Path(wavpath).suffix
st.audio(audio_bytes, format=f'audio/{file_type}', start_time=0)
files = upload_and_save_wavfiles('temp')
for wavpath in files:
display_wavfile(wavpath)
hey harish can you tell me how did u take a wav file as a input and convert it to a tensor?
simpler one
def upload_and_save_wavfiles(save_dir: Path) -> List[Path]:
""" limited 200MB, you could increase by `streamlit run foo.py --server.maxUploadSize=1024` """
uploaded_files = st.file_uploader("upload", type=['wav', 'mp3'], accept_multiple_files=True)
save_paths = []
for uploaded_file in uploaded_files:
with open(save_dir / uploaded_file.name, 'wb') as f:
f.write(uploaded_file.getbuffer())
save_paths.append(save_dir / uploaded_file.name)
return save_paths