Repository: ManimCommunity/manim
File: manim/scene/scene_file_writer.py (Python)

Code before:
        Parameters
        ----------
        sound_file
            The path to the sound file.

        time
            The timestamp at which the audio should be added.

        gain
            The gain of the given audio segment.

        **kwargs
            This method uses add_audio_segment, so any keyword arguments
            used there can be referenced here.

        """
        file_path = get_full_sound_file_path(sound_file)
        # we assume files with .wav / .raw suffix are actually
        # .wav and .raw files, respectively.
        if file_path.suffix not in (".wav", ".raw"):
            wav_file_path = NamedTemporaryFile(suffix=".wav")
            with (
                av.open(file_path) as input_container,
                av.open(wav_file_path, "w", format="wav") as output_container,
            ):
                for audio_stream in input_container.streams.audio:
                    output_stream = output_container.add_stream("pcm_s16le")
                    for frame in input_container.decode(audio_stream):
                        for packet in output_stream.encode(frame):
                            output_container.mux(packet)

                    for packet in output_stream.encode():
                        output_container.mux(packet)

            new_segment = AudioSegment.from_file(wav_file_path.name)
            logger.info(f"Automatically converted {file_path} to .wav")
            wav_file_path.close()

        else:
            new_segment = AudioSegment.from_file(file_path)

        if gain:
            new_segment = new_segment.apply_gain(gain)
        self.add_audio_segment(new_segment, time, **kwargs)

    # Writers
    def begin_animation(self, allow_write: bool = False, file_path=None):
        """
        Used internally by manim to stream the animation to FFMPEG for
        displaying or writing to a file.


Review comment (suggestion):
It seems on Windows, `NamedTemporaryFile` cannot be opened twice (it's opened once on creation). One of the things [the docs](https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile) suggest is setting `delete=False`, or setting `delete_on_close=False` and unlinking manually.
Unfortunately, I don't have a Windows machine to test this on, so I can't give a better suggestion :)

Code after:
        Parameters
        ----------
        sound_file
            The path to the sound file.

        time
            The timestamp at which the audio should be added.

        gain
            The gain of the given audio segment.

        **kwargs
            This method uses add_audio_segment, so any keyword arguments
            used there can be referenced here.

        """
        file_path = get_full_sound_file_path(sound_file)
        # we assume files with .wav / .raw suffix are actually
        # .wav and .raw files, respectively.
        if file_path.suffix not in (".wav", ".raw"):
            # we need to pass delete=False to work on Windows
            # TODO: figure out a way to cache the wav file generated (benchmark needed)
            wav_file_path = NamedTemporaryFile(suffix=".wav", delete=False)
            with (
                av.open(file_path) as input_container,
                av.open(wav_file_path, "w", format="wav") as output_container,
            ):
                for audio_stream in input_container.streams.audio:
                    output_stream = output_container.add_stream("pcm_s16le")
                    for frame in input_container.decode(audio_stream):
                        for packet in output_stream.encode(frame):
                            output_container.mux(packet)

                    for packet in output_stream.encode():
                        output_container.mux(packet)

            new_segment = AudioSegment.from_file(wav_file_path.name)
            logger.info(f"Automatically converted {file_path} to .wav")
            wav_file_path.close()
            Path(wav_file_path.name).unlink()
        else:
            new_segment = AudioSegment.from_file(file_path)

        if gain:
            new_segment = new_segment.apply_gain(gain)
        self.add_audio_segment(new_segment, time, **kwargs)

    # Writers
    def begin_animation(self, allow_write: bool = False, file_path=None):
        """
        Used internally by manim to stream the animation to FFMPEG for