前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【解决】librosa.load MP3返回空 或 报错Input signal length=0 is too small to resample from

【解决】librosa.load MP3返回空 或 报错Input signal length=0 is too small to resample from

作者头像
小锋学长生活大爆炸
发布2023-03-01 14:03:55
7390
发布2023-03-01 14:03:55
举报

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn]

目录

问题复现

问题分析

解决方法

方案一

方案二

方案三

方案四

附录

画图部分的代码

封装音频读取的代码

问题复现

        这个问题隐藏的比较深,明明读取是对的,但就是报错: 

或者我被迫改成48K,虽然读取的时长是对的,但返回为空数组

问题分析

        用pydub.utils.mediainfo()去分析,可以发现,它对音频start_time=0的音频都会报这个错,而start_time != 0的就可以正确加载。

代码语言:javascript
复制
# pip install pydub

import pydub

mp3_file_path = "sample-000001.mp3"
print(pydub.utils.mediainfo(mp3_file_path))

解决方法

方案一

这里提出了一个临时的、最简单粗暴解决方法:

        load时候指定一下他的持续时间duration即可,但注意需要比真正的时长短一点且为整数

代码语言:javascript
复制
import math

duration=math.floor(librosa.get_duration(filename=mp3_file_path))
y, sr = librosa.load(mp3_file_path, sr=48000, duration=duration)

        缺点也很明显,后面的数据没有了:

        方法太蠢了,不建议使用

方案二

        我发现他读取wav时候不会出现这个问题,因此我们可以先转为wav格式,然后在load。

代码语言:javascript
复制
sound = pydub.AudioSegment.from_mp3("sample-000001.mp3")
sound.export("sample-000001.wav", format="wav")

y, sr = librosa.load("sample-000001.wav", sr=44000)

        这样就完整了:

        推荐。

方案三

        既然方案二中可以通过pydub正确读取mp3来导出wav,那我能不能直接通过pydub读取后转为librosa格式呢?一顿好找后:

代码语言:javascript
复制
import librosa
import numpy as np
import os

sr = 44000
sound = pydub.AudioSegment.from_file(mp3_file_path).set_frame_rate(sr)
channel_sounds = sound.split_to_mono()
samples = [s.get_array_of_samples() for s in channel_sounds]
y= np.array(samples).T.astype(np.float32)
y/= np.iinfo(samples[0].typecode).max
y = y.reshape(-1)

效果也是可以的:

        推荐推荐。 

方案四

        一个想法是,既然方案一中的start_time=0会影响读取,那如果我直接把mp3文件的metadata中的start_time改成N/A或者0.0001,会不会也有用呢?不过暂时没有多找方法,因此这里没有尝试。


附录

画图部分的代码

代码语言:javascript
复制
# Plot the signal stored in 'y'
from matplotlib import pyplot as plt
import librosa.display

plt.figure(figsize=(12, 3))
plt.title("Audio signal as waveform")
librosa.display.waveshow(y, sr=sr)

封装音频读取的代码

代码语言:javascript
复制
def audio_load1(file_path, sr):
    '''直接使用pydub读取mp3,用librosa读取wav'''
    if file_path.endswith('.mp3'):
        sound = pydub.AudioSegment.from_file(file_path).set_frame_rate(sr)
        channel_sounds = sound.split_to_mono()
        samples = [s.get_array_of_samples() for s in channel_sounds]
        y = np.array(samples).T.astype(np.float32)
        y /= np.iinfo(samples[0].typecode).max
        y = y.reshape(-1)
    else:
        y, sr = librosa.load(file_path, sr=sr)
    return y, sr


def audio_load2(file_path, sr):
    '''先尝试用pydub读取,失败则用librosa读取'''
    try:
        y, sr = librosa.load(file_path, sr=sr)
        _ = y[0]
    except Exception as e:
        print('使用librosa读取失败,将转用pydub')
        sound = pydub.AudioSegment.from_file(file_path).set_frame_rate(sr)
        channel_sounds = sound.split_to_mono()
        samples = [s.get_array_of_samples() for s in channel_sounds]
        y = np.array(samples).T.astype(np.float32)
        y /= np.iinfo(samples[0].typecode).max
        y = y.reshape(-1)
    return y, sr

欢迎补充!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题复现
  • 问题分析
  • 解决方法
    • 方案一
      • 方案二
        • 方案三
          • 方案四
          • 附录
            • 画图部分的代码
              • 封装音频读取的代码
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档