OpenShot Video Editor  2.0.0
timeline.py
Go to the documentation of this file.
1 ##
2 #
3 # @file
4 # @brief This file contains a timeline object, which listens for updates and syncs a libopenshot timeline object
5 # @author Jonathan Thomas <jonathan@openshot.org>
6 #
7 # @section LICENSE
8 #
9 # Copyright (c) 2008-2018 OpenShot Studios, LLC
10 # (http://www.openshotstudios.com). This file is part of
11 # OpenShot Video Editor (http://www.openshot.org), an open-source project
12 # dedicated to delivering high quality video editing and animation solutions
13 # to the world.
14 #
15 # OpenShot Video Editor is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation, either version 3 of the License, or
18 # (at your option) any later version.
19 #
20 # OpenShot Video Editor is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License
26 # along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
27 #
28 
29 import time
30 import openshot # Python module for libopenshot (required video editing module installed separately)
31 
32 from classes.updates import UpdateInterface
33 from classes.logger import log
34 from classes.app import get_app
35 from classes import settings
36 
37 
38 ##
39 # This class syncs changes from the timeline to libopenshot
40 class TimelineSync(UpdateInterface):
41 
42  def __init__(self, window):
43  self.app = get_app()
44  self.window = window
45  project = self.app.project
47 
48  # Get some settings from the project
49  fps = project.get(["fps"])
50  width = project.get(["width"])
51  height = project.get(["height"])
52  sample_rate = project.get(["sample_rate"])
53  channels = project.get(["channels"])
54  channel_layout = project.get(["channel_layout"])
55 
56  # Create an instance of a libopenshot Timeline object
57  self.timeline = openshot.Timeline(width, height, openshot.Fraction(fps["num"], fps["den"]), sample_rate, channels,
58  channel_layout)
59  self.timeline.info.channel_layout = channel_layout
60  self.timeline.info.has_audio = True
61  self.timeline.info.has_video = True
62  self.timeline.info.video_length = 99999
63  self.timeline.info.duration = 999.99
64  self.timeline.info.sample_rate = sample_rate
65  self.timeline.info.channels = channels
66 
67  # Open the timeline reader
68  self.timeline.Open()
69 
70  # Add self as listener to project data updates (at the beginning of the list)
71  # This listener will receive events before others.
72  self.app.updates.add_listener(self, 0)
73 
74  # Connect to signal
75  self.window.MaxSizeChanged.connect(self.MaxSizeChangedCB)
76 
77  ##
78  # This method is invoked by the UpdateManager each time a change happens (i.e UpdateInterface)
79  def changed(self, action):
80 
81  # Ignore changes that don't affect libopenshot
82  if len(action.key) >= 1 and action.key[0].lower() in ["files", "history", "markers", "layers", "export_path", "import_path", "scale"]:
83  return
84 
85  elif len(action.key) >= 1 and action.key[0].lower() in ["profile"]:
86 
87  # The timeline's profile changed, so update all clips
88  self.timeline.ApplyMapperToClips()
89  return
90 
91  # Pass the change to the libopenshot timeline
92  try:
93  if action.type == "load":
94  # This JSON is initially loaded to libopenshot to update the timeline
95  self.timeline.SetJson(action.json(only_value=True))
96  self.timeline.Open() # Re-Open the Timeline reader
97 
98  # The timeline's profile changed, so update all clips
99  self.timeline.ApplyMapperToClips()
100 
101  # Refresh current frame (since the entire timeline was updated)
102  self.window.refreshFrameSignal.emit()
103 
104  else:
105  # This JSON DIFF is passed to libopenshot to update the timeline
106  self.timeline.ApplyJsonDiff(action.json(is_array=True))
107 
108  except Exception as e:
109  log.info("Error applying JSON to timeline object in libopenshot: %s. %s" % (e, action.json(is_array=True)))
110 
111  ##
112  # Callback for max sized change (i.e. max size of video widget)
113  def MaxSizeChangedCB(self, new_size):
114  while not self.window.initialized:
115  log.info('Waiting for main window to initialize before calling SetMaxSize')
116  time.sleep(0.5)
117 
118  log.info("Adjusting max size of preview image: %s" % new_size)
119 
120  # Clear timeline preview cache (since our video size has changed)
121  self.timeline.ClearAllCache()
122 
123  # Set new max video size (Based on preview widget size)
124  self.timeline.SetMaxSize(new_size.width(), new_size.height())
def get_app()
Returns the current QApplication instance of OpenShot.
Definition: app.py:55
This class syncs changes from the timeline to libopenshot.
Definition: timeline.py:40
def __init__(self, window)
Definition: timeline.py:42
def MaxSizeChangedCB(self, new_size)
Callback for max sized change (i.e.
Definition: timeline.py:113
def get_settings()
Get the current QApplication&#39;s settings instance.
Definition: settings.py:44
def changed(self, action)
This method is invoked by the UpdateManager each time a change happens (i.e UpdateInterface) ...
Definition: timeline.py:79