从文件、文件字节或采样点构造一个声音;对其进行编辑(每次编辑都会生成一个新的
声音);将其放入场景:add_sound 立即启动它且
不占用时间,而 play 将其作为 play 的一部分播放,
随后该 play 至少持续与声音一样长的时间。在组合中,它在其窗口
打开时启动:LaggedStart(*(AnimationGroup(FadeIn(d), click) for d in dots)) 在每个
点出现时发出咔嗒声。它不会改变屏幕上的任何内容,且 play 的 run_time 不会改变它:
声音持续其 duration。
def__init__(self,source:Source,*,rate:int|None=None)->None:ifisinstance(source,np.ndarray)!=(rateisnotNone):raiseValueError("give a rate with samples, and only with samples")ifrateisnotNoneand(notmath.isfinite(rate)orrate<=0):raiseValueError("the sample rate must be finite and positive")ifisinstance(source,str|os.PathLike)andnotPath(source).is_file():raiseFileNotFoundError(f"no sound file at {os.fspath(source)!r}")ifisinstance(source,np.ndarray):# its own: the samples as they were givensource=np.array(source,copy=True,subok=True)self.source=sourceself.rate=rateself._edit=_Edit()super().__init__(None)
defrun_time(self)->float:"""其时长:声音播放与其持续时长相同。无尽声音(`loop()`) 无法被播放:请添加它([`add_sound`][manimgx.Scene.add_sound]),然后停止它。 """ifself._edit.loop==math.inf:raiseValueError("an endless sound (loop()) never ends: add it with add_sound, and stop"" its clip, instead of playing it")returnself.duration
defspeed(self,factor:float)->Self:"""此声音以 `factor` 倍速播放,如同磁带一般:更高且更短。 结果速度必须为有限正数。 """speed=self._edit.speed*factorifnotmath.isfinite(speed)orspeed<=0:raiseValueError("the resulting speed must be finite and positive")returnself._but(speed=speed)
defadd_sound(self,sound:str|os.PathLike[str]|Sound,time_offset:float=0,gain:float|None=None,)->Clip:"""开始一个声音:现在,或距现在 `time_offset` 秒后;它不占用时间。 场景立即继续,声音在随后的内容上播放,直到其结束(或影片结束,或其 片段被停止)。由更新器调用时,它在更新器运行的时刻开始:弹跳声恰在 弹跳处响起。要等待一个声音,请改为 [`play`][manimgx.Scene.play] 它。 Args: sound: 该声音,或其文件。 time_offset: 距现在多久后开始,以秒为单位。 gain: 播放时增大的音量,以分贝表示(负值:更安静)。 Returns: 其片段:[`stop`][manimgx.audio.sound.Clip.stop] 它以提前结束。 """frommanimgx.audio.soundimportClip,Soundifnotisinstance(sound,Sound):sound=Sound(sound)ifgain:sound=sound.gain(gain)# decoded now: a file it cannot read fails here, not at the end of the render_=sound.samplesclip=Clip(sound,clock.now+clock.rational(time_offset))self.film.clips.append(clip)returnclip