如何使用pydub检测空的立体声通道

时间:2015-04-12 04:58:19

标签: python pydub

我正在使用的一些音频文件有一个烦人的属性:它们有两个通道,但一个是空的。这比单声道更糟糕,因为操作系统很乐意在左右立体声扬声器上播放单声道音轨,但这些文件仅播放(例如)左扬声器。

我想用PyDub检测到这一点,但是我有点陷入困境。如果我知道文件不好,我可以这样做:

import pydub
bad_sample = pydub.AudioSegment.from_mp3('bad_file.mp3')
mono_sample = bad_sample.set_channels(1)
mono_sample.export('mono_file.mp3')

到目前为止一切顺利。但我无法弄清楚如何自动检测是否坏。

隔离每个通道并检查是否为空是足够的。我的尝试是做一些事情:

import numpy as np
assert bad_sample.sample_width == 2  # hence int16
a = np.fromstring(bad_sample._data,
                  dtype=np.int16)
a = a.reshape((bad_sample.channels, bad_sample.frame_count()))
left = a[0, :]
right = a[1, :]

但对于这个糟糕的文件似乎都不是空的,这对我来说,我没有正确地阅读这种格式。

示例包括:http://www.newsonair.com/writereaddata/bulletins/Aurangabad-Marathi-Regional-Bulletins-38645.mp3

有人能建议一种简单的方法来分割频道并检测空频道吗?

1 个答案:

答案 0 :(得分:2)

好吧,事实证明我的步幅顺序错了。这有效:

def is_bad_mono(segment):
    if segment.channels != 2:
        return False
    a = np.fromstring(segment._data, dtype=np.uint16)
    a = a.reshape(( int(segment.frame_count()), 2 ))
    threshold = 0.3
    return ((a[:, 0] == 0).mean() > threshold or (a[:, 1] == 0).mean() > threshold)

基本上,如果有任何真实的声音传播的话,在正确的步幅下,坏的单声道情况只会比它们应该更加频繁。

希望这有助于其他人:)