def test_good_for_track_element(self): """Tests the good_for_track_element method.""" uri = get_sample_uri("tears_of_steel.webm") asset = GES.UriClipAsset.request_sync(uri) ges_clip = asset.extract() # Add the clip to a timeline so it gets tracks. ges_timeline = create_timeline_container().timeline.ges_timeline ges_timeline.append_layer() ges_layer, = ges_timeline.get_layers() ges_layer.add_clip(ges_clip) track_elements = dict([ (track_element.get_track_type(), track_element) for track_element in ges_clip.get_children(recursive=True) ]) audio_track_element = track_elements[GES.TrackType.AUDIO] video_track_element = track_elements[GES.TrackType.VIDEO] effect_info = EffectInfo(None, AUDIO_EFFECT, None, None, None) self.assertTrue( effect_info.good_for_track_element(audio_track_element)) self.assertFalse( effect_info.good_for_track_element(video_track_element)) effect_info = EffectInfo(None, VIDEO_EFFECT, None, None, None) self.assertFalse( effect_info.good_for_track_element(audio_track_element)) self.assertTrue( effect_info.good_for_track_element(video_track_element))
def __check_simple(self, left_click_also_seeks): timeline_container = create_timeline_container() timeline = timeline_container.timeline timeline.app.settings.leftClickAlsoSeeks = left_click_also_seeks ges_layer = timeline.ges_timeline.append_layer() asset = GES.UriClipAsset.request_sync( common.get_sample_uri("1sec_simpsons_trailer.mp4")) ges_clip1 = ges_layer.add_asset(asset, 0 * Gst.SECOND, 0, 1 * Gst.SECOND, GES.TrackType.UNKNOWN) ges_clip2 = ges_layer.add_asset(asset, 1 * Gst.SECOND, 0, 1 * Gst.SECOND, GES.TrackType.UNKNOWN) event = mock.Mock() event.get_button.return_value = (True, 1) timeline._seek = mock.Mock() timeline._seek.return_value = True timeline.get_clicked_layer_and_pos = mock.Mock() with mock.patch.object(Gtk, "get_event_widget") as get_event_widget: get_event_widget.return_value = timeline # Simulate click on first and shift+click on second clip. timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 0.5 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_parent()._shiftMask = True timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 1.5 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip1, ges_clip2], [])
def test_keyframe_toggle(self): """Checks keyframes toggling at the playhead position.""" timeline_container = common.create_timeline_container() timeline_container.app.action_log = UndoableActionLog() timeline = timeline_container.timeline ges_layer = timeline.ges_timeline.append_layer() ges_clip1 = self.add_clip(ges_layer, 0, duration=Gst.SECOND) ges_clip2 = self.add_clip(ges_layer, Gst.SECOND, duration=Gst.SECOND) ges_clip3 = self.add_clip(ges_layer, 2 * Gst.SECOND, inpoint=Gst.SECOND, duration=Gst.SECOND) # For variety, add TitleClip to the list of clips. ges_clip4 = common.create_test_clip(GES.TitleClip) ges_clip4.props.start = 3 * Gst.SECOND ges_clip4.props.duration = Gst.SECOND self.assertTrue(ges_layer.add_clip(ges_clip4)) self.check_keyframe_toggle(ges_clip1, timeline_container) self.check_keyframe_toggle(ges_clip2, timeline_container) self.check_keyframe_toggle(ges_clip3, timeline_container) self.check_keyframe_toggle(ges_clip4, timeline_container) self.check_keyframe_ui_toggle(ges_clip1, timeline_container) self.check_keyframe_ui_toggle(ges_clip2, timeline_container) self.check_keyframe_ui_toggle(ges_clip3, timeline_container) self.check_keyframe_ui_toggle(ges_clip4, timeline_container)
def test_can_group_ungroup(self): timeline_container = create_timeline_container() timeline = timeline_container.timeline self.__check_can_group_ungroup(timeline_container, False, False) ges_clip, = self.addClipsSimple(timeline, 1) self.toggle_clip_selection(ges_clip, expect_selected=True) self.__check_can_group_ungroup(timeline_container, False, True) timeline_container.ungroup_action.emit("activate", None) self.__check_can_group_ungroup(timeline_container, False, False) layer, = timeline.ges_timeline.get_layers() ges_clip0, ges_clip1 = layer.get_clips() self.toggle_clip_selection(ges_clip0, expect_selected=True) self.__check_can_group_ungroup(timeline_container, False, False) # Press <ctrl> so selecting in ADD mode event = mock.Mock() event.keyval = Gdk.KEY_Control_L timeline_container.do_key_press_event(event) self.toggle_clip_selection(ges_clip1, expect_selected=True) self.__check_can_group_ungroup(timeline_container, True, False) timeline_container.group_action.emit("activate", None) self.__check_can_group_ungroup(timeline_container, False, True)
def test_trimming_on_layer_separator(self): # Create a clip timeline_container = create_timeline_container() timeline = timeline_container.timeline clip, = self.addClipsSimple(timeline, 1) layer = clip.get_layer() # Click the right trim handle of the clip. with mock.patch.object(Gtk, 'get_event_widget') as get_event_widget: event = mock.Mock() event.get_button.return_value = True, 1 get_event_widget.return_value = clip.ui.rightHandle timeline._button_press_event_cb(None, event) self.assertIsNotNone(timeline.draggingElement) # Drag it to the left, on the separator below. event = mock.Mock() event.get_state.return_value = Gdk.ModifierType.BUTTON1_MASK with mock.patch.object( clip.ui.rightHandle, "translate_coordinates") as translate_coordinates: translate_coordinates.return_value = (0, 0) with mock.patch.object(timeline, "_get_layer_at") as _get_layer_at: _get_layer_at.return_value = layer, timeline._separators[1] timeline._motion_notify_event_cb(None, event) self.assertTrue(timeline.got_dragged) # Release the mouse button. event = mock.Mock() event.get_button.return_value = True, 1 timeline._button_release_event_cb(None, event) self.assertEqual(len(timeline.ges_timeline.get_layers()), 1, "No new layer should have been created")
def test_media_types(self): timeline_container = create_timeline_container() timeline = timeline_container.timeline ges_layer_1 = timeline.ges_timeline.append_layer() ges_layer_2 = timeline.ges_timeline.append_layer() # Timeline should contain no media_types. self.assertEqual(timeline.media_types, GES.TrackType(0)) # Timeline should now contain only audio media type. ges_clip_audio = self.add_clip(ges_layer_1, 10, clip_type=GES.TrackType.AUDIO) self.assertEqual(timeline.media_types, GES.TrackType.AUDIO) ges_layer_1.remove_clip(ges_clip_audio) ges_clip_video = self.add_clip(ges_layer_2, 20, clip_type=GES.TrackType.VIDEO) self.assertEqual(timeline.media_types, GES.TrackType.VIDEO) # Timeline should contain no media_types. ges_layer_2.remove_clip(ges_clip_video) self.assertEqual(timeline.media_types, GES.TrackType(0)) # Timeline should contain both clips. ges_clip_audio = self.add_clip(ges_layer_1, 10, clip_type=GES.TrackType.AUDIO) ges_clip_video = self.add_clip(ges_layer_2, 20, clip_type=GES.TrackType.VIDEO) self.assertEqual(timeline.media_types, GES.TrackType.VIDEO | GES.TrackType.AUDIO) # Timeline should contain no clips. ges_layer_1.remove_clip(ges_clip_audio) ges_layer_2.remove_clip(ges_clip_video) self.assertEqual(timeline.media_types, GES.TrackType(0))
def testSetSeparatorsPrelight(self): timeline_container = create_timeline_container() timeline = timeline_container.timeline timeline.__on_separators = [mock.Mock()] timeline._setSeparatorsPrelight(False) self.assertEqual(len(timeline.__on_separators), 1, "The separators must be forgotten only in dragEnd()")
def test_keyframe_toggle(self): """Checks keyframes toggling at the playhead position.""" timeline_container = create_timeline_container() timeline_container.app.action_log = UndoableActionLog() timeline = timeline_container.timeline ges_layer = timeline.ges_timeline.append_layer() ges_clip1 = self.add_clip(ges_layer, 0, duration=2 * Gst.SECOND) ges_clip2 = self.add_clip(ges_layer, 10, duration=2 * Gst.SECOND) ges_clip3 = self.add_clip(ges_layer, 20, inpoint=100, duration=2 * Gst.SECOND) # For variety, add TitleClip to the list of clips. ges_clip4 = create_test_clip(GES.TitleClip) ges_clip4.props.start = 30 ges_clip4.props.duration = int(0.9 * Gst.SECOND) ges_layer.add_clip(ges_clip4) self.check_keyframe_toggle(ges_clip1, timeline_container) self.check_keyframe_toggle(ges_clip2, timeline_container) self.check_keyframe_toggle(ges_clip3, timeline_container) self.check_keyframe_toggle(ges_clip4, timeline_container) for ges_clip in [ges_clip1, ges_clip2, ges_clip3, ges_clip4]: self.check_keyframe_ui_toggle(ges_clip, timeline_container)
def testGroupSplittedClipAndSelectGroup(self): position = 5 timeline_container = create_timeline_container() timeline = timeline_container.timeline clips = self.addClipsSimple(timeline, 1) self.toggle_clip_selection(clips[0], expect_selected=True) timeline.ges_timeline.get_asset().pipeline.getPosition = mock.Mock(return_value=position) layer = timeline.ges_timeline.get_layers()[0] # Split timeline_container.split_action.emit("activate", None) clips = layer.get_clips() self.assertEqual(len(clips), 2) # Only the first clip is selected so select the # second one self.assertTrue(clips[0].selected.selected) self.assertFalse(clips[1].selected.selected) event = mock.Mock() event.keyval = Gdk.KEY_Control_L timeline_container.do_key_press_event(event) self.toggle_clip_selection(clips[1], expect_selected=True) timeline_container.do_key_release_event(event) for clip in clips: self.assertTrue(clip.selected.selected) # Group the two parts timeline_container.group_action.emit("activate", None) self.toggle_clip_selection(clips[1], expect_selected=True)
def testSetAudioProp(self): timeline = common.create_timeline_container() project = timeline.app.project_manager.current_project project.addUris([common.get_sample_uri("mp3_sample.mp3")]) audio_track = [ t for t in project.ges_timeline.tracks if isinstance(t, GES.AudioTrack) ][0] mainloop = common.create_main_loop() def progress_cb(project, progress, estimated_time): if progress == 100: mainloop.quit() project.connect_after("asset-loading-progress", progress_cb) mainloop.run() expected = Gst.Caps("audio/x-raw,channels=(int)2,rate=(int)44100") ccaps = audio_track.props.restriction_caps self.assertTrue(ccaps.is_equal_fixed(expected), "%s != %s" % (ccaps, expected)) project.audiochannels = 6 expected = Gst.Caps("audio/x-raw,channels=(int)6,rate=(int)44100") ccaps = audio_track.props.restriction_caps self.assertTrue(ccaps.is_equal_fixed(expected), "%s != %s" % (ccaps, expected))
def test_prop_keyframe(self): """Checks the keyframe button effect.""" uri = common.get_sample_uri("tears_of_steel.webm") asset = GES.UriClipAsset.request_sync(uri) ges_clip = asset.extract() # Add the clip to a timeline so it gets tracks. timeline = common.create_timeline_container() self.app = timeline.app ges_timeline = timeline.ges_timeline ges_timeline.append_layer() ges_layer, = ges_timeline.get_layers() ges_layer.add_clip(ges_clip) self._register_alpha_widget( ("black_sens_adjustment", "GstAlpha::black-sensitivity", "GstAlpha::black-sensitivity::keyframe")) ges_clip.add(self.alpha_effect) track_element = self.element_settings_widget._GstElementSettingsWidget__get_track_element_of_same_type( self.alpha_effect) prop_keyframe_button = \ list(self.element_settings_widget._GstElementSettingsWidget__widgets_by_keyframe_button.keys())[0] # Control the self.prop property on the timeline prop_keyframe_button.set_active(True) self.assertEqual(track_element.ui_element._TimelineElement__controlledProperty, self.prop) # Revert to controlling the default property prop_keyframe_button.set_active(False) self.assertNotEqual(track_element.ui_element._TimelineElement__controlledProperty, self.prop)
def test_toplevels(self): timeline_container = common.create_timeline_container() timeline = timeline_container.timeline clip1, clip2, clip3, clip4 = self.addClipsSimple(timeline, 4) selection = Selection() selection.setSelection([clip1, clip2, clip3, clip4], SELECT) self.assertSetEqual(selection.toplevels, {clip1, clip2, clip3, clip4}) group1 = GES.Container.group([clip1, clip2]) group1.props.serialize = True self.assertSetEqual(selection.toplevels, {group1, clip3, clip4}) group2 = GES.Container.group([group1, clip3]) group2.props.serialize = True self.assertSetEqual(selection.toplevels, {group2, clip4}) group1.props.serialize = True group1.props.serialize = False self.assertSetEqual(selection.toplevels, {group2, clip4}) group1.props.serialize = False group2.props.serialize = False self.assertSetEqual(selection.toplevels, {clip1, clip2, clip3, clip4}) group1.props.serialize = True group2.props.serialize = False self.assertSetEqual(selection.toplevels, {group1, clip3, clip4})
def test_ungroup_clip(self): timeline_container = common.create_timeline_container() timeline = timeline_container.timeline ges_clip, = self.add_clips_simple(timeline, 1) self.toggle_clip_selection(ges_clip, expect_selected=True) timeline_container.ungroup_action.emit("activate", None) layer = timeline.ges_timeline.get_layers()[0] ges_clip0, ges_clip1 = layer.get_clips() self.assertEqual(ges_clip0.props.start, ges_clip1.props.start) self.assertEqual(ges_clip0.props.duration, ges_clip1.props.duration) track_elem_0, = ges_clip0.get_children(recursive=False) track_elem_1, = ges_clip1.get_children(recursive=False) if track_elem_0.get_track_type() == GES.TrackType.AUDIO: aclip = ges_clip0.ui atrackelem = track_elem_0.ui vclip = ges_clip1.ui vtrackelem = track_elem_1.ui else: aclip = ges_clip1.ui atrackelem = track_elem_1.ui vclip = ges_clip0.ui vtrackelem = track_elem_0.ui self.assertEqual(aclip.audio_widget, atrackelem) self.assertEqual(vclip.video_widget, vtrackelem)
def test_trimming_on_layer_separator(self): # Create a clip timeline_container = create_timeline_container() timeline = timeline_container.timeline clip, = self.addClipsSimple(timeline, 1) layer = clip.get_layer() # Click the right trim handle of the clip. with mock.patch.object(Gtk, 'get_event_widget') as get_event_widget: event = mock.Mock() event.get_button.return_value = True, 1 get_event_widget.return_value = clip.ui.rightHandle timeline._button_press_event_cb(None, event) self.assertIsNotNone(timeline.draggingElement) # Drag it to the left, on the separator below. event = mock.Mock() event.get_state.return_value = Gdk.ModifierType.BUTTON1_MASK with mock.patch.object(clip.ui.rightHandle, "translate_coordinates") as translate_coordinates: translate_coordinates.return_value = (0, 0) with mock.patch.object(timeline, "_get_layer_at") as _get_layer_at: _get_layer_at.return_value = layer, timeline._separators[1] timeline._motion_notify_event_cb(None, event) self.assertTrue(timeline.got_dragged) # Release the mouse button. event = mock.Mock() event.get_button.return_value = True, 1 timeline._button_release_event_cb(None, event) self.assertEqual(len(timeline.ges_timeline.get_layers()), 1, "No new layer should have been created")
def test_launching_rendering(self): """Checks no exception is raised when clicking the render button.""" timeline_container = common.create_timeline_container() app = timeline_container.app project = app.project_manager.current_project mainloop = common.create_main_loop() def asset_added_cb(project, asset): # pylint: disable=missing-docstring mainloop.quit() project.connect("asset-added", asset_added_cb) uris = [common.get_sample_uri("tears_of_steel.webm")] project.addUris(uris) mainloop.run() layer, = project.ges_timeline.get_layers() layer.add_asset(project.list_assets(GES.UriClip)[0], 0, 0, Gst.CLOCK_TIME_NONE, GES.TrackType.UNKNOWN) from pitivi.render import RenderDialog, RenderingProgressDialog with mock.patch.object(Gtk.Builder, "__new__"): dialog = RenderDialog(app, project) with mock.patch.object(dialog, "startAction"): with mock.patch.object(RenderingProgressDialog, "__new__"): with mock.patch.object(dialog, "_pipeline"): dialog._renderButtonClickedCb(None)
def test_video_source_scaling(self): """Checks the size of the scaled clips.""" timeline_container = common.create_timeline_container() timeline = timeline_container.timeline project = timeline.app.project_manager.current_project clip = self.add_clips_simple(timeline, 1)[0] video_source = clip.find_track_element(None, GES.VideoUriSource) sinfo = video_source.get_asset().get_stream_info() width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(sinfo.get_width(), 960) self.assertEqual(sinfo.get_height(), 400) self.assertEqual(project.videowidth, sinfo.get_width()) self.assertEqual(project.videoheight, sinfo.get_height()) self.assertEqual(project.videowidth, width) self.assertEqual(project.videoheight, height) project.set_video_properties(sinfo.get_width() * 2, sinfo.get_height() * 2, project.videorate) width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(project.videowidth, width) self.assertEqual(project.videoheight, height) # GES won't ever break aspect ratio, neither should we! project.set_video_properties(150, 200, project.videorate) self.assertEqual(video_source.get_child_property("width").value, width) self.assertEqual(video_source.get_child_property("height").value, height)
def testUngroupClip(self): timeline_container = create_timeline_container() timeline = timeline_container.timeline ges_clip, = self.addClipsSimple(timeline, 1) self.toggle_clip_selection(ges_clip, expect_selected=True) timeline_container.ungroup_action.emit("activate", None) layer = timeline.ges_timeline.get_layers()[0] ges_clip0, ges_clip1 = layer.get_clips() self.assertEqual(ges_clip0.props.start, ges_clip1.props.start) self.assertEqual(ges_clip0.props.duration, ges_clip1.props.duration) bTrackElem0, = ges_clip0.get_children(recursive=False) bTrackElem1, = ges_clip1.get_children(recursive=False) if bTrackElem0.get_track_type() == GES.TrackType.AUDIO: aclip = ges_clip0.ui atrackelem = bTrackElem0.ui vclip = ges_clip1.ui vtrackelem = bTrackElem1.ui else: aclip = ges_clip1.ui atrackelem = bTrackElem1.ui vclip = ges_clip0.ui vtrackelem = bTrackElem0.ui self.assertEqual(aclip._audioSource, atrackelem) self.assertEqual(vclip._videoSource, vtrackelem)
def test_prop_keyframe(self): """Checks the keyframe button effect.""" uri = common.get_sample_uri("tears_of_steel.webm") asset = GES.UriClipAsset.request_sync(uri) ges_clip = asset.extract() # Add the clip to a timeline so it gets tracks. timeline = common.create_timeline_container() self.app = timeline.app ges_timeline = timeline.ges_timeline ges_timeline.append_layer() ges_layer, = ges_timeline.get_layers() ges_layer.add_clip(ges_clip) self._register_alpha_widget( ("black_sens_adjustment", "GstAlpha::black-sensitivity", "GstAlpha::black-sensitivity::keyframe")) ges_clip.add(self.alpha_effect) track_element = self.element_settings_widget._GstElementSettingsWidget__get_track_element_of_same_type( self.alpha_effect) prop_keyframe_button = \ list(self.element_settings_widget._GstElementSettingsWidget__widgets_by_keyframe_button.keys())[0] # Control the self.prop property on the timeline prop_keyframe_button.set_active(True) self.assertEqual( track_element.ui_element._TimelineElement__controlledProperty, self.prop) # Revert to controlling the default property prop_keyframe_button.set_active(False) self.assertNotEqual( track_element.ui_element._TimelineElement__controlledProperty, self.prop)
def check_create_layer(self, start_priorities, expected_priorities): timeline = create_timeline_container().timeline ges_layers = [] for priority in start_priorities: ges_layer = timeline.create_layer(priority) self.assertEqual(ges_layer.props.priority, priority) ges_layers.append(ges_layer) self.check_priorities_and_positions(timeline, ges_layers, expected_priorities)
def checkGetLayerAt(self, heights, preferred, past_middle_when_adjacent, expectations): timeline_container = create_timeline_container() timeline = timeline_container.timeline # Allocate layers y = 0 for priority, height in enumerate(heights): ges_layer = timeline.create_layer(priority=priority) rect = Gdk.Rectangle() rect.y = y rect.height = height ges_layer.ui.set_allocation(rect) y += height + SEPARATOR_HEIGHT ges_layers = timeline.ges_timeline.get_layers() if preferred is None: preferred_ges_layer = None else: preferred_ges_layer = ges_layers[preferred] # The heights of the layers. h = [ges_layer.ui.get_allocation().height for ges_layer in ges_layers] s = SEPARATOR_HEIGHT def assertLayerAt(ges_layer, y): result = timeline._get_layer_at( int(y), prefer_ges_layer=preferred_ges_layer, past_middle_when_adjacent=past_middle_when_adjacent) self.assertEqual( ges_layer, result[0], "Expected %d, got %d at %d" % (ges_layers.index(ges_layer), ges_layers.index(result[0]), y)) # y on the top layer. assertLayerAt(ges_layers[expectations[0]], 0) assertLayerAt(ges_layers[expectations[1]], h[0] / 2 - 1) assertLayerAt(ges_layers[expectations[2]], h[0] / 2) assertLayerAt(ges_layers[expectations[3]], h[0] - 1) # y on the separator. assertLayerAt(ges_layers[expectations[4]], h[0]) assertLayerAt(ges_layers[expectations[5]], h[0] + s - 1) # y on the middle layer. assertLayerAt(ges_layers[expectations[6]], h[0] + s) assertLayerAt(ges_layers[expectations[7]], h[0] + s + h[1] / 2 - 1) assertLayerAt(ges_layers[expectations[8]], h[0] + s + h[1] / 2) assertLayerAt(ges_layers[expectations[9]], h[0] + s + h[1] - 1) # y on the separator. assertLayerAt(ges_layers[expectations[10]], h[0] + s + h[1]) assertLayerAt(ges_layers[expectations[11]], h[0] + s + h[1] + s - 1) # y on the bottom layer. assertLayerAt(ges_layers[expectations[12]], h[0] + s + h[1] + s) assertLayerAt(ges_layers[expectations[13]], h[0] + s + h[1] + s + h[2] / 2 - 1) assertLayerAt(ges_layers[expectations[14]], h[0] + s + h[1] + s + h[2] / 2) assertLayerAt(ges_layers[expectations[15]], h[0] + s + h[1] + s + h[2] - 1)
def setup_transformation_box(self): """Creates a TransformationProperties widget.""" timeline_container = common.create_timeline_container() app = timeline_container.app transformation_box = TransformationProperties(app) project = timeline_container._project transformation_box._newProjectLoadedCb(app, project) return transformation_box
def setUp(self): super().setUp() timeline_container = common.create_timeline_container() self.ges_timeline = timeline_container.timeline.ges_timeline timeline_container.app.action_log = UndoableActionLog() self.timeline_observer = TimelineObserver( timeline_container.ges_timeline, timeline_container.app.action_log)
def test_video_source_scaling(self): """Checks the size of the scaled clips.""" timeline_container = common.create_timeline_container() timeline = timeline_container.timeline project = timeline.app.project_manager.current_project clip = self.addClipsSimple(timeline, 1)[0] video_source = clip.find_track_element(None, GES.VideoUriSource) sinfo = video_source.get_asset().get_stream_info() width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(sinfo.get_width(), 960) self.assertEqual(sinfo.get_height(), 400) self.assertEqual(project.videowidth, sinfo.get_width()) self.assertEqual(project.videoheight, sinfo.get_height()) self.assertEqual(project.videowidth, width) self.assertEqual(project.videoheight, height) project.videowidth = sinfo.get_width() * 2 project.videoheight = sinfo.get_height() * 2 width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(project.videowidth, width) self.assertEqual(project.videoheight, height) project.videowidth = 150 project.videoheight = 200 width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] expected_width = project.videowidth expected_height = int(sinfo.get_height() * (project.videowidth / sinfo.get_width())) self.assertEqual(width, expected_width) self.assertEqual(height, expected_height) video_source.set_child_property("posx", 50) width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(width, expected_width) self.assertEqual(height, expected_height) project.videowidth = 1920 project.videoheight = 1080 self.assertEqual(width, expected_width) self.assertEqual(height, expected_height) expected_default_position = { "width": 1920, "height": 800, "posx": 0, "posy": 140 } self.assertEqual(video_source.ui.default_position, expected_default_position)
def setup_transformation_box(self): """Creates a TransformationProperties widget.""" timeline_container = common.create_timeline_container() app = timeline_container.app transformation_box = TransformationProperties(app) project = timeline_container._project transformation_box._new_project_loaded_cb(app, project) return transformation_box
def __check_shift_selection_single_layer(self, left_click_also_seeks): """Checks group clips selection across a single layer.""" timeline_container = create_timeline_container() timeline = timeline_container.timeline timeline.app.settings.leftClickAlsoSeeks = left_click_also_seeks ges_layer = timeline.ges_timeline.append_layer() ges_clip1 = self.add_clip(ges_layer, 5 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip2 = self.add_clip(ges_layer, 15 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip3 = self.add_clip(ges_layer, 25 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip4 = self.add_clip(ges_layer, 35 * Gst.SECOND, duration=2 * Gst.SECOND) event = mock.Mock() event.get_button.return_value = (True, 1) timeline.get_parent()._shiftMask = True timeline._seek = mock.Mock() timeline._seek.return_value = True timeline.get_clicked_layer_and_pos = mock.Mock() with mock.patch.object(Gtk, "get_event_widget") as get_event_widget: get_event_widget.return_value = timeline # Simulate shift+click before first and on second clip. timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 1 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 17 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip1, ges_clip2], [ges_clip3, ges_clip4]) self.__reset_clips_selection(timeline) timeline.resetSelectionGroup() # Simiulate shift+click before first and after fourth clip. timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 1 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 39 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip1, ges_clip2, ges_clip3, ges_clip4], []) self.__reset_clips_selection(timeline) timeline.resetSelectionGroup() # Simiulate shift+click on first, after fourth and before third clip. timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 6 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 40 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 23 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip1, ges_clip2], [ges_clip3, ges_clip4]) self.__reset_clips_selection(timeline) timeline.resetSelectionGroup() # Simulate shift+click twice on the same clip. timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 6 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer, 6.5 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip1], [ges_clip2, ges_clip3, ges_clip4])
def test_video_source_scaling(self): """Checks the size of the scaled clips.""" timeline_container = create_timeline_container() timeline = timeline_container.timeline project = timeline.app.project_manager.current_project clip = self.addClipsSimple(timeline, 1)[0] video_source = clip.find_track_element(None, GES.VideoUriSource) sinfo = video_source.get_asset().get_stream_info() width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(sinfo.get_width(), 960) self.assertEqual(sinfo.get_height(), 400) self.assertEqual(project.videowidth, sinfo.get_width()) self.assertEqual(project.videoheight, sinfo.get_height()) self.assertEqual(project.videowidth, width) self.assertEqual(project.videoheight, height) project.videowidth = sinfo.get_width() * 2 project.videoheight = sinfo.get_height() * 2 width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(project.videowidth, width) self.assertEqual(project.videoheight, height) project.videowidth = 150 project.videoheight = 200 width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] expected_width = project.videowidth expected_height = int(sinfo.get_height() * (project.videowidth / sinfo.get_width())) self.assertEqual(width, expected_width) self.assertEqual(height, expected_height) video_source.set_child_property("posx", 50) width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(width, expected_width) self.assertEqual(height, expected_height) project.videowidth = 1920 project.videoheight = 1080 self.assertEqual(width, expected_width) self.assertEqual(height, expected_height) expected_default_position = { "width": 1920, "height": 800, "posx": 0, "posy": 140} self.assertEqual(video_source.ui.default_position, expected_default_position)
def __check_shift_selection_multiple_layers(self, left_click_also_seeks): """Checks group clips selection across multiple layers.""" timeline_container = create_timeline_container() timeline = timeline_container.timeline timeline.app.settings.leftClickAlsoSeeks = left_click_also_seeks ges_layer1 = timeline.ges_timeline.append_layer() ges_clip11 = self.add_clip(ges_layer1, 5 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip12 = self.add_clip(ges_layer1, 15 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip13 = self.add_clip(ges_layer1, 25 * Gst.SECOND, duration=2 * Gst.SECOND) ges_layer2 = timeline.ges_timeline.append_layer() ges_clip21 = self.add_clip(ges_layer2, 0 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip22 = self.add_clip(ges_layer2, 6 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip23 = self.add_clip(ges_layer2, 21 * Gst.SECOND, duration=2 * Gst.SECOND) ges_layer3 = timeline.ges_timeline.append_layer() ges_clip31 = self.add_clip(ges_layer3, 3 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip32 = self.add_clip(ges_layer3, 10 * Gst.SECOND, duration=2 * Gst.SECOND) ges_clip33 = self.add_clip(ges_layer3, 18 * Gst.SECOND, duration=2 * Gst.SECOND) event = mock.Mock() event.get_button.return_value = (True, 1) timeline.get_parent()._shiftMask = True timeline._seek = mock.Mock() timeline._seek.return_value = True timeline.get_clicked_layer_and_pos = mock.Mock() with mock.patch.object(Gtk, "get_event_widget") as get_event_widget: get_event_widget.return_value = timeline timeline.get_clicked_layer_and_pos.return_value = (ges_layer2, 3 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer1, 9 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip11, ges_clip22], [ges_clip12, ges_clip13, ges_clip21, ges_clip23, ges_clip31, ges_clip32, ges_clip33]) timeline.get_clicked_layer_and_pos.return_value = (ges_layer3, 12 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip22, ges_clip31, ges_clip32], [ges_clip11, ges_clip12, ges_clip13, ges_clip21, ges_clip23, ges_clip33]) timeline.get_clicked_layer_and_pos.return_value = (ges_layer1, 22 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip11, ges_clip12, ges_clip22, ges_clip23], [ges_clip13, ges_clip21, ges_clip31, ges_clip32, ges_clip33]) self.__reset_clips_selection(timeline) timeline.resetSelectionGroup() timeline.get_clicked_layer_and_pos.return_value = (ges_layer1, 3 * Gst.SECOND) timeline._button_release_event_cb(None, event) timeline.get_clicked_layer_and_pos.return_value = (ges_layer2, 26 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip11, ges_clip12, ges_clip13, ges_clip22, ges_clip23], [ges_clip21, ges_clip31, ges_clip32, ges_clip33]) timeline.get_clicked_layer_and_pos.return_value = (ges_layer3, 30 * Gst.SECOND) timeline._button_release_event_cb(None, event) self.__check_selected([ges_clip11, ges_clip12, ges_clip13, ges_clip22, ges_clip23, ges_clip31, ges_clip32, ges_clip33], [ges_clip21])
def check_move_layer(self, from_priority, to_priority, expected_priorities): timeline = create_timeline_container().timeline # Add layers to move them later. ges_layers = [] for priority in range(len(expected_priorities)): ges_layer = timeline.create_layer(priority) ges_layers.append(ges_layer) timeline.moveLayer(ges_layers[from_priority], to_priority) self.check_priorities_and_positions(timeline, ges_layers, expected_priorities)
def test_check_media_types_when_no_control_ui(self): ges_layer = GES.Layer() png = common.get_sample_uri("flat_colour1_640x480.png") video_clip = GES.UriClipAsset.request_sync(png).extract() self.assertTrue(ges_layer.add_clip(video_clip)) self.assertEqual(len(ges_layer.get_clips()), 1) timeline_container = common.create_timeline_container() timeline = timeline_container.timeline # This will add widgets for the clips in ges_layer and # the layer will use checkMediaTypes which updates the # height of layer.control_ui, which now it should not be set. self.assertFalse(hasattr(ges_layer, "control_ui")) unused_layer = Layer(ges_layer, timeline)
def test_update_clips_asset(self): timeline_container = common.create_timeline_container() mainloop = common.create_main_loop() mainloop.run(until_empty=True) ges_timeline = timeline_container.ges_timeline layer, = ges_timeline.get_layers() title_clip = GES.TitleClip() title_clip.props.duration = 100 layer.add_clip(title_clip) self.assertListEqual(list(timeline_container.timeline.clips()), [title_clip]) # Check the title clips are ignored. timeline_container.update_clips_asset(mock.Mock())
def check_remove_layer(self, removal_order): timeline = create_timeline_container().timeline # Add layers to remove them later. ges_layers = [] for priority in range(len(removal_order)): ges_layer = timeline.createLayer(priority) ges_layers.append(ges_layer) # Remove the layers in the specified order. for priority in removal_order: ges_layer = ges_layers[priority] self.assertTrue(timeline.ges_timeline.remove_layer(ges_layer)) ges_layers.remove(ges_layer) self.check_priorities_and_positions(timeline, ges_layers, list(range(len(ges_layers))))
def test_timeline_proxy_switching(self): sample_name = "30fps_numeroted_frames_red.mkv" with common.cloned_sample(sample_name): self.check_import([sample_name], proxying_strategy=ProxyingStrategy.NOTHING) common.create_timeline_container(self.app) timeline = self.app.project_manager.current_project.ges_timeline asset = self.medialibrary.store[0].asset timeline.append_layer().add_asset(asset, 0, 0, Gst.CLOCK_TIME_NONE, GES.TrackType.VIDEO) def check_timeline_clip(expected_asset): for layer in timeline.layers: for clip in layer.get_clips(): self.assertEqual(clip.get_asset(), expected_asset) # Check asset is in the timeline check_timeline_clip(asset) # Check asset is replaced by scaled proxy scaled_proxy = self.check_add_proxy(asset, scaled=True) check_timeline_clip(scaled_proxy) # Check proxy is replaced back by asset self.check_disable_proxy(scaled_proxy, asset, delete=True) check_timeline_clip(asset) # Check asset is replaced by HQ proxy hq_proxy = self.check_add_proxy(asset) check_timeline_clip(hq_proxy) # Check proxy was replaced back by asset self.check_disable_proxy(hq_proxy, asset, delete=True) check_timeline_clip(asset)
def testGroupUngroup(self): num_clips = 2 timeline_container = create_timeline_container() timeline = timeline_container.timeline clips = self.addClipsSimple(timeline, num_clips) self.group_clips(timeline_container, clips) self.assertEqual(len(timeline.selection.selected), num_clips) timeline_container.ungroup_action.emit("activate", None) layer = timeline.ges_timeline.get_layers()[0] clips = layer.get_clips() self.assertEqual(len(clips), num_clips) for clip in clips: self.assertIsNone(clip.get_parent())
def check_remove_layer(self, removal_order): timeline = create_timeline_container().timeline # Add layers to remove them later. ges_layers = [] # Pitivi doesn't support removing the last remaining layer, # that's why we create an extra layer. for priority in range(len(removal_order) + 1): ges_layer = timeline.create_layer(priority) ges_layers.append(ges_layer) # Remove layers one by one in the specified order. for priority in removal_order: ges_layer = ges_layers[priority] ges_layer.control_ui.delete_layer_action.activate(None) ges_layers.remove(ges_layer) self.check_priorities_and_positions(timeline, ges_layers, list(range(len(ges_layers))))
def testGroupSelection(self): num_clips = 2 timeline_container = create_timeline_container() timeline = timeline_container.timeline clips = self.addClipsSimple(timeline, num_clips) self.group_clips(timeline_container, clips) layer = timeline.ges_timeline.get_layers()[0] clips = layer.get_clips() self.assertEqual(len(clips), num_clips) # Deselect one grouped clip clips self.toggle_clip_selection(clips[0], expect_selected=False) # Make sure all the clips have been deselected for clip in clips: self.assertFalse(bool(clip.ui.get_state_flags() & Gtk.StateFlags.SELECTED)) self.assertFalse(clip.selected.selected)
def test_rotation(self): """Checks the size of the clips flipped 90 degrees.""" timeline_container = create_timeline_container() timeline = timeline_container.timeline clip = self.addClipsSimple(timeline, 1)[0] video_source = clip.find_track_element(None, GES.VideoUriSource) sinfo = video_source.get_asset().get_stream_info() width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(sinfo.get_width(), 960) self.assertEqual(sinfo.get_height(), 400) self.assertEqual(width, 960) self.assertEqual(height, 400) videoflip = GES.Effect.new("videoflip") videoflip.set_child_property("method", 1) # clockwise clip.add(videoflip) # The video is flipped 90 degrees width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(width, 167) self.assertEqual(height, 400) videoflip.props.active = False width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(width, 960) self.assertEqual(height, 400) videoflip.props.active = True width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(width, 167) self.assertEqual(height, 400) clip.remove(videoflip) width = video_source.get_child_property("width")[1] height = video_source.get_child_property("height")[1] self.assertEqual(width, 960) self.assertEqual(height, 400)
def copyClips(self, num_clips): timeline_container = create_timeline_container() timeline = timeline_container.timeline clips = self.addClipsSimple(timeline, num_clips) # Press <ctrl> so selecting in ADD mode event = mock.Mock() event.keyval = Gdk.KEY_Control_L timeline_container.do_key_press_event(event) # Select the 2 clips for clip in clips: self.toggle_clip_selection(clip, expect_selected=True) self.assertTrue(timeline_container.copy_action.props.enabled) self.assertFalse(timeline_container.paste_action.props.enabled) timeline_container.copy_action.emit("activate", None) self.assertTrue(timeline_container.paste_action.props.enabled) return timeline_container
def test_keyframe_toggle(self): """Checks keyframes toggling at the playhead position.""" timeline_container = create_timeline_container() timeline_container.app.action_log = UndoableActionLog() timeline = timeline_container.timeline ges_layer = timeline.ges_timeline.append_layer() ges_clip1 = self.add_clip(ges_layer, 0, duration=2*Gst.SECOND) ges_clip2 = self.add_clip(ges_layer, 10, duration=2*Gst.SECOND) ges_clip3 = self.add_clip(ges_layer, 20, inpoint=100, duration=2*Gst.SECOND) # For variety, add TitleClip to the list of clips. ges_clip4 = create_test_clip(GES.TitleClip) ges_clip4.props.start = 30 ges_clip4.props.duration = int(0.9 * Gst.SECOND) ges_layer.add_clip(ges_clip4) self.check_keyframe_toggle(ges_clip1, timeline_container) self.check_keyframe_toggle(ges_clip2, timeline_container) self.check_keyframe_toggle(ges_clip3, timeline_container) self.check_keyframe_toggle(ges_clip4, timeline_container) for ges_clip in [ges_clip1, ges_clip2, ges_clip3, ges_clip4]: self.check_keyframe_ui_toggle(ges_clip, timeline_container)
def test_dragging_group_on_separator(self): # Create two clips on different layers and group them. timeline_container = create_timeline_container() timeline = timeline_container.timeline clip1, = self.addClipsSimple(timeline, 1) layer1 = clip1.get_layer() # Add another clip on a new layer. clip2, = self.addClipsSimple(timeline, 1) self.assertEqual(len(timeline.ges_timeline.get_layers()), 2) self.group_clips(timeline_container, [clip1, clip2]) # Click the first clip in the group. with mock.patch.object(Gtk, 'get_event_widget') as get_event_widget: event = mock.Mock() event.x = 0 event.get_button.return_value = True, 1 get_event_widget.return_value = clip1.ui timeline._button_press_event_cb(None, event) self.assertIsNotNone(timeline.draggingElement) # Move it to the right, on the separator below. event = mock.Mock() event.get_state.return_value = Gdk.ModifierType.BUTTON1_MASK with mock.patch.object(clip1.ui, "translate_coordinates") as translate_coordinates: translate_coordinates.return_value = (40, 0) with mock.patch.object(timeline, "_get_layer_at") as _get_layer_at: _get_layer_at.return_value = layer1, timeline._separators[1] timeline._motion_notify_event_cb(None, event) self.assertTrue(timeline.got_dragged) # Release the mouse button. event = mock.Mock() event.get_button.return_value = True, 1 timeline._button_release_event_cb(None, event) self.assertEqual(len(timeline.ges_timeline.get_layers()), 2, "No new layer should have been created")
def test_good_for_track_element(self): """Checks the good_for_track_element method.""" uri = common.get_sample_uri("tears_of_steel.webm") asset = GES.UriClipAsset.request_sync(uri) ges_clip = asset.extract() # Add the clip to a timeline so it gets tracks. ges_timeline = common.create_timeline_container().timeline.ges_timeline ges_timeline.append_layer() ges_layer, = ges_timeline.get_layers() ges_layer.add_clip(ges_clip) track_elements = {track_element.get_track_type(): track_element for track_element in ges_clip.get_children(recursive=True)} audio_track_element = track_elements[GES.TrackType.AUDIO] video_track_element = track_elements[GES.TrackType.VIDEO] effect_info = EffectInfo(None, AUDIO_EFFECT, None, None, None) self.assertTrue(effect_info.good_for_track_element(audio_track_element)) self.assertFalse(effect_info.good_for_track_element(video_track_element)) effect_info = EffectInfo(None, VIDEO_EFFECT, None, None, None) self.assertFalse(effect_info.good_for_track_element(audio_track_element)) self.assertTrue(effect_info.good_for_track_element(video_track_element))
def create_simple_project(self): """Creates a Project with a layer a clip.""" timeline_container = common.create_timeline_container() app = timeline_container.app project = app.project_manager.current_project if not project.ges_timeline.get_layers(): project.ges_timeline.append_layer() mainloop = common.create_main_loop() def asset_added_cb(project, asset): # pylint: disable=missing-docstring mainloop.quit() project.connect("asset-added", asset_added_cb) uris = [common.get_sample_uri("tears_of_steel.webm")] project.addUris(uris) mainloop.run() layer, = project.ges_timeline.get_layers() layer.add_asset(project.list_assets(GES.UriClip)[0], 0, 0, Gst.CLOCK_TIME_NONE, GES.TrackType.UNKNOWN) return project
def testSetAudioProp(self): timeline = common.create_timeline_container() project = timeline.app.project_manager.current_project project.addUris([common.get_sample_uri("mp3_sample.mp3")]) audio_track = [t for t in project.ges_timeline.tracks if isinstance(t, GES.AudioTrack)][0] mainloop = common.create_main_loop() def progress_cb(project, progress, estimated_time): if progress == 100: mainloop.quit() project.connect_after("asset-loading-progress", progress_cb) mainloop.run() expected = Gst.Caps("audio/x-raw,channels=(int)2,rate=(int)44100") ccaps = audio_track.props.restriction_caps self.assertTrue(ccaps.is_equal_fixed(expected), "%s != %s" % (ccaps, expected)) project.audiochannels = 6 expected = Gst.Caps("audio/x-raw,channels=(int)6,rate=(int)44100") ccaps = audio_track.props.restriction_caps self.assertTrue(ccaps.is_equal_fixed(expected), "%s != %s" % (ccaps, expected))
def test_no_clip_selected(self): """Checks nothing happens when no clip is selected.""" timeline_container = create_timeline_container() # Make sure this does not raise any exception timeline_container._keyframe_cb(None, None)