Exemplo n.º 1
0
def test_resolution_flag(tmp_path, manim_cfg_file, simple_scenes_path):
    scene_name = "NoAnimations"
    # test different separators
    resolutions = [
        (720, 480, ";"),
        (1280, 720, ","),
        (1920, 1080, "-"),
        (2560, 1440, ";"),
        # (3840, 2160, ","),
        # (640, 480, "-"),
        # (800, 600, ";"),
    ]

    for (width, height, separator) in resolutions:
        command = [
            sys.executable,
            "-m",
            "manim",
            "--media_dir",
            str(tmp_path),
            "--resolution",
            f"{width}{separator}{height}",
            str(simple_scenes_path),
            scene_name,
        ]

        _, err, exit_code = capture(command)
        assert exit_code == 0, err

        path = (tmp_path / "videos" / "simple_scenes" / f"{height}p60" /
                f"{scene_name}.mp4")
        meta = get_video_metadata(path)
        assert (width, height) == (meta["width"], meta["height"])
Exemplo n.º 2
0
def check_video_data(path_control_data, path_video_gen):
    """Compare control data with generated output.
    Used abbreviations:
        exp  -> expected
        gen  -> generated
        sec  -> section
        meta -> metadata
    """
    # movie file specification
    path_sec_gen = os.path.join(
        pathlib.Path(path_video_gen).parent.absolute(),
        "sections",
    )
    control_data = load_control_data(path_control_data)
    movie_meta_gen = get_video_metadata(path_video_gen)
    movie_meta_exp = control_data["movie_metadata"]

    assert_shallow_dict_compare(movie_meta_gen, movie_meta_exp,
                                "Movie file metadata mismatch:")

    # sections directory layout
    sec_dir_layout_gen = set(get_section_dir_layout(path_sec_gen))
    sec_dir_layout_exp = set(control_data["section_dir_layout"])

    unexp_gen = sec_dir_layout_gen - sec_dir_layout_exp
    ungen_exp = sec_dir_layout_exp - sec_dir_layout_gen
    if len(unexp_gen) or len(ungen_exp):
        dif = [f"'{dif}' got unexpectedly generated" for dif in unexp_gen
               ] + [f"'{dif}' didn't get generated" for dif in ungen_exp]
        mismatch = "\n".join(dif)
        raise AssertionError(f"Sections don't match:\n{mismatch}")

    # sections index file
    scene_name = "".join(os.path.basename(path_video_gen).split(".")[:-1])
    path_sec_index_gen = os.path.join(path_sec_gen, f"{scene_name}.json")
    sec_index_gen = get_section_index(path_sec_index_gen)
    sec_index_exp = control_data["section_index"]

    if len(sec_index_gen) != len(sec_index_exp):
        raise AssertionError(
            f"expected {len(sec_index_exp)} sections ({', '.join([el['name'] for el in sec_index_exp])}), but {len(sec_index_gen)} ({', '.join([el['name'] for el in sec_index_gen])}) got generated (in '{path_sec_index_gen}')"
        )
    # check individual sections
    for sec_gen, sec_exp in zip(sec_index_gen, sec_index_exp):
        assert_shallow_dict_compare(
            sec_gen,
            sec_exp,
            # using json to pretty print dicts
            f"Section {json.dumps(sec_gen, indent=4)} (in '{path_sec_index_gen}') doesn't match expected Section (in '{json.dumps(sec_exp, indent=4)}'):",
        )
Exemplo n.º 3
0
def save_control_data_from_video(path_to_video: str, name: str) -> None:
    """Helper used to set up a new test that will compare videos.

    This will create a new ``.json`` file in ``control_data/videos_data`` that contains:
    - the name of the video,
    - the metadata of the video, like fps and resolution and
    - the paths of all files in the sections subdirectory (like section videos).

    Refer to the documentation for more information.

    Parameters
    ----------
    path_to_video : :class:`str`
        Path to the video to extract information from.
    name : :class:`str`
        Name of the test. The .json file will be named with it.

    See Also
    --------
    tests/utils/video_tester.py : read control data and compare with output of test
    """
    path_to_sections = os.path.join(
        pathlib.Path(path_to_video).parent.absolute(), "sections")
    tests_directory = os.path.dirname(
        os.path.dirname(os.path.abspath(__file__)))
    path_control_data = os.path.join(tests_directory, "control_data",
                                     "videos_data")
    # this is the name of the section used in the test, not the name of the test itself, it can be found as a parameter of this function
    scene_name = "".join(os.path.basename(path_to_video).split(".")[:-1])

    movie_metadata = get_video_metadata(path_to_video)
    section_dir_layout = get_section_dir_layout(path_to_sections)
    section_index = get_section_index(
        os.path.join(path_to_sections, f"{scene_name}.json"))
    data = {
        "name": name,
        "movie_metadata": movie_metadata,
        "section_dir_layout": section_dir_layout,
        "section_index": section_index,
    }
    path_saved = os.path.join(path_control_data, f"{name}.json")
    with open(path_saved, "w") as f:
        json.dump(data, f, indent=4)
    logger.info(f"Data for {name} saved in {path_saved}")
Exemplo n.º 4
0
    def get_dict(self, sections_dir: str) -> Dict[str, Any]:
        """Get dictionary representation with metadata of output video.

        The output from this function is used from every section to build the sections index file.
        The output video must have been created in the ``sections_dir`` before executing this method.
        This is the main part of the Segmented Video API.
        """
        if self.video is None:
            raise ValueError(
                f"Section '{self.name}' cannot be exported as dict, it does not have a video path assigned to it"
            )

        video_metadata = get_video_metadata(os.path.join(sections_dir, self.video))
        return dict(
            {
                "name": self.name,
                "type": self.type,
                "video": self.video,
            },
            **video_metadata,
        )