예제 #1
0
    def init_output_directories(self) -> None:
        out_dir = self.output_directory or ""
        if self.mirror_module_path:
            module_dir = self.get_default_module_directory()
            out_dir = os.path.join(out_dir, module_dir)

        scene_name = self.file_name or self.get_default_scene_name()
        if self.save_last_frame:
            image_dir = guarantee_existence(os.path.join(out_dir, "images"))
            image_file = add_extension_if_not_present(scene_name, ".png")
            self.image_file_path = os.path.join(image_dir, image_file)
        if self.write_to_movie:
            movie_dir = guarantee_existence(os.path.join(out_dir, "videos"))
            movie_file = add_extension_if_not_present(
                scene_name, self.movie_file_extension)
            self.movie_file_path = os.path.join(movie_dir, movie_file)
            if self.break_into_partial_movies:
                self.partial_movie_directory = guarantee_existence(
                    os.path.join(
                        movie_dir,
                        "partial_movie_files",
                        scene_name,
                    ))
        # A place to save mobjects
        self.saved_mobject_directory = os.path.join(out_dir, "mobjects")
예제 #2
0
 def init_output_directories(self):
     """
     This method initialises the directories to which video
     files will be written to and read from (within MEDIA_DIR).
     If they don't already exist, they will be created.
     """
     module_directory = self.output_directory or self.get_default_module_directory()
     scene_name = self.file_name or self.get_default_scene_name()
     if self.save_last_frame:
         if consts.VIDEO_DIR != "":
             image_dir = guarantee_existence(os.path.join(
                 consts.VIDEO_DIR,
                 module_directory,
                 "images",
             ))
         else:
             image_dir = guarantee_existence(os.path.join(
                 consts.VIDEO_OUTPUT_DIR,
                 "images",
             ))
         self.image_file_path = os.path.join(
             image_dir,
             add_extension_if_not_present(scene_name, ".png")
         )
     if self.write_to_movie:
         if consts.VIDEO_DIR != "":
             movie_dir = guarantee_existence(os.path.join(
                 consts.VIDEO_DIR,
                 module_directory,
                 self.get_resolution_directory(),
             ))
         else:
             movie_dir = guarantee_existence(consts.VIDEO_OUTPUT_DIR)
         self.movie_file_path = os.path.join(
             movie_dir,
             add_extension_if_not_present(
                 scene_name, self.movie_file_extension
             )
         )
         self.gif_file_path = os.path.join(
             movie_dir,
             add_extension_if_not_present(
                 scene_name, self.gif_file_extension
             )
         )
         self.partial_movie_directory = guarantee_existence(os.path.join(
             movie_dir,
             "partial_movie_files",
             scene_name,
         ))
예제 #3
0
 def init_output_directories(self):
     module_directory = self.output_directory or self.get_default_module_directory()
     scene_name = self.file_name or self.get_default_scene_name()
     if self.save_last_frame:
         if consts.VIDEO_DIR != "":
             image_dir = guarantee_existence(os.path.join(
                 consts.VIDEO_DIR,
                 module_directory,
                 "images",
             ))
         else:
             image_dir = guarantee_existence(os.path.join(
                 consts.VIDEO_OUTPUT_DIR,
                 "images",
             ))
         self.image_file_path = os.path.join(
             image_dir,
             add_extension_if_not_present(scene_name, ".png")
         )
     if self.write_to_movie:
         if consts.VIDEO_DIR != "":
             movie_dir = guarantee_existence(os.path.join(
                 consts.VIDEO_DIR,
                 module_directory,
                 self.get_resolution_directory(),
             ))
         else:
             movie_dir = guarantee_existence(consts.VIDEO_OUTPUT_DIR)
         self.movie_file_path = os.path.join(
             movie_dir,
             add_extension_if_not_present(
                 scene_name, self.movie_file_extension
             )
         )
         self.gif_file_path = os.path.join(
             movie_dir,
             add_extension_if_not_present(
                 scene_name, self.gif_file_extension
             )
         )
         self.partial_movie_directory = guarantee_existence(os.path.join(
             movie_dir,
             "partial_movie_files",
             scene_name,
         ))
예제 #4
0
def get_output_dir():
    return guarantee_existence(get_directories()["output"])
예제 #5
0
def get_downloads_dir():
    return guarantee_existence(os.path.join(get_temp_dir(), "manim_downloads"))
예제 #6
0
def get_mobject_data_dir():
    return guarantee_existence(os.path.join(get_temp_dir(), "mobject_data"))
