我已经上过这堂课了:
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)
答案 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__()
之前调用。