如何强迫上课?

时间:2016-05-08 10:34:29

标签: python pydub

我已经上过这堂课了:

class AudioSegmentCustom(AudioSegment):

    def fade_override(self, seg, fade_len=100):
        seg1, seg2 = AudioSegment._sync(self, seg)
        final = seg1[:-fade_len]
        a_fin = seg1[-fade_len:].fade(to_gain=-120, start=0, end=float('inf'))
        a_fin *= seg2[:fade_len]
        return (final + a_fin) + seg2[fade_len:]

我面临的问题是当我创建一些AudioSegmentCustom变量时,如果我"添加"它们,add操作返回其原始父类型= AudioSegment

因此以下代码不起作用:

final = AudioSegmentCustom.from_mp3(mp3_src) + AudioSegment.from_mp3(mp3_other)
final = final.fade_override(...blabla...)

因为我得到了:

'AudioSegment' object has no attribute 'fade_override'

...即使我已经开始使用AudioSegmentCustom个对象,我的结尾只有AudioSegment"只有"宾语。 是什么方式来强迫"强迫"新创建的对象的类型?

万一你需要它:

class AudioSegment(object):
    def __add__(self, arg):
        if isinstance(arg, AudioSegment):
            return self.append(arg, crossfade=0)
        else:
            return self.apply_gain(arg)

1 个答案:

答案 0 :(得分:1)

看起来问题是AudioSegment._spawn()

它无条件地返回一个简单的AudioSegment实例。由于这是一种常规方法,您可以在AudioSegmentCustom

中覆盖它
def _spawn(self, data, overrides={}):
    """
    Creates a new audio segment using the metadata from the current one
    and the data passed in. Should be used whenever an AudioSegment is
    being returned by an operation that would alters the current one,
    since AudioSegment objects are immutable.
    """
    # accept lists of data chunks
    if isinstance(data, list):
        data = b''.join(data)

    # accept file-like objects
    if hasattr(data, 'read'):
        if hasattr(data, 'seek'):
            data.seek(0)
        data = data.read()

    metadata = {
        'sample_width': self.sample_width,
        'frame_rate': self.frame_rate,
        'frame_width': self.frame_width,
        'channels': self.channels
    }
    metadata.update(overrides)
    return self.__class__(data=data, metadata=metadata)

复制和粘贴当然不是一个好习惯,但它可以完成这项工作。

但请注意,它引入了不对称性,因为AudioSegmentCustom + AudioSegment会返回AudioSegmentCustom,而AudioSegment + AudioSegmentCustom会返回AudioSegment。 通过在__radd__()中另外提供AudioSegmentCustom,可以修复 - 更多 - 。它将在AudioSegment.__add__()之前调用。