README.md: fix a couple of typos
[vidi-player.git] / vidi / Timeline.py
1 #!/usr/bin/env python3
2 #
3 # Timeline - very simple GES timeline wrapper
4 #
5 # Copyright (C) 2016  Antonio Ospite <ao2@ao2.it>
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import gi
21
22 gi.require_version('Gst', '1.0')
23 from gi.repository import Gst
24 Gst.init(None)
25
26 gi.require_version('GES', '1.0')
27 from gi.repository import GES
28 GES.init()
29
30 from .Player import Player
31
32 TITLE_BACKGROUND = 0xFF000000
33 TITLE_COLOR = 0xFFFFFFFF
34 TITLE_OUTLINE_COLOR = 0x00000000
35 TITLE_FONT_DESC = "Georgia, 24"
36
37 class Timeline(object):
38     def __init__(self, canvas_size=None):
39         self.project = GES.Project(extractable_type=GES.Timeline)
40         self.timeline = GES.Asset.extract(self.project)
41
42         audio_track = GES.AudioTrack.new()
43         video_track = GES.VideoTrack.new()
44
45         if canvas_size:
46             width, height = canvas_size
47             caps = Gst.Caps.new_empty_simple("video/x-raw")
48             caps.set_value("width", width)
49             caps.set_value("height", height)
50             video_track.set_restriction_caps(caps)
51
52         self.timeline.add_track(audio_track)
53         self.timeline.add_track(video_track)
54
55         self.layer = self.timeline.append_layer()
56
57         ges_pipeline = GES.Pipeline()
58         ges_pipeline.set_timeline(self.timeline)
59         self.player = Player(ges_pipeline)
60
61     def add_title_clip(self, text, start_time, duration):
62         title_clip = GES.TitleClip()
63         title_clip.set_start(start_time * Gst.SECOND)
64         title_clip.set_duration(duration * Gst.SECOND)
65         self.layer.add_clip(title_clip)
66
67         # Now that the clip is inserted in the timeline, it has a source which
68         # can be used to set its properties. (comment taken from Pitivi)
69         title_source = title_clip.find_track_element(None, GES.TitleSource)
70         title_source.set_child_property("text", text)
71         title_source.set_child_property("background", TITLE_BACKGROUND)
72         title_source.set_child_property("color", TITLE_COLOR)
73         title_source.set_child_property("outline-color", TITLE_OUTLINE_COLOR)
74         title_source.set_child_property("font-desc", TITLE_FONT_DESC)
75         title_source.set_child_property("halignment", GES.TextVAlign.ABSOLUTE)
76         title_source.set_child_property("valignment", GES.TextHAlign.ABSOLUTE)
77
78     def add_clip(self, clip_path, start_time, duration):
79         clip_uri = Gst.filename_to_uri(clip_path)
80         asset = GES.UriClipAsset.request_sync(clip_uri)
81         self.layer.add_asset(asset, start_time * Gst.SECOND, 0,
82                              duration * Gst.SECOND, GES.TrackType.UNKNOWN)
83
84     def add_layer_clip(self, clip_path, start_time, duration):
85         """Add a clip on its own layer"""
86         clip_uri = Gst.filename_to_uri(clip_path)
87         asset = GES.UriClipAsset.request_sync(clip_uri)
88         new_layer = self.timeline.append_layer()
89         new_layer.add_asset(asset, start_time * Gst.SECOND, 0,
90                             duration * Gst.SECOND, GES.TrackType.UNKNOWN)
91
92     def play(self):
93         self.timeline.commit()
94         self.player.play()
95
96     def stop(self):
97         self.player.stop()
98
99     def save(self, path):
100         uri = Gst.filename_to_uri(path)
101         self.project.save(self.timeline, uri, None, False)