|
8 | 8 | import shutil
|
9 | 9 | from pathlib import Path
|
10 | 10 | from queue import Queue
|
| 11 | +from tempfile import NamedTemporaryFile |
11 | 12 | from threading import Thread
|
12 | 13 | from typing import TYPE_CHECKING, Any
|
13 | 14 |
|
@@ -330,7 +331,32 @@ def add_sound(
|
330 | 331 |
|
331 | 332 | """
|
332 | 333 | file_path = get_full_sound_file_path(sound_file)
|
333 |
| - new_segment = AudioSegment.from_file(file_path) |
| 334 | + # we assume files with .wav / .raw suffix are actually |
| 335 | + # .wav and .raw files, respectively. |
| 336 | + if file_path.suffix not in (".wav", ".raw"): |
| 337 | + # we need to pass delete=False to work on Windows |
| 338 | + # TODO: figure out a way to cache the wav file generated (benchmark needed) |
| 339 | + wav_file_path = NamedTemporaryFile(suffix=".wav", delete=False) |
| 340 | + with ( |
| 341 | + av.open(file_path) as input_container, |
| 342 | + av.open(wav_file_path, "w", format="wav") as output_container, |
| 343 | + ): |
| 344 | + for audio_stream in input_container.streams.audio: |
| 345 | + output_stream = output_container.add_stream("pcm_s16le") |
| 346 | + for frame in input_container.decode(audio_stream): |
| 347 | + for packet in output_stream.encode(frame): |
| 348 | + output_container.mux(packet) |
| 349 | + |
| 350 | + for packet in output_stream.encode(): |
| 351 | + output_container.mux(packet) |
| 352 | + |
| 353 | + new_segment = AudioSegment.from_file(wav_file_path.name) |
| 354 | + logger.info(f"Automatically converted {file_path} to .wav") |
| 355 | + wav_file_path.close() |
| 356 | + Path(wav_file_path.name).unlink() |
| 357 | + else: |
| 358 | + new_segment = AudioSegment.from_file(file_path) |
| 359 | + |
334 | 360 | if gain:
|
335 | 361 | new_segment = new_segment.apply_gain(gain)
|
336 | 362 | self.add_audio_segment(new_segment, time, **kwargs)
|
|
0 commit comments