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")
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, ))
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, ))
def get_output_dir(): return guarantee_existence(get_directories()["output"])
def get_downloads_dir(): return guarantee_existence(os.path.join(get_temp_dir(), "manim_downloads"))
def get_mobject_data_dir(): return guarantee_existence(os.path.join(get_temp_dir(), "mobject_data"))
def get_text_dir(): return guarantee_existence(os.path.join(get_temp_dir(), "media", "Text"))
def get_saved_mobject_directory(self) -> str: return guarantee_existence( os.path.join( self.saved_mobject_directory, str(self.scene), ))
def get_tex_dir(): return guarantee_existence(os.path.join(get_temp_dir(), "Tex"))
def get_saved_mobject_directory(self) -> str: return guarantee_existence(self.saved_mobject_directory)
def get_text_dir() -> str: return guarantee_existence(os.path.join(get_temp_dir(), "Text"))
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)