from pydub import AudioSegment
from pydub.playback import play
class Granule:
def __init__(self,
audio:AudioSegment,
iterations:int=0,
start:int=0,
end:int=0,
fade_start:int=0,
fade_end:int=0,
):
self.audio:AudioSegment = audio
self.iterations:int = iterations
self.final_clip:AudioSegment = AudioSegment.empty()
self.start:int = start
self.end:int = end
self.fade_start:int = fade_start
self.fade_end:int = fade_end
self.clip = None
if self.start > 0 and self.end > 0:
self.split(self.start, self.end)
def split(self, start:int, end:int):
self.clip = self.audio[start:end]
def render(self):
final_clip = AudioSegment.empty()
for _ in range(self.iterations):
current_clip = self.clip
if self.fade_start > 0:
current_clip = current_clip.fade_in(self.fade_start)
if self.fade_end > 0:
current_clip = current_clip.fade_out(self.fade_end)
final_clip += current_clip
return final_clip
def generate(self):
for _ in range(self.iterations):
current_clip = self.clip
if self.fade_start > 0:
current_clip = current_clip.fade_in(self.fade_start)
if self.fade_end > 0:
current_clip = current_clip.fade_out(self.fade_end)
yield current_clip
class Render:
def __init__(self, granules:list[Granule]=[]):
self.granules = granules
self.final_clip = AudioSegment.empty()
def append(self, granule:Granule):
self.granules.append(granule)
def pop(self, index:int):
self.granules.pop(index)
def insert(self, index:int, granule:Granule):
self.granules.pop(index, granule)
def render(self):
self.final_clip = AudioSegment.empty()
for granule in self.granules:
for clip in granule.generate():
self.final_clip += clip
def play(self):
play(self.final_clip)
def export(self, file_path: str, format: str = "mp3", parameters: dict = None):
if len(self.final_clip) == 0:
raise BaseException("Нет аудио для экспорта. Сначала выполните render().")
try:
export_params = {"format": format}
if parameters:
export_params.update(parameters)
self.final_clip.export(file_path, **export_params)
return True
except Exception as e:
raise BaseException(f"Ошибка при экспорте файла: {e}")
def export_mp3(self, file_path: str, bitrate: str = "192k"):
return self.export(file_path, format="mp3", parameters={"bitrate": bitrate})
def export_wav(self, file_path: str):
return self.export(file_path, format="wav")
def clear(self):
self.granules.clear()
self.final_clip = AudioSegment.empty()