Unable to load m4a files with librosa.load() in streamlit run

Instead of

try with

import streamlit as st
import librosa as rosa
import pandas as pd
import numpy as np
from tempfile import NamedTemporaryFile

st.title("異音チェッカー シミュレーション")

uploaded_files = st.file_uploader(
    "OKデータのオーディオファイルをアップロードしてください", accept_multiple_files=True
)

for uploaded_file in uploaded_files:
    st.write("filename:", uploaded_file.name)
    with NamedTemporaryFile() as f:
        f.write(uploaded_file.read())
        wave, sr = rosa.load(f.name, sr=None)
    
    times = pd.Index(np.array(range(len(wave))) / sr, name="time(sec)")
    ts = pd.Series(wave, index=times, name=str(uploaded_file))
    st.write(ts)


Details:
that looks like a problem from the librosa package on how it handles paths and file-like objects. You can replicate the exception you see on streamlit when you try passing a BytesIO object to librosa.load(), which it’s supposedly supported but leads to different behavior.

import librosa as rosa
import pandas as pd
import numpy as np
import pathlib

print("audio check")

cwd = pathlib.Path.cwd()
uploaded_files = sorted(cwd.glob("*.m4a"))

for uploaded_file in uploaded_files:
    with open(uploaded_file, 'rb') as f:
        wave, sr = rosa.load(f, sr=None)
        times = pd.Index(np.array(range(len(wave))) / sr, name="time(sec)")
        ts = pd.Series(wave, index=times, name=str(uploaded_file))
        print(ts)

The proposed fix is to write the BytesIO object obtained from st.file_uploader into a temporal file, so librosa.load() is tricked into treating that as a path.