使用 librosa 下载并打开文件而不写入文件系统

Download and open file with librosa without writing to filesystem

我知道 Heroku dynos 是短暂的,不能在请求之间存储文件。我有一个 Flask 应用程序,它应该从 Spotify 获取 MP3,将其传递给 LibROSA 进行分析,然后 return 可视化。

我有一个脚本可以在本地使用 urllib.urlopen 下载文件,将其保存到文件中,然后使用 librosa.load 加载该文件。但是,我似乎无法从 Heroku 上的文件系统加载文件。当我不控制文件系统时,如何加载下载的文件?

song_url = "https://p.scdn.co/mp3-preview/8e29d103eba74b5cef8600722fff3c491e37fc9a.mp3"
sample_30s = urlopen(song_url)
mp3_path = os.path.join(os.path.dirname(__file__), 'static/data/temp.mp3')

output = open(mp3_path, 'wb')
output.write(sample_30s.read())

y, sr = librosa.load(mp3_filepath)

librosa.load can take a file-like object, as an alternative to a file path. The object returns by urlopen 类似于文件。可以直接传给librosa。

from urllib.request import urlopen
import librosa

with urlopen(song_url) as response:
    y, sr = librosa.load(response)

但是,librosa 只支持从文件系统加载 MP3 文件。您可以使用 soundfile.available_formats(). Either obtain the file in a different format, or use a library such as pydub 查看类文件对象支持哪些格式以将其转换为 WAV。

import io
from urllib.request import urlopen
import librosa
import pydub

wav = io.BytesIO()

with urlopen(mp3_url) as r:
    r.seek = lambda *args: None  # allow pydub to call seek(0)
    pydub.AudioSegment.from_file(r).export(wav, "wav")

wav.seek(0)
y, sr = librosa.load(wav)