FCPXML output declares version 1.9, rational time strings, and an asset-clip per scene.
(tmp_path: Path)
| 348 | |
| 349 | |
| 350 | def test_write_scene_list_fcpx(tmp_path: Path): |
| 351 | """FCPXML output declares version 1.9, rational time strings, and an asset-clip per scene.""" |
| 352 | scenes = _fake_scenes(_FPS_NTSC, [(48, 96), (96, 144)]) |
| 353 | output_path = tmp_path / "scenes.xml" |
| 354 | # `video_path` need not exist; only `.absolute().as_uri()` is called on it. |
| 355 | write_scene_list_fcpx( |
| 356 | output_path=output_path, |
| 357 | scene_list=scenes, |
| 358 | video_path=tmp_path / "fake_video.mp4", |
| 359 | frame_rate=_FPS_NTSC, |
| 360 | frame_size=(1280, 544), |
| 361 | ) |
| 362 | |
| 363 | root = ElementTree.parse(output_path).getroot() |
| 364 | assert root.tag == "fcpxml" |
| 365 | assert root.attrib["version"] == "1.9" |
| 366 | |
| 367 | fmt = root.find("resources/format") |
| 368 | assert fmt is not None |
| 369 | # 24000/1001 fps -> frameDuration is the reciprocal: 1001/24000s. |
| 370 | assert fmt.attrib["frameDuration"] == "1001/24000s" |
| 371 | assert fmt.attrib["width"] == "1280" |
| 372 | assert fmt.attrib["height"] == "544" |
| 373 | |
| 374 | media_rep = root.find("resources/asset/media-rep") |
| 375 | assert media_rep is not None |
| 376 | assert media_rep.attrib["src"].startswith("file://") |
| 377 | |
| 378 | clips = root.findall("library/event/project/sequence/spine/asset-clip") |
| 379 | assert len(clips) == 2 |
| 380 | for clip in clips: |
| 381 | for attr in ("offset", "start", "duration"): |
| 382 | assert clip.attrib[attr].endswith("s") |
| 383 | |
| 384 | |
| 385 | def test_write_scene_list_fcpx_video_name_defaults_to_path_stem(tmp_path: Path): |
nothing calls this directly
no test coverage detected