Pratyush Tiwari
Avid programmer, learning the art of problem-solving. Android Developer. Opensource Contributer. To build services which would ease the life, not make it less mobile.
Aug , 2021 • 10 min read

Google Summer of Code Final Report @Pitivi~Cut Mode.

Let's quickly go over the project :)

Pitivi ~Cut Mode

The Idea for this project is to have two timelines to ease certain types of tasks and increase productivity. This will essentially bring in a non-zoomable Timeline which will serve to ease the task of trimming, cutting, rearranging clips on the timeline in sync with the other timeline.


You can also watch the GUADEC Intern Lightening talks 2021, I talk about my project "Cut-Mode" with the other contributors and communty members.


Mostly, when we have a movie of a longer duration, we want to use the Zoom feature to see the whole timeline and scroll in-out to perform edits and rearrange clips. It consumes a lot of time which may be used productively somewhere, so to reduce user actions we have a zoom fitted timeline with small height layers so that all the layers and tracks are always visible. Now you only think about Zoom when you want to perform some precise edits, others on the Zoom fitted timeline ;).

From now, we will call the ZoomFitted timeline a Mini Timeline and the other simply a Timeline.

Longer duration timeline?

You can easily keep track having the scaled, reduced size elements on the Mini Timeline.


Further, it scales as you add elements at the end (Timeline Duration Increases) vice-versa, the whole timeline fits in the Mini Timeline view.


Many layers to work with?

Pitivi allows you to unlock all the views to a separate window, so If you have more layers, you may undock the views to separate screens and expand the Mini Timeline to make all the layers visible at the same time.


Let's dive deep!

Consider a case where we want to edit a portion of a timeline, for precise edits we have to zoom in at the required position, do the edits, zoom out, move to the next position, and so on for subsequent edits. This eats up a lot of precious time. The new Mini timeline allows the user to see the zoomed view as well as keep track of position in the Mini timeline at the same time. Now you can move anywhere in the timeline with a single click, preserving the zoomed view in Playhead Locked mode, can be enabled via keys `Alt+P`.
It scrolls the Timeline horizontally such that Playhead is centered concerning the Timeline.


Mini Timeline also allows you to rearrange clips so, where you have a short clip of about a few seconds and you wish to relocate it, say from start to the end of the timeline, you would select a clip, zoom out the timeline and drag it to end, zoom in to come to the same state. Another way is to start dragging and use the over scroll mechanism and wait for your desired position. Neither of them is ideal. The new Mini timeline allows us to quickly locate clips and drag them at any position since the entire duration is always in view.


What else?

You can do all the stuff on Mini Timeline that you do on the conventional Timeline. For example, you can drag clips directly on the Mini Timeline, select overlapped clips to apply transitions, drag effects directly over the mini timeline elements, etc.

Drag on the Mini Timeline.


Apply transitions & Drop effects.


Finally, when you are done, you can easily hide it by hitting keys `Alt+C`





I present you a high-level overview of how everything is structured.

The Layer class was refactored and subclassed into two implementations, namely, Full Layer and Mini Layer.


Similarly, the Clip class was refactored and subclassed into Full Clip and Mini Clip.


Similarly, for other related classes as well.

So, now, the Timeline architecture changes to


Code Snippets

1. As the Mini Timeline does not change with zoom-level (unlike Timeline) and always remains zoom-fitted, the Mini versions of classes do not subclass Zoomable , instead, they use the best ratio to transform positions whenever changed.
Below is the method for the calculation of the best ratio to fit the Timeline into the view.

def calc_best_zoom_ratio(self, mini=True):
    """Returns the zoom ratio so that the entire timeline is in (mini)view."""
    duration = 0 if not self.ges_timeline else self.ges_timeline.get_duration()
    if not duration or (mini and not self.mini_layout_container.get_visible()):
        # Maximum available width, the parent is TimelineContainer
        return self.get_parent().get_allocated_width()

    # Add Gst.SECOND - 1 to the timeline duration to make sure the
    # last second of the timeline will be in view.
    timeline_duration = duration + Gst.SECOND - 1
    timeline_duration_s = int(timeline_duration / Gst.SECOND)
    self.debug("Adjusting zoom for a timeline duration of %s secs",

    layout = self.mini_layout if mini else self.layout
    zoom_ratio = layout.get_allocation().width / timeline_duration_s
    return zoom_ratio

2. The Clips/Elements on the Mini Timeline are just simple representations without the thumbnails, we use color-filled rectangles (the color is decided based on the type of clip) to represent them.

class MiniPreview (Gtk.Layout):
"""Mini Clip previewer to draw color filled mini clips."""

def __init__(self, color):
    self.color = color
    self.props.height_request = MINI_LAYER_HEIGHT

def do_draw(self, context):
    rect = Gdk.cairo_get_clip_rectangle(context)[1]
    context.rectangle(0, 0, rect.width, rect.height)

All the Code and the changes are available on MR !397

Implementing the Mini Timeline became easy with the feedback from mentors and the clean and extensible codebase.

That's it for now. I will be adding more things here as they come.

Have a great day!

Will update you soon.