예제 #7
0
def get_text_dir():
    return guarantee_existence(os.path.join(get_temp_dir(), "media", "Text"))
예제 #8
0
 def get_saved_mobject_directory(self) -> str:
     return guarantee_existence(
         os.path.join(
             self.saved_mobject_directory,
             str(self.scene),
         ))
예제 #9
0
def get_tex_dir():
    return guarantee_existence(os.path.join(get_temp_dir(), "Tex"))
예제 #10
0
 def get_saved_mobject_directory(self) -> str:
     return guarantee_existence(self.saved_mobject_directory)
예제 #11
0
def get_text_dir() -> str:
    return guarantee_existence(os.path.join(get_temp_dir(), "Text"))
예제 #12
0
    def combine_movie_files(self):
        # Manim renders the scene as many smaller movie files
        # which are then concatenated to a larger one.  The reason
        # for this is that sometimes video-editing is made easier when
        # one works with the broken up scene, which effectively has
        # cuts at all the places you might want.  But for viewing
        # the scene as a whole, one of course wants to see it as a
        # single piece.
        kwargs = {
            "remove_non_integer_files": True,
            "extension": self.movie_file_extension,
        }
        if self.scene.start_at_animation_number is not None:
            kwargs["min_index"] = self.scene.start_at_animation_number
        if self.scene.end_at_animation_number is not None:
            kwargs["max_index"] = self.scene.end_at_animation_number
        else:
            kwargs["remove_indices_greater_than"] = self.scene.num_plays - 1
        partial_movie_files = get_sorted_integer_files(
            self.partial_movie_directory, **kwargs)
        if len(partial_movie_files) == 0:
            print("No animations in this scene")
            return

        # Write a file partial_file_list.txt containing all
        # partial movie files
        file_list = os.path.join(self.partial_movie_directory,
                                 "partial_movie_file_list.txt")
        with open(file_list, 'w') as fp:
            for pf_path in partial_movie_files:
                if os.name == 'nt':
                    pf_path = pf_path.replace('\\', '/')
                fp.write("file \'{}\'\n".format(pf_path))

        movie_file_path = self.get_movie_file_path()
        module_directory = self.output_directory or self.get_default_module_directory(
        )
        commands = [
            FFMPEG_BIN,
            '-y',  # overwrite output file if it exists
            '-f',
            'concat',
            '-safe',
            '0',
            '-i',
            file_list
        ]
        if self.save_pngs:
            file_name = self.file_name or self.get_default_scene_name()
            if consts.VIDEO_DIR != "":
                image_dir = guarantee_existence(
                    os.path.join(
                        consts.VIDEO_DIR,
                        module_directory,
                        self.get_resolution_directory(),
                        f"{file_name}_pngs",
                    ))
            else:
                image_dir = guarantee_existence(
                    os.path.join(
                        consts.VIDEO_OUTPUT_DIR,
                        self.get_resolution_directory(),
                        f"{file_name}_pngs",
                    ))
            image_file_path = os.path.join(
                image_dir,
                add_extension_if_not_present(f'{file_name}%00001d', ".png"))
            commands += [
                image_file_path,
                '-hide_banner',
            ]
            self.image_dir_pngs = image_dir

        commands += ['-loglevel', 'error']

        if not self.save_as_gif:
            commands += ['-c', 'copy', movie_file_path]
        if self.save_as_gif:
            movie_file_path = self.gif_file_path
            commands += [
                movie_file_path,
            ]
        if not self.includes_sound:
            commands.insert(-1, '-an')

        combine_process = subprocess.Popen(commands)
        combine_process.wait()

        if self.includes_sound:
            sound_file_path = movie_file_path.replace(
                self.movie_file_extension, ".wav")
            # Makes sure sound file length will match video file
            self.add_audio_segment(AudioSegment.silent(0))
            self.audio_segment.export(
                sound_file_path,
                bitrate='312k',
            )
            temp_file_path = movie_file_path.replace(".", "_temp.")
            commands = [
                "ffmpeg",
                "-i",
                movie_file_path,
                "-i",
                sound_file_path,
                '-y',  # overwrite output file if it exists
                "-c:v",
                "copy",
                "-c:a",
                "aac",
                "-b:a",
                "320k",
                # select video stream from first file
                "-map",
                "0:v:0",
                # select audio stream from second file
                "-map",
                "1:a:0",
                '-loglevel',
                'error',
                # "-shortest",
                temp_file_path,
            ]
            subprocess.call(commands)
            shutil.move(temp_file_path, movie_file_path)
            subprocess.call(["rm", sound_file_path])

        self.print_file_ready_message(movie_file_path)