Changes of Revision 12

flowblade.changes Changed
x
 
1
@@ -1,7 +1,7 @@
2
 -------------------------------------------------------------------
3
 Mon Mar  3 03:03:03 UTC 2025 - olaf@aepfle.de
4
 
5
-- Update to 2.18.1
6
+- Update to 2.20
7
 
8
 -------------------------------------------------------------------
9
 Sun Apr  1 18:22:22 UTC 2018 - avvissu@yandex.by
10
flowblade.spec Changed
10
 
1
@@ -17,7 +17,7 @@
2
 
3
 
4
 Name:           flowblade
5
-Version:        2.18.1
6
+Version:        2.20
7
 Release:        0
8
 Summary:        Multitrack non-linear video editor
9
 License:        GPL-3.0-only
10
_service Changed
10
 
1
@@ -1,7 +1,7 @@
2
 <services>
3
    <service name="obs_scm">
4
        <param name="filename">flowblade</param>
5
-       <param name="revision">8bede966fa66c526ec97d35254cca75704799e58</param>
6
+       <param name="revision">cce3d674b796f5cc2ccaf3c40611faf3b6b4d74e</param>
7
        <param name="scm">git</param>
8
        <param name="submodules">disable</param>
9
        <param name="url">https://github.com/jliljebl/flowblade.git</param>
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en Deleted
2
 
1
-(directory)
2
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/advanced.html Deleted
201
 
1
@@ -1,1035 +0,0 @@
2
-<!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Advanced Editing</title>
6
-  <link rel="stylesheet" href="style.css">
7
-<script src="toc.js" type="text/javascript"></script>
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png">
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div id="advtoc">
20
-<div class="subject-header">Advanced Editing Features</div>
21
-</div>
22
-
23
-<div id="toc"></div>
24
-
25
-<h2>1. Advanced Project Actions </h2>
26
-
27
-
28
-<h3>Combining Sequences</h3>
29
-<p>
30
-It is possible to import full contents of another Sequence into Sequence currently being edited.
31
-</p>
32
-
33
-<ol>
34
-<li> Select <b>Sequence->Import Another Sequence into this Sequence...</b></li>
35
-<li> Select Import action.</li>
36
-<ul>
37
-<li> <b>Append Sequence</b> adds imported Sequence at the end of current Sequence</li>
38
-<li> <b>Insert Sequence at Playhead Position</b> creates a cut at playhead position and inserts imported Sequences at that position</li>
39
-</ul>
40
-<li> Select a Sequence to Import</li>
41
-<ul>
42
-<li> <b>Note that you obviously need at least two Sequences to exist to do any import actions.</b></li>
43
-</ul>
44
-<li> Press <b>Import</b> button to execute import.</li>
45
-</ol>
46
-
47
-<h3>Split part of Sequence to new Sequence</h3>
48
-
49
-<ol>
50
-<li> Select <b>Sequence->Split to new Sequence at Playhead position</b></li>
51
-<li> After confirmation dialog the a new Sequence with contents of source Sequence after playhead position will be created and made active.</li>
52
-</ol>
53
-
54
-<h3>Importing Media from another Project</h3>
55
-
56
-<p>
57
-You can import Media Items from another Project.
58
-</p>
59
-
60
-<ol>
61
-<li> Select <b>Project->Import Media From Project...</b></li>
62
-<li> Select a Project file from file system.</li>
63
-<li> Media items that are not present in current Project will be opened in the current bin. Note that it takes a few seconds to load the project before new Media Items begin to appear.</li>
64
-</ol>
65
-
66
-
67
-
68
-<h2>2. Timeline Audio Syncing</h2>
69
-
70
-<p>
71
-You can make a clip to move to a position in timeline in which its audio is in sync with audio of another clip on timeline.
72
-</p>
73
-
74
-<p>
75
-This enables you to do simplified version of multicam editing on the timeline.
76
-</p>
77
-
78
-<ol>
79
-<li> Open context menu with <b>Right Mouse</b> on Clip you wish to sync with some other clip.</li>
80
-<li> Select menu item <b>Audio->Select Clip to Audio Sync With...</b>. The cursor changes to a targeting cross.</li>
81
-<li> Click on Clip you wish to audio sync with.</li>
82
-<li> A dialog opens giving info on the sync action that is to be done to sync clips.</li>
83
-<li> Press <b>Do Audio Sync Move Edit</b> button to do the syncing edit.</li>
84
-<li> It is usually a good idea to mute one of the synched clips</li>
85
-</ol>
86
-
87
-<div class="note">
88
-Audio syncing looks for best mathematical match between two audio waveforms, so <b>audio syncing non-matching audio will produce random results.</b>
89
-</div>
90
-
91
-
92
-<h2>3. Slow / Fast Motion and Reverse</h2>
93
-
94
-<p>
95
-In Flowblade there are two ways to do motion effects:
96
-</p>
97
-<ul>
98
-<li> Changing Clip Speed and direction in Timeline</li>
99
-<li> Creating new New Media Items in Bins</li>
100
-</ul>
101
-
102
-
103
-<h3> Changing Timeline Clip Speed and direction</h3>
104
-<h4> Creating Slow / Fast Motion Clips </h4>
105
-<ol>
106
-<li> Right click on a Timeline Clip File and select <b>Slow Motion -> Slow / Fast</b> from popup menu.</li>
107
-<li> Edit parameters for the new motion Clip</li>
108
-<ul>
109
-<li> Set speed</li>
110
-<li> Set encoding and quality</li>
111
-<li> Select render range, either:</li>
112
-<ul>
113
-<li> Current Clip Content</li>
114
-<li> Full Media</li>
115
-</ul>
116
-</ul>
117
-<li> Click <b>Render</b> button to create a new motion Timeline Clip.</li>
118
-</ol>
119
-
120
-<h4> Creating Reverse Motion Clips</h4>
121
-<ol>
122
-<li> Right click on a Timeline Clip File and select <b>Slow Motion -> Reverse</b> from popup menu.</li>
123
-<li> Edit parameters for the new motion Clip</li>
124
-<ul>
125
-<li> Set speed</li>
126
-<li> Set encoding and quality</li>
127
-<li> Select render range, either:</li>
128
-<ul>
129
-<li> Current Clip Content</li>
130
-<li> Full Media</li>
131
-</ul>
132
-</ul>
133
-<li> Click <b>Render</b> button to create a new reverse Timeline Clip.</li>
134
-</ol>
135
-
136
-<h3> Creating Motion Media Items </h3>
137
-<h4> Creating Slow / Fast Media Items </h4>
138
-<ol>
139
-<li> Right click on a Media File and select <b>Render Slow / Fast Motion File</b> from menu</li>
140
-<li>Edit parameters for the new motion Clip
141
-<ul>
142
-<li> Set speed</li>
143
-<li> Give name and location for motion Clip </li>
144
-<li> Select rendering parameters for motion Clip. It is probably a good idea to use a <b>lossless format</b> here to avoid any generational quality losses.</li>
145
-<li> Select render range, either:</li>
146
-<ul>
147
-<li> Full Source Clip</li>
148
-<li> From Source Clip Mark In to Mark Out</li>
149
-</ul>
150
-</ul>
151
-<li> Click <b>Render</b> button to create a new motion Media Item</li>
152
-</ol>
153
-
154
-<h4> Creating Reverse Media Items </h4>
155
-<ol>
156
-<li> Right click on a Media File and select <b>Render Reverse Motion File</b> from menu</li>
157
-<li>Edit parameters for the new motion Clip
158
-<ul>
159
-<li> Set speed</li>
160
-<li> Give name and location for reverse Clip </li>
161
-<li> Select rendering parameters for reverse Clip. It is probably a good idea to use a <b>lossless format</b> here to avoid any generational quality losses.</li>
162
-<li> Select render range, either:</li>
163
-<ul>
164
-<li> Full Source Clip</li>
165
-<li> From Source Clip Mark In to Mark Out</li>
166
-</ul>
167
-</ul>
168
-<li> Click <b>Render</b> button to create a new reverse Media Item</li>
169
-</ol>
170
-
171
-
172
-<h2>4. Synched Audio Splits and Clip Parenting</h2>
173
-
174
-<p>
175
-In Flowblade Movie Editor you can <b>set a clip's positions to follow another clip's positions</b> on request.
176
-</p>
177
-
178
-<h3>Main points</h3>
179
-<ul>
180
-<li>Sync relations are between two clips set up by selecting a <b>Sync Parent Clip</b> for a <b>Sync Child Clip</b>.</li>
181
-<li>Splitting audio with <b>Audio Split Synched </b> creates sync relation between original clip and split audio clip.</li>
182
-<li><b>Only clips on track V1 can be Sync Parent Clips</b>. This is done to encourage edit style in which the main body of the Sequence is on track V1 and composites and audio split edits are done relative to the clip sequence on track V1.</li>
183
-<li><b>Sync feature helps preserve earlier work</b> an multitrack composites and audio split edits when clips are no longer in correct positions relative to each other, because of edits elsewhere on the Sequence.</li>
184
-<li><b>Resyncs are only done on request</b> to avoid jumping of clips on the timeline while editing. Explicit resyncs are also better from the point of view of avoiding side effects when doing edits.
185
-</li>
186
-</ul>
187
-
188
-<h3>4.1 Audio Split Syncing</h3>
189
-<ul>
190
-<li> Click <b>Right Mouse</b> on clip in track V1 and select  <b>Audio Edit->Select Sync Parent Clip...</b>.</li>
191
-<li> Now you e.g. can use <b>Multitrim</b> tool to create J or L audio edits.</li>
192
-<li> Sync State Box appears on the Sync Child Clip.</li>
193
-<ul>
194
-<li> Green means that clip is in sync with parent.</li>
195
-<li> Red means that clip is NOT in sync with parent.</li>
196
-<li> Displayed number gives info on how many frames clip positions are away from being synched.</li>
197
-</ul>
198
-</ul>
199
-<h4>Resyncing Sync Child Clips</h4>
200
-<ul>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/all_comp.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/basic_editing.html Deleted
201
 
1
@@ -1,329 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Basic Editing</title>
6
-  <link rel="stylesheet" href="style.css">
7
-</head>
8
-
9
-<body>
10
-
11
-<div id="content">
12
-<img src="header_text_5.png" >
13
-
14
-<script src="tocgen.js"></script>
15
-
16
-<div class="subject-header">Basic Editing</div>
17
-
18
-<p>
19
-This section describes the minimal workflow for making a movie using only a single track.
20
-</p>
21
-<div id="toc"></div>
22
-
23
-<div id="toccontent">
24
-
25
-<h3>Creating a New Project</h3>
26
-<p>
27
-Flowblade Movie Editor saves work in project files.
28
-</p>
29
-<p>
30
-To create a new Project:
31
-</p>
32
-<ul>
33
-<li> <b>Menu:</b> Select <b>File -> New</b> from menu.</li>
34
-<li> <b>Keyboard Shortcut:</b> Press <b>Control+N</b>.</li>
35
-</ul>
36
-<p>
37
-A project contains:
38
-</p>
39
- <ul>
40
-<li> one or more Sequences of edited media</li>
41
-<li> a collection of Media Files stored in Bins.</li>
42
-</ul>
43
-<p>
44
-There are two parameters that can be selected for a new project:
45
-</p>
46
-<ul style="list-style-type:none">
47
-<li> <b>Project Profile</b> Project Profile determines frame rate per second, image size in pixels and pixel aspect ratio.</li>
48
-<li> <b>Tracks count</b> Select the number of video and audio tracks that are used in the project. This can be changed later, but the operation destroys the Undo / Redo stack and all the Timeline Clips that do not fit in the newly created version of the Sequence.</li>
49
-<li> <b>Data Store</b> Thumbnails, Generator and Rendered Transitions, stabilizing and motion tracking data, proxy files etc. are stored here in a <b>Data Store</b>, see chapter: <a href="datastores.html">Data Stores</a>.
50
-
51
-
52
-</ul>
53
-
54
-<div class="note">
55
-Flowblade Movie Editor handles image data internally as YUV420 frames, so the encoding associated with a given profile has no affect on quality before rendering.
56
-</div>
57
-<div class="note">
58
-For <b>best possible quality</b> the <b>input material, Project Profile and Rendering Profile</b> should <b>all have the same pixel dimensions</b> and pixel aspect ratio.
59
-</div>
60
-
61
-<h3>Adding and removing new Sequences</h3>
62
-<p>
63
-A Project contains one or more Sequences. The term Sequence refers to the full contents of the timeline forming a program, a movie.
64
-</p>
65
-
66
-<p>
67
-For complex projects it is sometimes best to use multiple sequences for creating and managing different parts of the finished product.
68
-</p>
69
-
70
-<p>
71
-<b>Adding Sequences:</b>
72
-</p>
73
-<ul>
74
-<li> <b>Default layout:</b> Press <b>Right Mouse</b> popup menu on Sequences area and select menu item <b>Add New Sequence</b>..</li>
75
-<li> <b>Small screen layout:</b> Press <b>Right Mouse</b> popup menu in the <b>Project</b> tab <b>Sequences</b> area and select menu item <b>Add New Sequence</b>.</li>
76
-<li> Or select  <b>Project -> Sequence -> Add New Sequence</b> from application menu.</li>
77
-</ul>
78
-
79
-
80
-<p>
81
-<b>Deleting Sequences</b> can be done with menu actions accessed in the same places.
82
-</p>
83
-
84
-<div class="note">
85
-<p>
86
-When creating a new Sequence, you can choose the number of Tracks in the Sequence. This can be changed later, but the operation destroys the Undo / Redo stack and all the Timeline Clips that do not fit in the newly created version of the Sequence.
87
-</p>
88
-</div>
89
-
90
-<h3>Working with Media Files</h3>
91
-
92
-<p>
93
-Flowblade Movie Editor holds files in <b>Media</b> tab. Files are listed in unnamed table that displays contents of the currently selected Bin. Bins are listed in the <b>Bins</b> table.
94
-</p>
95
-
96
-<p>
97
-<b>Opening Media Files:</b>
98
-</p>
99
-
100
-<ol>
101
-<li> Press <b>Right Mouse</b> on <b>Media</b> tab empty area and select menu item <b>Add Video, Audio or Image...</b>.
102
-<li> Or select  <b>Project -> Add Video, Audio or Image...</b> from application menu.
103
-<li> Use dialog to find and select files.</li>
104
-<li> Files are displayed as thumbnails.</li>
105
-<li> Note that creating thumbnails for opened files will take some time.</li>
106
-</ol>
107
-
108
-<div class="note">
109
-<h3 style="margin-top:10px">Project Media: Absolute and relative paths</h3>
110
-<ul>
111
-<li> Flowblade <b>saves references</b> to media files used in a project as <b>absolute paths</b>.</li>
112
-<li> If a media is <b>not found on load</b>, Flowblade attempts to find a media file with the same name in subfolders relative to the project file.</li>
113
-<li> If all media used by a project is saved in subfolders relative to project file, <b>project file and media can moved as a unit</b> and the project will load successfully after data is copied to a different place</li>
114
-<li> <b>Rendered files</b> like transitions are saved by default in a <b>Data Store</b>, see chapter: <a href="datastores.html">Data Stores</a>.</li>
115
-<li> <b>Load order</b> between absolute and relative paths can be set in preferences window</li>
116
-<li> <b>Media Relinker</b> tool can be used to fix problems that may occur </li>
117
-</ul>
118
-</div>
119
-
120
-<h3>Working with Bins</h3>
121
-
122
-<p>
123
-In video editing a bin is a named location for storing media. The term is used in Avid and was earlier used by film editors.
124
-</p>
125
-
126
-<p>
127
-    <b>Adding a Bin:</b>
128
-<p>
129
-<ul>
130
-<li> <b>Default layout:</b> Press <b>Right Mouse</b> on Bin area to launch a popup menu and select menu item <b>Add Bin</b>.</li>
131
-<li> <b>Small screen layout:</b> Press <b>Right Mouse</b> in the <b>Media</b> tab <b>Bins</b> panel to launch a popup menu and select menu item <b>Add Bin</b>.</li>
132
-<li> Or select  <b>Project -> Bin -> Add Bin</b> from application menu.</li>
133
-</ul>
134
-
135
-<p><b>Deleting a Bin</b>: Delete actions can be accessed from the same places as above.</p>
136
-<p><b>Renaming a Bin</b>: Click on the Bin name, type new name and press <b>Enter</b>.</p>
137
-<p><b>Moving files to another Bin:</b></p>
138
-<ul>
139
-<li> Select and drag files on top of the Bin you wish to move the files into.</li>
140
-<li> Select files and open <b>Hamburger menu</b> in <b>Media</b> panel and select menu item <b>Move Selected media to Bin</b> and then the menu item with the Bins name.</li>
141
-</ul>
142
-<div class="tabbed">
143
-
144
-</div>
145
-
146
-<h4>Filtering Bin View</h4>
147
-<p>
148
-    Bins can be mede to display only subset of media items thei contain. Press on filtering button in <b>Media Panel</b> bottom row next <b>Hamburger</b> and <b>columns</b> buttons.
149
-<p>
150
-    <ul>
151
-    <li> <b>Filtering by media type.</b> Select one of options <i>All Files, Video Files Audio Files, Graphics Files, Image Sequences, Pattern Producers, Unused Files</i>.</li>
152
-    <li> <b>Filtering by ratings.</b> Select one of options in submenu <i>Ratings</i>, either <i>Show All Ratings, Show Favorites, Hide bad</i>. Each media item can be given a rating in context popover submenu <i>Rating</i>.</li>
153
-    </ul>
154
-    
155
-<h3>Using Timeline</h3>
156
-
157
-<h4>Scrolling Timeline</h4>
158
-<ul>
159
-<li> Press and Drag <b>Scrollbar</b> below Timeline</li>
160
-<li> Scroll <b>Mouse Middle</b> button + <b>CTRL</b> key while on top of Timeline</li>
161
-</ul>
162
-
163
-<h4>Zooming Timeline</h4>
164
-<ul>
165
-<li> Click <b>Zoom In</b>, <b>Zoom Out</b> or <b>Zoom Length</b> buttons.</li>
166
-<li> Scroll <b>Mouse Middle</b> button on top of Timeline </li>
167
-</ul>
168
-
169
-<h4>Changing Current Frame</h4>
170
-<ul>
171
-<li> Drag with <b>Right Mouse</b> button starting from  an empty space in the Timeline.</li>
172
-<li> Drag with <b>Left Mouse</b> button on the Frame Scale.</li>
173
-<li> Drag with <b>Left Mouse</b> on the Monitor Position Bar.</li>
174
-<li> Click <b>Left Arrow</b> key or <b>Right Arrow</b> key to move to next or previous frame.</li>
175
-<li> Click <b>Up Arrow</b> key or <b>Down Arrow</b> key to move to next or previous cut on topmost active track.</li>
176
-<li> Click <b>Next</b> or <b>Prev</b> button in Monitor Buttons area to move to next or previous frame.</li>
177
-</ul>
178
-
179
-<h4>Changing Current Frame when Clip is displayed on Monitor</h4>
180
-<ul>
181
-<li> Drag with <b>Left Mouse</b> on the Monitor Position Bar.</li>
182
-<li> Click <b>Left Arrow</b> key or <b>Right Arrow</b> key to move to next or previous frame.</li>
183
-<li> Click <b>Up Arrow</b> key or <b>Down Arrow</b> key to move to next or previous of the following: Mark In/Mark Out/Start/End</li>
184
-<li> Click <b>Next</b> or <b>Prev</b> button in Monitor Buttons area to move to next or previous frame.</li>
185
-</ul>
186
-
187
-<h4>Switching between Timeline and Clip Display</h4>
188
-<ul>
189
-<li> Click buttons with icons representing sequence or single clip in Monitor Buttons area.</li>
190
-<li> Drag Media File on top of <b>Monitor</b> to display Clip.</li>
191
-</ul>
192
-
193
-<h4>Setting Active Tracks</h4>
194
-<ul>
195
-<li> Click <b>Track Active Switch</b> on the right side of Tracks Column area. Topmost  <b>Track Active Switch</b> displays arrow pointing downwards indicating that <b>Insert From Monitor</b> and other buttons place clips on that track.</li>
196
-</ul>
197
-
198
-<div class="note">
199
-<h4>Effects of Track Active State</h4>
200
-<ul>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/compositor.html Deleted
201
 
1
@@ -1,221 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Creating Composited Images</title>
6
-  <link rel="stylesheet" href="style.css">
7
-</head>
8
-
9
-<body>
10
-
11
-<div id="content">
12
-<img src="header_text_5.png" >
13
-
14
-<script src="tocgen.js"></script>
15
-
16
-<div id="toccontent">
17
-
18
-<div class="subject-header">Creating Composited Images</div>
19
-
20
-<p>
21
-Flowblade Movie Editor uses Compositors to mix images from two different tracks.
22
-</p>
23
-
24
-<div id="toc"></div>
25
-
26
-<h3>Compositing Modes</h3>
27
-<p>
28
-The way that Compositors work is defined by a Compositing Mode. Users can select Compositing Mode to suit their preference or editing needs of a particular Sequence.
29
-</p>
30
-<p>
31
-<b>To set Compositing Mode</b> for a Sequence select it from <b><i>Sequence -> Compositing Mode</i></b> sub menu.
32
-</p>
33
-
34
-<h4>Standard Full Track</h4>
35
-<p>
36
-This is the most simple and easiest to use Compositing Mode. No Compositors are needed. Fade In/Outs, Wipes and transforms are created with Filters. Some compositing functionality is not available. It is not possible to create node tree compositions
37
-</p>
38
-<h4>Compositor Free Move</h4>
39
-<p>
40
-This is the most powerful and complex Compositing Mode. Users can set destination tracks and positions of Compositors freely and create node tree compositions if needed.
41
-</p>
42
-
43
-<h2>Standard Full Track Compositing Mode</h2>
44
-<p>
45
-Compositing in Standard Full Track mode is similar to using layers in applications like Gimp and Photoshop.
46
-
47
-
48
-<h3>Workflow</h3>
49
-<h4>Creating layered compositions</h4>
50
-
51
-<ul>
52
-<li> Add Clips on Timeline on different tracks.</li>
53
-<li> Images are composited in bottom to top order.</li>
54
-<li> Images with alpha channel are composited with transparency as defined by alpha channel.</li>
55
-<li> Use Filters to create Dissolves, Wipes, Blends and affine transforms.</li>
56
-</ul>
57
-
58
-<h4>Dissolves</h4>
59
-<ul>
60
-<li> Add Clips on Timeline on different tracks.</li>
61
-<li> Add <b>Fade In</b> or <b>Fade Out</b> Filters to Clip on the upper track to create Dissolves with Clip on the lower track.</li>
62
-<li> <b>Fade In</b> and <b>Fade Out</b> Filters are in <b>Fade</b> Filter category.</li>
63
-</ul>
64
-
65
-<h4>Dissolves - Rendered Transition</h4>
66
-
67
-<ul>
68
-<li> Select two Clips on the same track.</li>
69
-<li> Press <b>Add Rendered Transition</b> button in middlebar.</li>
70
-<li> Give length of rendered transition and press <b>Render</b> button.</li>
71
-</ul>
72
-
73
-<h4>Blends</h4>
74
-<ul>
75
-<li> Add Clips on Timeline on different tracks.</li>
76
-<li> Add <b>Blend</b> Filter to Clip on the upper track to control blend mode used when compositing image on top of the Clip on the lower track.</li>
77
-<li> <b>Blend</b> Filters can be combined with other Filters to create compositions as wished.</li>
78
-<li> <b>Blend</b> Filters are in <b>Blend</b> Filter category.</li>
79
-</ul>
80
-
81
-<h4>Wipes</h4>
82
-<ul>
83
-<li> Add Clips on Timeline on different tracks.</li>
84
-<li> Add <b>Wipe</b> Filters to the top Clip to create wipe transitions.</li>
85
-<li> <b>Wipe</b> Filters are in <b>Blend</b> Filter category.</li>
86
-</ul>
87
-
88
-<h4>Alpha channel manipulation: Keys, Rotomasks etc.</h4>
89
-<ul>
90
-<li> Add Clips on Timeline on different tracks.</li>
91
-<li> Use appropriate Filters in <b>Alpha</b> Filter category to create more complex compositing opearations such as color keys, shaped masks or animated masks.</li>
92
-</ul>
93
-
94
-<h4>Transforms</h4>
95
-<ul>
96
-<li> Add Clips on Timeline on different tracks.</li>
97
-<li> Add <b>Position Scale</b> or <b>Position Scale Rotation</b> Filters to the top Clip to move, rotate and scale image before it is composited on lower track.</li>
98
-<li> These Filters are in <b>Transform</b> Filter category.</li>
99
-</ul>
100
-
101
-<h2>Compositor Free Move Compositing mode</h2>
102
-<p>
103
-In this modes Compositors have a Source track and a Destination track.</p>
104
-</p>
105
-<p>
106
-On the Timeline a Compositor is displayed as a rectangular object on top of two tracks. Source track is always the one above Compositor, but Destination track may be any of the tracks below it.
107
-</p>
108
-<p>
109
-Parameters defining the resulting image are edited in the <b>Edit</b> tab.
110
-</p>
111
-
112
-<h3>Workflow</h3>
113
-<p>
114
-By combining multiple tracks and multiple Compositors complex composite images can be achieved.
115
-</p>
116
-<ol>
117
-<li>Creating a Compositor
118
-<ul>
119
-<li> Click <b>Right Mouse</b> on any clip on tracks from V5 to V2 and select for example <b>Add Compositor -> Dissolve</b> or <b>Add Blender -> Softlight</b> from popupmenu to create a new Compositor.</li>
120
-</ul>
121
-<li>Trimmimg or Moving a Compositor</li>
122
-<ul>
123
-<li> To trim Compositor start and end points: Press and drag <b>Left Mouse</b> near either end of Compositor on Timeline.</li>
124
-<li> To move Compositor: Press and drag <b>Left Mouse</b> in the middle of Compositor on Timeline.</li>
125
-</ul>
126
-<li>Editing Compositor Parameters in Compositors Tab</li>
127
-<ul>
128
-<li> Double click Compositor with <b>Left Mouse</b>.</li>
129
-<li> Click <b>Right Mouse</b> on any Compositor and select Open In Compositor Editor</li>
130
-<li> Edit parameters using value editors.</li>
131
-</ul>
132
-<li>Deleting Compositor</li>
133
-<ul>
134
-<li> Click <b>Left Mouse</b> on any Compositor to select it and press <b>Delete</b> key.</li>
135
-</ul>
136
-</ol>
137
-
138
-<h3>Compositor are executed from top to bottom in Top Down Compositing modes</h3>
139
-In Flowblade Movie Editor <b>the order of rendering is top-to-bottom</b>,
140
-instead of bottom-to-top like in Gimp or Photoshop.
141
-
142
-When attempting certain type of multilayer composites this yields results that seem unintuitive,
143
-unless the user is aware of rendering order of Compositors.
144
-
145
-<h4>Rendering A Composited Frame</h4>
146
-<ol>
147
-<li>For each frame it is checked if there is a Compositor covering this frame on the top most track.</li>
148
-<li>If such Compositor is found, do composite on Destination track.</li>
149
-<li>Frame on Destination track is now altered and if that frame is used as source the altered version is used</li>
150
-<li>Check if frame on next track below has compositor and if Compositor is found render the composite image</li>
151
-<li>This is done for each track.</li>
152
-<li>Output image on is from the topmost track that has media on the frame and does not have a compostor on the frame.</li>
153
-</ol>
154
-
155
-<h3>Using Filters</h3>
156
-<p> Exept for <b>Blend</b> Filter, all filters can used in the same way to achieve compositions as in <b>Standard Free Move</b> compositing mode.</p>
157
-
158
-<h3>EXAMPLE: Creating a 3-layer composite</h3>
159
-<p style="margin-bottom:45px" >
160
-In this example we demonstrate how top-to-bottom Compositor
161
-order affects compositing. We are trying to make word 'GO' appear on top of 2-color
162
-background made by combining red and blue Color Clips using 'Free Stripes' wipe.
163
-</p>
164
-<h4>Media Items and desired result</h4>
165
-<p>
166
-To make alpha transparency work the GO.PNG graphic has to composited using 'Dissolve'.
167
-</p>
168
-<p>
169
-<i><b>Clips: RED and BLUE Color Clips and GO.PNG graphic with alpha transparency</b></i>
170
-</p>
171
-<img src="comp_clips.png">
172
-
173
-<p>
174
-<i><b>Desired result</b></i>
175
-</p>
176
-
177
-<img style="margin-bottom:45px" src="correct_comp.png">
178
-
179
-<h4>Gimp/Photoshop style layer order yields wrong result</h4>
180
-<p>
181
-Here we have arranged clips on the tracks as we would arrange layers in Gimp.
182
-</p>
183
-<p>
184
-<i><b>Gimp style layer order</b></i>
185
-</p>
186
-<img src="wrong_timeline.png">
187
-
188
-<p>
189
-What happens here is that first 'GO.PNG' is composited on 'RED' Color Clip, and the resulting image is composited using 'Free Stripes' wipe on top of 'BLUE' Color Clip. We get the wrong result.
190
-</p>
191
-<p>
192
-<i><b>Wrong result</b></i>
193
-</p>
194
-<img  style="margin-bottom:45px" src="wrong_comp.png">
195
-<h4>Correct layer order when compositing order is top-to-bottom</h4>
196
-<p>
197
-Here we have arranged clips in correct order for the desired result.
198
-</p>
199
-<p>
200
-<i><b>Correct layer order</b></i>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/container_clips.html Deleted
134
 
1
@@ -1,132 +0,0 @@
2
-<!DOCTYPE html>
3
- 
4
-<html>
5
-<head>
6
-  <title>Container Clips</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png">
15
-
16
-<script src="tocgen.js"></script>
17
-
18
-<div id="toccontent">
19
-
20
-<div class="subject-header">Container Clips</div>
21
-
22
-
23
-
24
-<div id="toc"></div>
25
-
26
-<h2>Container Clips Concept</h2>
27
-<p>
28
-A <b>Container Clip</b> is a Media Item and the Timeline Clip made from it that has three items packed together as a single entity: <i>Program, Unrendered Media</i> and <i>Rendered Media</i>.
29
-</p>
30
-<h3>Components</h3>
31
-<ol>
32
-<li><b>Unrendered Media</b> This is what is displayed on timeline if container clip media is not rendered.</li>
33
-<li><b>Program</b> This data is used to render a media clip on timeline, sometimes using unrendered media as input.</li>
34
-<li><b>Rendered Media</b> This is what is displayed on timeline when Container Clip is rendered.</li>
35
-</ol>
36
-
37
-
38
-<h2>G'Mic Script Container Clips</h2>
39
-
40
-<h5>Components</h5>
41
-<p>
42
-<ul style="list-style-type:none">
43
-<li><b>Unrendered Media</b> Video Clip.</li>
44
-<li><b>Program</b> G'Mic script created and saved from G'Mic tool.</li>
45
-<li><b>Rendered Media</b> A clip rendered with G'mic effect.</li>
46
-</ul>
47
-</p>
48
-<p>
49
-<h5>Use Cases</h5>
50
-<ul>
51
-<li>Render G'Mic effects only on clip ranges used on timeline.</li>
52
-<li>Make easier to use single user defined G'Mic effect on multiple clips.</li>
53
-</ul>
54
-
55
-<h5> Creating G'Mic Script Container Clips</h5>
56
-
57
-<ol>
58
-<li>Open <b>G'Mic tool</b>.</li>
59
-<li>Create G'Mic effect script. See section on <b>G'Mic Effects</b> in Chapter <b>Tools</b>.</li>
60
-<li>Press <b>Save Script</b> button in bottom left corner and save effect.</li>
61
-<li>Select menu item <b>Project -> Create Contaniner Clip -> From G'Mic Script</b>.</li>
62
-<li>Select the script you saved and the clip that it will be applied on to create Container Clip.</li>
63
-</ol>
64
-
65
-
66
-<h2>Selection Container Clips</h2>
67
-<h5>Components</h5>
68
-<p>
69
-<ul style="list-style-type:none">
70
-<li><b>Unrendered Media</b> A MLT XML vdieo clip created from selection or sequence like Compound clips previously.</li>
71
-<li><b>Program</b> A MLT XML video clip created from selection or sequence like Compound clips previously. Here Program is the same as unrendered media.</li>
72
-<li><b>Rendered Media</b> Clip Rendered from MLT XML Clip.</li>
73
-</ul>
74
-</p>
75
-<h5>Use Cases</h5>
76
-
77
-<ul>
78
-<li>Make possible to create Media items from selections and full Sequences.</li>
79
-<li>Give better timeline performance for complex multitrack container clips by pre-rendering them on timeline.</li>
80
-</ul>
81
-
82
-<h5> Creating Selection Container Clip from Selection</h5>
83
-
84
-<ol>
85
-<li> Select 2 or more adjacent clips from a single track.</li>
86
-<li> Select <b>Project->Create Container Clip->From Selected Clips</b></li>
87
-<li> A new Media Item appears in the current Bin.</li>
88
-</ol>
89
-
90
-<h5> Creating Selection Container Clip from Sequence</h5>
91
-
92
-<ol>
93
-<li> Select <b>Project->Create Container Clip->From Current Sequence</b></li>
94
-<li> A new Media Item appears in the current Bin.</li>
95
-</ol>
96
-
97
-<h5> Creating audio synced Selection Container Clip from two Media Items</h5>
98
-
99
-<ol>
100
-<li> Select 2 Media Items in Media panel.</b>
101
-   <ul>
102
-   <li> The expected case is to select <b>1 Video and 1 Audio Clip</b>.</li>
103
-   <li> If you select <b>2 Video Clips</b> then which is used as video depends on selection order.</li>
104
-   <li> Audio from clip treated as video is muted.</li>
105
-   </ul>
106
-</li>
107
-<li> Select <b>Project->Create Compound Clip->Audio Sync Merge Clip From 2 Media Items</b></li>
108
-<li> If audio sync is successful a dialog appears. Give a name for the new Media Item in the dialog.</li>
109
-<li> A new Media Item appears in the current Bin.</li>
110
-</ol>
111
-
112
-<div class="note">
113
-Audio syncing looks for best mathemathical match between two audio waveforms, so <b>audio syncing non-matching audio will produce random results.</b>
114
-</div>
115
-
116
-<h2>Generator Container Clips</h2>
117
-<p>
118
-<b>Generators</b> are Container Clips too, see more info in chapter <a href="generatorsfluxity.html">Generators and Fluxity API</a>
119
-</p>
120
-
121
-<h2>Blender Project Container Clips</h2>
122
-<p><i>
123
-Feature was removed in release 2.10.
124
-</i></p>
125
-
126
-</div>
127
-
128
-</div>
129
-</div>
130
-
131
-</body>
132
-
133
-</html> 
134
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/edit_tools.html Deleted
201
 
1
@@ -1,251 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Timeline Edit Tools</title>
6
-  <link rel="stylesheet" href="style.css">
7
-  <META CHARSET="UTF-8">
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-
14
-<img src="header_text_5.png" >
15
-
16
-<script src="tocgen.js"></script>
17
-
18
-<div class="subject-header">Timeline Edit Tools</div>
19
-
20
-<p>
21
-Flowblade Movie Editor has 6 edit tools for doing timeline edits.
22
-</p>
23
-
24
-<div id="toccontent">
25
-<div id="toc"></div>
26
-
27
-<h2>Selecting Tools</h2>
28
-
29
-<p>
30
-Use <b>Tool Switcher</b> button drop menu or press key <b>1 - 6</b>  to pick a tool.
31
-</p>
32
-
33
-<p>
34
-It is also possible to use Tool Dock instead of <b>Tool Switcher</b> button by selecting <b>Dock</b> in <b>View->Edit Tool Selection Widget</b>.
35
-</p>
36
-
37
-
38
-<div class="note">
39
-<b>Use Keyboard Shortcuts!</b> It is much faster to use keys <b>1 - 6</b> to change tools. Note that keys 1-6 only change tools if timeline has keyboard focus. 
40
-</div>
41
-
42
-
43
-<h2>Move Tools</h2>
44
-
45
-
46
-<a id="overwrite"></a>
47
-<h3>Move</h3>
48
-
49
-<p>
50
-Lift out one or more clips and insert them at any point to overwrite on any track.
51
-</p>
52
-
53
-<ol>
54
-<li>Select clip
55
-   <ul>
56
-   <li><b> Click </b>Left Mouse on a clip.</li>
57
-   </ul>
58
-</li>
59
-<li>Select other end of clip range if moving multiple clips
60
-   <ul>
61
-   <li> Click <b>CTRL+Left Mouse</b> on the clip you wish to be the other end of move clip range.</li>
62
-   </ul>
63
-</li>
64
-<li>Drag Clip(s) to new position
65
-   <ul>
66
-   <li> Press <b>Left Mouse</b> on a selected clip and drag clip/s to a new position.</li>
67
-   <li> Red shadow clips show overwrite area.</li>
68
-   <li> You can also move clips to a different track.</li>
69
-   </ul>
70
-</li>
71
-</ol>
72
-
73
-<p>
74
-Drag clip ends to change clip length.
75
-</p>
76
-
77
-<ol>
78
-<li>Place cursor near clip end
79
-   <ul>
80
-   <li>When cursor changes to horizontal arrow with vertical bar you can start clip end drag edit.</li>
81
-   </ul>
82
-</li>
83
-<li>Drag clip end with <b>Left Mouse</b>.
84
-   <ul>
85
-   <li> Added clip length will perform overwrite on blanks and empty space</li>
86
-   </ul>
87
-   <ul>
88
-   <li> Added clip length will perform insert on other clips</li>
89
-   </ul>
90
-   <ul>
91
-   <li> Decreased clip length will perform splice out.</li>
92
-   </ul>
93
-</li>
94
-</ol> 
95
-
96
-<p>
97
-Select and overwrite move all Timeline items contained in a box selection.
98
-</p>
99
-
100
-<ol>
101
-<li>Select an area on Timeline by dragging a box selection with <b>Left Mouse</b> around all items you wish to move and release mouse button.</li>
102
-<li>Press <b>Left Mouse</b> inside the box selection and drag the box into new position on timeline and release mouse.</li>
103
-<li>Box contents are overwritten on new position and Compositors are moved.</li>
104
-
105
-</ol>
106
-
107
-
108
-<a id="insert"></a>
109
-<h3>Insert</h3>
110
-
111
-<p>
112
-Splice out one or more clips and insert them at desired cut on any track.
113
-</p>
114
-
115
-<ol>
116
-<li>Select clip
117
-   <ul>
118
-   <li> Click <b>Left Mouse</b> on a clip.</li>
119
-   </ul>
120
-</li>
121
-<li>Select other end of clip range if moving multiple clips
122
-   <ul>
123
-   <li> Click <b>CTRL+Left Mouse</b> on the clip you wish to be the other end of move clip range.</li>
124
-   </ul>
125
-</li>
126
-<li>Drag Clip(s) to new position
127
-   <ul>
128
-   <li> Press <b>Left Mouse</b> on a selected clip and drag clip/s to a new position.</li>
129
-   <li> Yellow arrow displays insert point.</li>
130
-   <li> You can also move clips to a different track.</li>
131
-   </ul>
132
-</li>
133
-</ol>
134
-
135
-<p>
136
-Drag clip ends to change clip length.
137
-</p>
138
-
139
-<ol>
140
-<li>Place cursor near clip end 
141
-   <ul>
142
-   <li>When cursor changes to horizontal arrow with vertical bar you can start clip end drag edit.</li>
143
-   </ul>
144
-</li>
145
-<li>Drag clip end with <b>Left Mouse</b>.
146
-   <ul>
147
-   <li> Added clip length will perform overwrite on blanks and empty space</li>
148
-   </ul>
149
-   <ul>
150
-   <li> Added clip length will perform insert on other clips</li>
151
-   </ul>
152
-   <ul>
153
-   <li> Decreased clip length will perform splice out.</li>
154
-   </ul>
155
-</li>
156
-
157
-</ol> 
158
-
159
-
160
-
161
-
162
-
163
-
164
-<a id="spacer"></a>
165
-<h3>Spacer</h3>
166
-
167
-<p>Move all Timeline items after pressed frame on all tracks or on a single track</p>
168
-<ol>
169
-<li>Select a clip on Timeline and move it and all items to the right of it
170
-   <ul>
171
-   <li> Press <b>Left Mouse</b> on a clip.</li>
172
-   <li> Continue to <b>Left drag</b> clip and all clips and compositors to right of it into a new position</li>
173
-   <li> It is not possible to move items on top of clips. Items can only be moved on top of empty space </li>
174
-       </ul>
175
-   <li>Use <b>Control</b> button to only affect items on a single track</li>
176
-       <ul>
177
-   <li> Press <b>Control</b> and use <b>Left Mouse</b> to move all items on single track to the right of the selected clip</li>
178
-   </ul>
179
-</li>
180
-</ol>
181
-
182
-
183
- 
184
- 
185
-<h2>Trim Tools</h2>
186
-
187
-<a id="multitrim"></a>
188
-<h3>Multitrim</h3>
189
-<p>
190
-Do  <b>Trim</b>, <b>Roll</b> or <b>Slip</b> tool edits based on cursor position on timeline.
191
-</p>
192
-<ol>
193
-
194
-<li> Cursor change indicates which type of trim edit is done when edit is initiated with <b>Left Mouse</b> press.
195
-   <ul>
196
-   <li> If cursor is right on the cut, a <b>Roll</b> edit is done. <b>Roll</b> edit moves edit point between two clips so that their combined length stays the same.</li>
197
-   <li> If cursor is right on the center of clip, a <b>Slip</b> edit is done. <b>Slip</b> edit changes the displayed area of media in a clip while keeping the clip position unchanged on the timeline.</li>
198
-   <li> On other cursor positions a <b>Trim</b> edit on the closer clip end is done. <b>Trim</b> edit makes clip longer or shorter from either clip's end or from clip's beginning.</li>
199
-   </ul>
200
-</li>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/fluxity.html Deleted
201
 
1
@@ -1,3836 +0,0 @@
2
-<!doctype html>
3
-<html lang="en">
4
-<head>
5
-<meta charset="utf-8">
6
-<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
7
-<meta name="generator" content="pdoc 0.10.0" />
8
-<title>fluxity API documentation</title>
9
-<meta name="description" content="GPL Licence text …" />
10
-<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
11
-<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
12
-<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
13
-<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2id^="header-"{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
14
-<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
15
-<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}ahref:after{content:" (" attr(href) ")";font-size:90%}ahreftitle:after{content:none}abbrtitle:after{content:" (" attr(title) ")"}.ir a:after,ahref^="javascript:":after,ahref^="#":after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
16
-<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
17
-<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
18
-</head>
19
-<body>
20
-<main>
21
-<article id="content">
22
-<header>
23
-<h1 class="title">Module <code>fluxity</code></h1>
24
-</header>
25
-<section id="section-intro">
26
-<h3 id="gpl-licence-text">GPL Licence text</h3>
27
-<p>Flowblade Movie Editor is a nonlinear video editor.
28
-Copyright 2021 Janne Liljeblad.</p>
29
-<p>This file is part of Flowblade Movie Editor <a href="https://github.com/jliljebl/flowblade/">https://github.com/jliljebl/flowblade/</a>.</p>
30
-<p>Flowblade Movie Editor is free software: you can redistribute it and/or modify
31
-it under the terms of the GNU General Public License as published by
32
-the Free Software Foundation, either version 3 of the License, or
33
-(at your option) any later version.</p>
34
-<p>Flowblade Movie Editor is distributed in the hope that it will be useful,
35
-but WITHOUT ANY WARRANTY; without even the implied warranty of
36
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
37
-See the
38
-GNU General Public License for more details.</p>
39
-<p>You should have received a copy of the GNU General Public License
40
-along with Flowblade Movie Editor. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
41
-<h1 id="fluxity-scripting">FLUXITY SCRIPTING AND API</h1>
42
-<p>Fluxity scripting is a <strong>Python scripting solution</strong> created to provide <strong>Flowblade Movie Editor</strong> with a <em>Plugin API</em>.
43
-Currently <em>Fluxity API</em>
44
-is used by Flowblade <em>Generators</em> feature.</p>
45
-<p><em>Fluxity API</em> is made available to scripts mainly by <em>fluxity.FluxityContext</em> object and its methods.
46
-This object is created to communicate with the script before calling any of the methods of the script.</p>
47
-<p>Some constants mentioned in this source file - such as <code><a title="fluxity.EDITOR_FLOAT" href="#fluxity.EDITOR_FLOAT">EDITOR_FLOAT</a></code> or <code><a title="fluxity.PROFILE_WIDTH" href="#fluxity.PROFILE_WIDTH">PROFILE_WIDTH</a></code> - can also be used by scripts. </p>
48
-<p>See below for <em>fluxity.FluxityContext</em> object API details.</p>
49
-<h2 id="script-interface">SCRIPT INTERFACE</h2>
50
-<p>A Python script needs to have the following functions to load and run without crashing as a Fluxity API conforming script.</p>
51
-<pre><code>def init_script(fctx):
52
-    pass
53
-
54
-def init_render(fctx):
55
-    pass
56
-
57
-def render_frame(frame, fctx, w, h):
58
-    pass
59
-</code></pre>
60
-<h2 id="script-lifecycle">SCRIPT LIFECYCLE</h2>
61
-<p><strong><code>init_script(fctx):</code></strong> This method is called when script is first loaded by Flowblade to create data structures with info on editors and script metadata. </p>
62
-<p><strong><code>init_render(fctx):</code></strong> This method is called before a render is started to get user input from editors and possibly to create some additional data structures.</p>
63
-<p><strong><code>render_frame(frame, fctx, w, h):</code></strong> This method is called for each frame rendered to create an output image for that frame.</p>
64
-<p>Object <strong><code>fctx</code></strong> is object of class <strong><code>fluxity.FluxityContext</code></strong>.</p>
65
-<h2 id="example-script">EXAMPLE SCRIPT</h2>
66
-<h3 id="init_script">init_script()</h3>
67
-<pre><code>import cairo
68
-import numpy as np
69
-import random
70
-import math
71
-
72
-import fluxity
73
-
74
-def init_script(fctx):
75
-    fctx.set_name(&quot;Floating Balls&quot;)
76
-    fctx.set_version(1)
77
-    fctx.set_author(&quot;Janne Liljeblad&quot;)
78
-
79
-    fctx.add_editor(&quot;Hue&quot;, fluxity.EDITOR_COLOR, (0.8, 0.50, 0.3, 1.0))
80
-    fctx.add_editor(&quot;Speed&quot;, fluxity.EDITOR_FLOAT_RANGE, (1.0, -5.0, 5.0))
81
-    fctx.add_editor(&quot;Speed Variation %&quot;, fluxity.EDITOR_INT_RANGE, (40, 0, 99))
82
-    fctx.add_editor(&quot;Number of Items&quot;, fluxity.EDITOR_INT_RANGE, (50, 10, 500))
83
-    fctx.add_editor(&quot;Size&quot;, fluxity.EDITOR_INT_RANGE, (330, 10, 800))
84
-    fctx.add_editor(&quot;Size Variation %&quot;, fluxity.EDITOR_INT_RANGE, (0, 0, 80))
85
-    fctx.add_editor(&quot;Opacity&quot;, fluxity.EDITOR_INT_RANGE, (100, 5, 100))
86
-    fctx.add_editor(&quot;Random Seed&quot;, fluxity.EDITOR_INT, 42)
87
-</code></pre>
88
-<p>In <em>init_script()</em> we define the editors that will be presented to the user and set some metadata like the name of the script displayed to the user and the script author.</p>
89
-<p>Object <strong><code>fctx</code></strong> is object of class <strong><code>fluxity.FluxityContext</code></strong>.</p>
90
-<h3 id="init_render">init_render()</h3>
91
-<pre><code>def init_render(fctx):
92
-    # The script is possibly rendered using multiple prosesses and we need to have the
93
-    # same sequence of random numbers in all processes. If we don't set seed we'll get completely different
94
-    # ball positions, colors and speeds in different rendering processes.
95
-    random.seed(fctx.get_editor_value(&quot;Random Seed&quot;))
96
-
97
-    # Ball colors data structure
98
-    hue = fctx.get_editor_value(&quot;Hue&quot;)
99
-    hr, hg, hb, alpha = hue
100
-    fctx.set_data_obj(&quot;hue_tuple&quot;, hue)
101
-    color_array = list(hue)
102
-    ball_colors = 
103
-    color_mult = 1.05
104
-    opacity = float(fctx.get_editor_value(&quot;Opacity&quot;)) / 100.0
105
-
106
-    for i in range(0, 10):
107
-        array = np.array(color_array) * color_mult
108
-        r, g, b, a = array
109
-        ball_colors.append(cairo.SolidPattern(_clamp(r), _clamp(g), _clamp(b), opacity))
110
-        color_array = array
111
-    fctx.set_data_obj(&quot;ball_colors&quot;, ball_colors)
112
-
113
-    # Ball animations data structure
114
-    ball_data = 
115
-    number_of_balls = fctx.get_editor_value(&quot;Number of Items&quot;)
116
-    speed = fctx.get_editor_value(&quot;Speed&quot;)
117
-    speed_var_size_precentage = fctx.get_editor_value(&quot;Speed Variation %&quot;)
118
-    speed_var_max = speed * (speed_var_size_precentage  / 100.0)
119
-    size = fctx.get_editor_value(&quot;Size&quot;)
120
-    size_var_size_precentage = fctx.get_editor_value(&quot;Size Variation %&quot;)
121
-    size_var_max = size * (size_var_size_precentage / 100.0)
122
-    size_max = size + size_var_max
123
-    fctx.set_data_obj(&quot;size_max&quot;, size_max)
124
-
125
-    for i in range(0, number_of_balls):
126
-        path_pos = random.uniform(0.0, 1.0)
127
-        y = random.randint(-330, 1080 + 330)
128
-        speed_var = random.uniform(-1.0, 1.0)
129
-
130
-        ball_speed = speed + (speed_var * speed_var_max)
131
-        size_var = random.uniform(-1.0, 1.0)
132
-        ball_size = size + (size_var * size_var_max)
133
-        color_index = random.randint(0, 9)
134
-        ball_data.append((path_pos, y, ball_speed, ball_size, color_index))
135
-
136
-    fctx.set_data_obj(&quot;ball_data&quot;, ball_data)
137
-</code></pre>
138
-<p>In <em>init_render() </em> we read editor values set by the user and create some data structures for moving ball animations based on that data.</p>
139
-<p>Also note that <strong>we need to set seed for Pythom module 'random'</strong> because when a frame sequence is rendered using multiple processes we need the exact same sequence of random numbers produced in every process. </p>
140
-<p>Object <strong><code>fctx</code></strong> is object of class <strong><code>fluxity.FluxityContext</code></strong>.</p>
141
-<h3 id="render_frame">render_frame()</h3>
142
-<pre><code>def render_frame(frame, fctx, w, h):
143
-    cr = fctx.get_frame_cr()
144
-
145
-    # Draw bg
146
-    bg_color = cairo.SolidPattern(*fctx.get_data_obj(&quot;hue_tuple&quot;))
147
-    ball_colors = fctx.get_data_obj(&quot;ball_colors&quot;)
148
-    ball_data = fctx.get_data_obj(&quot;ball_data&quot;)
149
-
150
-    cr.set_source(bg_color)
151
-    cr.rectangle(0, 0, w, h)
152
-    cr.fill()
153
-
154
-    # Draw balls
155
-    number_of_balls = fctx.get_editor_value(&quot;Number of Items&quot;)
156
-    size_max = fctx.get_data_obj(&quot;size_max&quot;)
157
-    path_start_x = - size_max
158
-    path_end_x =  w + size_max
159
-    path_len = path_end_x - path_start_x
160
-    SPEED_NORM_PER_FRAME = 15.0 / float(w) # Speed value 1.0 gets 15 pixels of movement per frame.
161
-    for i in range(0, number_of_balls):
162
-        path_pos, y, ball_speed, ball_size, color_index = ball_datai
163
-        xc = ball_size / 2.0
164
-        yc = ball_size / 2.0
165
-        xpos_norm = path_pos + (float(frame) * ball_speed * SPEED_NORM_PER_FRAME)
166
-        while xpos_norm &gt; 1.0:
167
-            xpos_norm = xpos_norm - 1.0
168
-        x = path_start_x + path_len * xpos_norm
169
-        cr.save()
170
-        cr.translate(x, y)
171
-        cr.arc(xc, yc, ball_size / 4.0, 0.0, 2.0 * math.pi)
172
-        cr.set_source(ball_colorscolor_index)
173
-        cr.fill()
174
-        cr.restore()
175
-
176
-# ----------------------- helper func
177
-def _clamp(v):
178
-    return max(min(v, 1.0), 0.0)
179
-
180
-</code></pre>
181
-<p>In <em>render_frame()</em> we first acquire <em>Cairo.Context</em> object that can be drawn onto to create output for the frame.</p>
182
-<p>After that the data structures created in <em>init_render()</em> are accessed and image is drawn.</p>
183
-<p>There is a helper function <em>_clamp(v)</em> used to make sure that all color values are in range 0-1. Any number of helper functions, objects and data structures can be created.</p>
184
-<h2 id="developing-fluxity-scripts">DEVELOPING FLUXITY SCRIPTS</h2>
185
-<p><strong>Flowblade</strong> comes with a simple GUI tool for developing Fluxity scripts. It can be accessed from menu <strong>Tools-&gt;Generator Script Editor</strong>.</p>
186
-<p>Using the development tool you can edit scripts, render output from them, and get receive error messages when something goes wrong. From hamburger menu you can open and save your own scripts, access this document, and open and inspect example code of the <em>Generators</em> distributed with Flowblade. </p>
187
-<p>Since the text editor in the development tool is quite rudimentary <em>(with a future GTK4 port we may get improvement here)</em>, it can be a useful workflow to use an external text editor to edit the scripts, and press <em>Reload Script</em> button to update text area contents before attempting render.</p>
188
-<h1 id="fluxity-api_1">FLUXITY API</h1>
189
-<details class="source">
190
-<summary>
191
-<span>Expand source code</span>
192
-</summary>
193
-<pre><code class="python">&#34;&#34;&#34;
194
-    ### GPL Licence text
195
-
196
-    Flowblade Movie Editor is a nonlinear video editor.
197
-    Copyright 2021 Janne Liljeblad.
198
-
199
-    This file is part of Flowblade Movie Editor &lt;https://github.com/jliljebl/flowblade/&gt;.
200
-
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/generatorsfluxity.html Deleted
115
 
1
@@ -1,113 +0,0 @@
2
-<!DOCTYPE html>
3
- 
4
-<html>
5
-<head>
6
-  <title>Generators</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-
15
-<img src="header_text_5.png">
16
-
17
-<script src="tocgen.js"></script>
18
-
19
-<div id="toccontent">
20
-
21
-<div class="subject-header">Generators</div>
22
-
23
-<div id="toc"></div>
24
-
25
-<p>
26
-<b>Generators</b> are <b>Media Items</b> that render into animated media clips when placed on timeline.
27
-</p>
28
-
29
-<p>
30
-Currently there are three different types of <b>Generators</b> available:
31
-<ul style="list-style-type:none">
32
-<li><b>Backgrounds</b> Animated backgrounds.</li>
33
-<li><b>Texts</b> Animated texts.</li>
34
-<li><b>Cover Transitions</b> Incoming shapes cover frame fully and then disappear creating a transition.</li>
35
-</ul>
36
-
37
-</p>
38
-
39
-<p>
40
-Flowblade <b>Generators</b> are implemented as Python scripts using <i>Fluxity API</i> <i>(see below)</i> packed inside <a href="container_clips.html">Container Clips.</a>
41
-</p>
42
-
43
-
44
-<h3>Using Generators</h3>
45
-
46
-<h4>Adding Generators</h4>
47
-<ol>
48
-<li>Select menu item <b>Project -> Add Generator</b>.</li>
49
-<li>Select <b>Generator</b> using <b>Generator</b> drop down menu.</li>
50
-<li>Set properties using left side panel, select frame using <b>Clip Frame</b> spin button and press <b>Preview</b> button to view results.</li>
51
-<li>Use <b>Generator Length</b> spin button to set generator maximum length. Use <b>Import Action</b> drop down menu to either add as <b>Media Item</b> or render a video clip.</b></li>
52
-<li>Use <b>Add Generator</b> button to complete <b>Generator</b> creation.</li>
53
-</ol>
54
-
55
-<h4>Editing Generator Clips</h4>
56
-<ol>
57
-<li>Open timeline clip <b>Right Mouse</b> pop-up menu and select item <b>Edit Generator...</b>.</li>
58
-<li>Set <b>Generator</b> properties using editors opened in <b>Edit</b> panel.</li>
59
-<li>Select frame using spin button and press <b>Preview</b> button to view results.</li>
60
-<li>Use <b>Apply</b> button to re-render timeline clip using edited properties.</li>
61
-</ol>
62
-
63
-<h3>Generators List</h3>
64
- <table>
65
-  <tr>
66
-    <th>Category</th>
67
-    <th>Name</th>
68
-    <th>Description</th>
69
-  </tr>
70
-  <tr>
71
-    <td><i>Backgrounds</i></td>
72
-    <td><b>Floating Balls</b></td>
73
-    <td>Colored balls moving horizontally with differing sizes and speeds.</td>
74
-  </tr>
75
-  <tr>
76
-    <td><i>Backgrounds</i></td>
77
-    <td><b>Hex Colors</b></td>
78
-    <td>Colored hexagonals of selected size changing color at selected speed.</td>
79
-  </tr>
80
-  <tr>
81
-    <td><i>Texts</i></td>
82
-    <td><b>Multiline text</b></td>
83
-    <td>Animated lines of text with multiple in and out animation types, with optional lines or rectangle background.</td>
84
-  </tr>
85
-  <tr>
86
-    <td><i>Texts</i></td>
87
-    <td><b>TypeWriter</b></td>
88
-    <td>Text typewriter effect with steps of adding a letter, word or line.</td>
89
-  </tr>
90
-  <tr>
91
-    <td><i>Cover Transitions</i></td>
92
-    <td><b>Lines Sweep</b></td>
93
-    <td>Cover transition with horizontally moving colored lines.</td>
94
-  </tr>
95
-   <tr>
96
-    <td><i>Cover Transitions</i></td>
97
-    <td><b>Hex Overlay</b></td>
98
-    <td>Cover transition with apperaing and disappearing hexagonals.</td>
99
-  </tr>
100
-</table> 
101
-
102
-<h2>Fluxity Scripting</h2>
103
-<p>Fluxity scripting is a <strong>Python scripting solution</strong> created to provide <strong>Flowblade Movie Editor</strong> with a <em>Plugin API</em> used to create <em>Generators</em> providing means to create e.g. animated text and animated background clips.</p>
104
-
105
-
106
-<h3>Fluxity API</h3>
107
-<p>Instructions on how to create <strong>Generators</strong> using <strong>Fluxity API</strong> <a href="fluxity.html">here.</a></p>
108
-
109
-</div>
110
-</div>
111
-
112
-</body>
113
-
114
-</html> 
115
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/header_text_5.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/help.html Deleted
87
 
1
@@ -1,85 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Flowblade Reference Guide</title>
6
-  <link rel="stylesheet" href="style.css">
7
-<script src="toc.js" type="text/javascript"></script>
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-
15
-<a class="french-link" href="https://github.com/jliljebl/flowblade/blob/master/flowblade-trunk/docs/FLOWBLADE_manuel_fr.pdf">Manuel en français</a>
16
-
17
-<div id="help-index">
18
-       <div class="subject-cell">
19
-           <a href="intro.html">Introduction</a>
20
-       </div>
21
-
22
-       <div class="subject-cell">
23
-           <a href="basic_editing.html">Basic Editing</a> 
24
-       </div>
25
-
26
-       <div class="subject-cell">
27
-           <a href="edit_tools.html">Timeline Edit Tools</a> 
28
-       </div> 
29
-
30
-       <div class="subject-cell">
31
-           <a href="compositor.html">Creating Composited Images</a>
32
-       </div>
33
-
34
-       <div class="subject-cell">
35
-           <a href="filtering.html">Filtering image and audio</a> 
36
-       </div>
37
-
38
-       <div class="subject-cell">
39
-           <a href="advanced.html">Advanced Editing Features</a> 
40
-       </div> 
41
-
42
-       <div class="subject-cell">
43
-           <a href="range_log.html">Range Log</a>
44
-       </div>
45
-
46
-       <div class="subject-cell">
47
-           <a href="proxy.html">Proxy Editing</a>
48
-       </div>
49
-       
50
-       <div class="subject-cell">
51
-           <a href="container_clips.html">Container Clips</a>
52
-       </div>
53
-
54
-       <div class="subject-cell">
55
-            <a href="generatorsfluxity.html">Generators</a>
56
-       </div>
57
-
58
-       <div class="subject-cell">
59
-           <a href="tools.html">Tools</a>
60
-       </div>
61
-       
62
-       <div class="subject-cell">
63
-            <a href="rendering.html">Rendering</a>
64
-       </div>
65
-
66
-       <div class="subject-cell">
67
-           <a href="datastores.html">Data Stores</a>
68
-       </div>
69
-
70
-        <div class="subject-cell">
71
-           <a href="infotips.html">Info & Tips</a>
72
-       </div>
73
-        
74
-</div>
75
-
76
-<h6 class="appendix-title">Appendices:</h6>
77
-<a class="appendix-index" href="filters_list.html">Filters list</a>
78
-<a class="appendix-index" href="fluxity.html">Fluxity API doc</a>
79
-<a class="appendix-index" href="kbshortcuts.html">Keyboard Shortcuts</a>
80
-
81
-<div class="copyright-info">Flowblade Reference Guide v 3.0 9-3-2017.</div> 
82
-
83
-</div>
84
-</body>
85
-
86
-</html> 
87
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/only_one_comp.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/style.css Deleted
201
 
1
@@ -1,330 +0,0 @@
2
-html {
3
-   font-size: 100%;
4
-   -webkit-text-size-adjust: 100%;
5
-   -ms-text-size-adjust: 100%;
6
-}
7
-
8
-body {
9
-   font-family: Georgia, "Times New Roman", Times, serif;
10
-   color:#222222;
11
-   background-color: #ffffff; 
12
-   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
13
-   font-family: sans-serif;
14
-   word-wrap: break-word;
15
-   line-height: 1.4;
16
-   vertical-align: baseline;
17
-}
18
-
19
-#content {
20
-  width: 700px ;
21
-  margin-left: auto ;
22
-  margin-right: auto ;
23
-}
24
-
25
-#help-index{
26
-   margin-top: 80px;
27
-   width: 900px;
28
-   margin-bottom: 80px;
29
-   display: flex;
30
-   justify-content: center;
31
-   flex-direction: column;
32
-   text-align: center;
33
-}
34
-
35
-.appendix-index{
36
-   margin-top: 10px;
37
-   width: 900px;
38
-   margin-bottom: 10px;
39
-   display: flex;
40
-   justify-content: center;
41
-   flex-direction: column;
42
-   text-align: left;
43
-   color: #666666;
44
-   font-size:18px;
45
-}
46
-
47
-.french-link{
48
-   margin-top: 40px;
49
-   width: 900px;
50
-   margin-bottom: 0px;
51
-   display: flex;
52
-   justify-content: center;
53
-   flex-direction: column;
54
-   text-align: left;
55
-   font-size:18px;
56
-}
57
-
58
-.subject-cell {
59
-   padding-right: 20px;
60
-   color:#222222;
61
-   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
62
-   font-family: sans-serif;
63
-   word-wrap: break-word;
64
-   line-height: 1.4;
65
-   vertical-align: baseline;
66
-   font-weight:400;
67
-   font-size:30px;
68
-   margin-bottom: 35px;
69
-}
70
-
71
-.grid-container {
72
-   margin-top: 80px;
73
-        width: 700px;
74
-   margin-bottom: 80px;
75
-}
76
-
77
-.row:before, 
78
-.row:after {
79
-   content:"";
80
-   display: table ;
81
-   clear:both;
82
-}
83
-
84
-.column4 {
85
-   float: left; 
86
-   width: 33.3%;
87
-   margin-bottom: 50px;
88
-}
89
-
90
-.subject-cell {
91
-   padding-right: 20px;
92
-   color:#222222;
93
-   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
94
-   font-family: sans-serif;
95
-   word-wrap: break-word;
96
-   line-height: 1.4;
97
-   vertical-align: baseline;
98
-   font-weight:400;
99
-   font-size:22px;
100
-   text-transform: uppercase;
101
-}
102
-
103
-.appendix-pad {
104
-   color: #666666;
105
-   font-size:14px;
106
-}
107
-.appendix-title {
108
-   color: #666666;
109
-   font-size:20px;
110
-}
111
-
112
-.note {
113
-   background-color: #f3f3f0;
114
-   padding: 25px;
115
-   margin-bottom: 10px ;
116
-}
117
-
118
-.important {
119
-   background-color: #f5d77d;
120
-   padding: 25px;
121
-   margin-bottom: 10px ;
122
-}
123
-
124
-.tabbed {
125
-   padding-left: 25px;
126
-   margin-bottom: 10px ;
127
-}
128
-
129
-.tabbed_line {
130
-   padding-left: 25px;
131
-}
132
-
133
-.tocitem {
134
-   font-size:12px;
135
-   line-height: 1.0;
136
-
137
-}
138
-
139
-.tocli {
140
-   list-style-type: none;
141
-}
142
-
143
-.copyright-info {
144
-   font-family: Georgia, "Times New Roman", Times, serif;
145
-   margin-top:80px;
146
-   color: #444444;
147
-   font-weight:400;
148
-   font-size:12px;
149
-}
150
-
151
-.code-text {
152
-   font-family: "Lucida Console", "Courier New", monospace;
153
-   background-color: #f3f3f0;
154
-   padding: 10px;
155
-   margin-bottom: 5px ;
156
-   line-height: 10px
157
-}
158
-
159
-.subject-header {
160
-   text-transform: uppercase;
161
-   margin-top:10px;
162
-   color: #000000;
163
-   font-weight:400;
164
-   font-size:26px;
165
-}
166
-
167
-.filter {
168
-   margin-bottom: 25px;
169
-   color: #000000;
170
-   font-weight:400;
171
-   font-family: sans-serif;
172
-   word-wrap: break-word;
173
-   line-height: 1.4;
174
-   vertical-align: baseline;
175
-}
176
-
177
-.filter-name {
178
-   padding-left: 20px;
179
-}
180
-
181
-.filter-property {
182
-   padding-left: 50px;
183
-   font-size:12px;
184
-}
185
-.filter-value {
186
-   display:inline-block;
187
-   color: #0000bb;
188
-   font-size: 8;
189
-}
190
-
191
-.filter-group {
192
-   color: #000000;
193
-   font-size: 26;
194
-   text-transform: uppercase;
195
-   margin-top: 50px;
196
-   margin-bottom: 10px;
197
-}
198
-
199
-.r-widget {
200
-   display: inline-block;
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/tocgen.js Deleted
41
 
1
@@ -1,39 +0,0 @@
2
-/*
3
-* Generates table of Contents from headers in a html file
4
-*/
5
-
6
-window.onload = function () {
7
-    var toc = "";
8
-    var level = 3;
9
-
10
-    document.getElementById("toccontent").innerHTML =
11
-        document.getElementById("toccontent").innerHTML.replace(
12
-            /<h(\d)>(^<+)<\/h(\d)>/gi,
13
-            function (str, openLevel, titleText, closeLevel) {
14
-                if (openLevel != closeLevel) {
15
-                    return str;
16
-                }
17
-
18
-                if (openLevel > level) {
19
-                    toc += (new Array(openLevel - level + 1)).join("<ul>");
20
-                } else if (openLevel < level) {
21
-                    toc += (new Array(level - openLevel + 1)).join("</ul>");
22
-                }
23
-
24
-                level = parseInt(openLevel);
25
-
26
-                var anchor = titleText.replace(/ /g, "_");
27
-                toc += "<li class=\"tocli\"><a class=\"tocitem\" href=\"#" + anchor + "\">" + titleText
28
-                    + "</a></li>";
29
-
30
-                return "<h" + openLevel + "><a name=\"" + anchor + "\">"
31
-                    + titleText + "</a></h" + closeLevel + ">";
32
-            }
33
-        );
34
-
35
-    if (level) {
36
-        toc += (new Array(level + 1)).join("</ul>");
37
-    }
38
-
39
-    document.getElementById("toc").innerHTML += toc;
40
-};
41
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/en/workflow.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru Deleted
2
 
1
-(directory)
2
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/advanced.html Deleted
179
 
1
@@ -1,177 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-  <title>Расширенное редактирование</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-
16
-<script src="tocgen.js"></script>
17
-
18
-<div id="toccontent">
19
-
20
-<div id="advtoc">
21
-<div class="subject-header">Расширенные возможности редактирования</div>
22
-</div>
23
-
24
-<div id="toc"></div>
25
-
26
-<h2>1. Действия по проекту</h2>
27
-<h3>Объединение последовательностей</h3>
28
-<p>Можно импортировать всё содержимое других последовательностей в активную в последовательность.</p>
29
-<ol>
30
-<li> Выберите <b>Последовательность → Импортировать ещё одну последовательность…</b></li>
31
-<li> Выберите действие для импорта.</li>
32
-<ul>
33
-<li> <b>Добавить последовательность</b>: последовательность будет добавлена в конце текущей последовательности.</li>
34
-<li> <b>Вставить последовательность по указателю воспроизведения</b>: в месте расположения указателя воспроизведения будет создан надрез, куда и вставится импортируемая последовательность.</li>
35
-</ul>
36
-<li> Выберите последовательность для импорта</li>
37
-<ul>
38
-<li> <b>Обратите внимание, что для импорта, у вас должно быть не меньше двух последовательностей.</b></li>
39
-</ul>
40
-<li> Нажмите на кнопку <b>Импорт</b>, для выполнения операции.</li>
41
-</ol>
42
-<h3> Разрезание последовательности</h3>
43
-<ol>
44
-<li> Выберите <b>Последовательность → Разрезать последовательность по указателю</b></li>
45
-<li> Эта операция создаст новую последовательность из элементов расположенных справа от указателя воспроизведения и удалит их из текущей последовательности. Созданная последовательность откроется как текущая активная.</li >
46
-</ol>
47
-<h3>Импорт медиа из другого проекта</h3>
48
-<p>Вы можете импортировать элементы мультимедиа из другого проекта.</p>
49
-<ol>
50
-<li> Выберите <b>Проект → Импортировать медиа из проекта…</b></li>
51
-<li> Выберите файл проекта.</li>
52
-<li> Элементы медиа, которые отсутствуют в текущем проекте будут открыты в корзине. Обратите внимание, что загрузка новых элементов из проекта, займёт некоторое время.</li>
53
-</ol>
54
-<h2>2. Синхронизация звука на монтажном столе</h2>
55
-<p>На монтажном столе можно сделать, так чтобы, клип на одной дорожке автоматически переместился на нужное количество кадров для синхронизации со звуком клипа на другой дорожке.</p>
56
-<p>Что позволяет, нам сделать упрощённую версию многокамерного редактирования на монтажном столе.</p>
57
-<ol>
58
-<li> Щёлкните <b>Правой кнопкой мыши</b> по клипу, который хотите синхронизировать.</li>
59
-<li> Выберите пункт меню <b>Выбрать звуковой клип для синхронизаци...</b> Курсор примет форму целевого креста.</li>
60
-<li> Нажмите на клип, с которым вы хотите синхронизировать звук.</li>
61
-<li> Откроется диалоговое окно с информацией о действиях синхронизации, которые необходимо выполнить для синхронизации клипов.</li>
62
-<li> Для выполнения синхронизации нажмите кнопку <b>Сдвинуть клип для синхронизации</b>.</li>
63
-<li> Обычно рекомендуется отключить один из синхронизированных клипов.</li>
64
-</ol>
65
-<p><div class="note">Во время звуковой синхронизации идёт поиск на наилучшее математическое соответствие между двумя звуковыми сигналами, поэтому использование несоответствующего звука приведёт к случайным результатам.</b></div></p>
66
-<h2>3. Изменение скорости клипа и клип в обратном направлении</h2>
67
-<p>В Flowblade эффекты движения достигаются путём <b>сборки клипа с изменением скорости или сборки клипа в обратном направлении</b> с последующим их размещением на монтажном столе.</p>
68
-<h3>Сборка клипа с изменением скорости</h3>
69
-<ol>
70
-<li> Щёлкните правой кнопкой мыши по видеоклипу и в выпадающем меню выберите <b>Собрать клип с изменением скорости</b>.</li>
71
-<li> Измените параметры сборки для нового клипа</li>
72
-<ul>
73
-<li> Установите скорость.</li>
74
-<li> Присвойте имя и выберите место расположения будущего клипа.</li>
75
-<li> Выберите параметры сборки.</li>
76
-<li> Выберите длительность сборки:</li>
77
-<ul>
78
-<li> Длительность оригинального клипа</li>
79
-<li> Участок оригинального клипа</li>
80
-</ul>
81
-<li> Нажмите кнопку <b>Сборка</b>, для создания нового клипа.</li>
82
-</ol>
83
-<h3> Сборка клипа в обратном направлении </h3>
84
-<ol>
85
-<li> Щёлкните правой кнопкой мыши по видеоклипу и в выпадающем меню выберите <b>Собрать клип в обратном направлении</b>.</li>
86
-<li>Измените параметры сборки для нового клипа
87
-<ul>
88
-<li> Установите скорость.</li>
89
-<li> Присвойте имя и выберите место расположения будущего клипа.</li>
90
-<li> Выберите параметры сборки.</li>
91
-<li> Выберите участок сборки:</li>
92
-<ul>
93
-<li> Длительность оригинального клипа</li>
94
-<li> Участок оригинального клипа</li>
95
-</ul>
96
-</ul>
97
-<li> Нажмите кнопку <b>Сборка</b>, для создания нового клипа.</li>
98
-</ol>
99
-<h2>4. Синхронизация по родительскому клипу</h2>
100
-<p>В видеоредакторе Flowblade можно <b>установить позицию клипа, так чтобы он стартовал и в дальнейшем работал с позиции другого клипа</b> по запросу.</p>
101
-<h3>Основные положения</h3>
102
-<ul>
103
-<li> Синхронизация устанавливается путём выбора синхронизирующего <b>родительского клипа</b> и синхронизируемого <b>дочернего клипа</b>.</li>
104
-<li> <b>Родительскими клипами могут быть только те клипы, которые расположенные на дорожке V1</b>. Это сделано для того, чтобы подчеркнуть стиль редактирования, в котором основные элементы последовательности всегда находятся на дорожке V1, а компоновка и отделение звука выполняется относительно последовательности клипов расположенных на дорожке V1.</li>
105
-<li> <b>Функция синхронизации помогает сохранить проделанную работу</b> — компоновку нескольких дорожек и изменения в отделённом от видеоклипа звуке... Например, когда из-за правок в других местах последовательности, сбилось правильное расположение клипов относительно друг друга.</li>
106
-<li> Чтобы избежать нежелательных перемещений клипов по монтажному столу, во время редактирования <b>ресинхронизация выполняется только по запросу</b>. Ресинхронизация желательна для возможного предотвращения побочных эффектов при редактировании.</li>
107
-</ul>
108
-<h3>Настройка синхронизации родительского клипа</h3>
109
-<ol>
110
-<li> Щёлкните <b>правой кнопкой мыши</b> по клипу на любой дорожке кроме V1 и выберите пункт «Выбрать родительский клип для синхронизации…».</li>
111
-<li> Курсор примет форму целевого креста. На дорожке V1 выберите родительский клип, щёлкнув по нему левой кнопкой мыши.</li>
112
-<li> Между двумя клипами установится связь синхронизации. Курсор примет форму указателя по умолчанию.</li>
113
-<li> Узнать состояние синхронизации можно по индикаторным линиям на дочернем клипе. Цвет индикаторных линий синхронизации на клипах:</li>
114
-<ul>
115
-<li> Зелёный — дочерний клип синхронизирован с родительским.</li>
116
-<li> Красный — дочерний клип не синхронизирован с родительским.</li>
117
-<li> Серый — родительский клип на дорожке V1 отсутствует.</li>
118
-</ul>
119
-</ol>
120
-
121
-<h3>Повторная синхронизация дочерних элементов</h3>
122
-<p>Для того чтобы дочерний клип выполнил повторную синхронизацию с родительским, выполните одно из действий:</p>
123
-<ul>
124
-<li> В меню приложения выберите <b>Правка → Ресинхронизировать</b>.</li>
125
-<li> Щёлкните <b>Правой кнопкой мыши</b> по дочернему клипу и выпавшем меню клипа выберите <b>Ресинхронизировать</b>.</li>
126
-<li> Нажмите <b>Ресинхронизировать</b> на панели редактирования.</li>
127
-</ul>
128
-<h3>Удаление связи синхронизации с родительским клипом</h3>
129
-<ul>
130
-<li> Щёлкните <b>Правой кнопкой мыши</b> по дочернему клипу и выберите <b>Удалить связь синхронизации</b>.</li>
131
-</ul>
132
-<h3>Синхронизация скомпонованных клипов</h3>
133
-<ul>
134
-<li> При необходимости установите связь синхронизации всех клипов, которые являются частью многодорожечной компоновки с родительским клипом.</li>
135
-</ul>
136
-<h3>Синхронизация отделённого звука</h3>
137
-<ul>
138
-<li> Щёлкните <b>Правой кнопкой мыши</b> по клипу на дорожке V1 и выберите «Отделить звук для синхронизации».</li>
139
-<li> Чтобы поддержать синхронизацию с родительским клипом отредактируйте отделённый от видео звук, используя инструменты «Прокрутка» и «Обрезка».</li>
140
-<li> При необходимости синхронизируйте звук.</li>
141
-</ul>
142
-</ol>
143
-
144
-<h2>5. Предпросмотр монтажного стола</h2>
145
-<p><b>Предпросмотр монтажного стола</b>  — это способ добиться плавного воспроизведения в тех областях монтажного стола, которые предъявляют высокие требования к системным ресурсам для приемлемого воспроизведения.</p>
146
-<h3>Включение сборки для предпросмотра</h3>
147
-<p>Включить сборку для предпросмотра монтажного стола можно двумя способами:
148
-<ul><li>В выпадающем списке под заголовками дорожек;</li>
149
-<li>через меню <b>«Последовательность» → «Собирать для предпросмотра»</b>.</li></ul></p>
150
-<img src="tlinerender.webp">
151
-<p><i>Кнопка запуска предпросмотра монтажного стола слева, а справа под монтажным столом шкала управления сегментами.</i></p>
152
-<h3>Режимы предпросмотра монтажного стола</h3> 
153
-<p>Существует два режима активирующих предпросмотр монтажного стола:<ul> 
154
-<li><b>Собирать автоматически</b>. В этом режиме определённые сегменты при каждом изменении содержимого монтажного стола в этом диапазоне собираются автоматически;</li> 
155
-<li><b>Собирать по запросу</b>. В этом режиме сегменты собираются по запросу пользователя.</li></ul></p>
156
-<h3>Работа с сегментами</h3> 
157
-<p><ul> <li><b>Создание сегмента предпросмотра</b>. Переместите мышь с нажатой <i>левой кнопкой</i> влево или вправо по шкале управления сегментами.</li>
158
-<li><b>Изменение размера сегмента</b>. Переместите мышь с нажатой <i>левой кнопкой</i> по сегменту за его пределы или наоборот. Перемещение мыши внутри сегмента приведёт к его перезаписи.</li>
159
-<li><b>Объединение сегментов</b>. Перемещайте мышь с нажатой <i>левой кнопкой</i> захватив несколько сегментов</li>
160
-<li><b>Удаление сегментов</b>. Щёлкните по сегменту <i>левой кнопкой мыши</i> для его выделения и нажмите клавишу <i>Delete</i> или щёлкните <i>правой кнопкой мыши</i> и в выпавшем меню выберите подходящий элемент меню.</li>
161
-<li><b>Сборка сегмента в режиме  «Собирать по запросу»</b>.  Дважды щёлкните по сегменту <i>левой кнопкой мыши</i> или щёлкните <i>правой кнопкой мыши</i> и в выпавшем меню выберите  «Собрать сегмент».</li></li></ul></p>
162
-<h3>Параметры</h3> 
163
-<p>Формат кодировки сборки и размер кадра можно выбрать через меню <b>«Последовательность» → «Собирать для предпросмотра» → «Параметры»</b>.</p>
164
-<h2>6. Маскировка эффектов</h2>
165
-<p>Маскировка эффектов позволяет применять один или несколько эффектов только к определённой пользователем части изображения</b>.</p>
166
-<img src="filter_mask.webp">
167
-<p><i>Кнопка запуска меню маскировки эффектов расположена над подсказкой «Добавить маскировку эффектов». «Открывающая маска» и «Закрывающая маска» образуют собой блок и определяют, какие эффекты будут замаскированы. На данном снимке это эффекты «Сепия» и «Пикселизация».</i></p><ol>
168
-<li> Нажмите на кнопку «Добавить маскировку эффектов» и выберите, хотите ли вы замаскировать один или сразу все эффекты.</li>
169
-<li> В подменю выберите нужный маскирующий эффект <b>Фигуры в альфа</b> или <b>Ключ яркости</b>.</li>
170
-<li> Измените параметры маскировки во вкладке редактирования эффектов в начале блока <b>Открывающая маска</b>.</li>
171
-<li> Эффекты можно перемещать в маскирующий блок и извлекать их из него.</li>
172
-
173
-</div>
174
-</div>
175
-
176
-</body>
177
-
178
-</html> 
179
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/basic_editing.html Deleted
201
 
1
@@ -1,321 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-  <title>Основы редактирования</title>
7
-  <link rel="stylesheet" href="style.css">
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div class="subject-header">Основы редактирования</div>
18
-
19
-<p>
20
-В этом разделе описывается минимальный процесс создания фильма с использованием только одной дорожки. 
21
-</p>
22
-<div id="toc"></div>
23
-
24
-<div id="toccontent">
25
-
26
-<h3>Создание нового проекта</h3>
27
-<p>
28
-Вся информация о вашем фильме хранится в файле проекта Flowblade.
29
-</p>
30
-<p>
31
-Создать новый проект можно через:
32
-</p>
33
-<ul>
34
-<li> <b>Меню:</b> в меню выберете <b>Файл -> Новый проект</b>.</li>
35
-<li> <b>Сочетания клавиш:</b> нажмите <b>Ctrl + N</b>.</li>
36
-</ul>
37
-<p>
38
-Проект содержит:
39
-</p>
40
- <ul>
41
-<li> одну или несколько последовательностей</li>
42
-<li> коллекцию медиафайлов, хранящуюся в корзинах.</li>
43
-</ul>
44
-<p>
45
-Для нового проекта можно выбрать два параметра:
46
-</p>
47
-<ul style="list-style-type:none">
48
-<li> <b>Профиль проекта</b>: Определяет кадровую частоту, размер и пропорции кадра и пикселя для всех последовательностей в проекте.</li>
49
-<li> <b>Количество дорожек</b>: Выберите количество видео и звуковых дорожек, которые будут использоваться в проекте. Изменить их количество можно позже, но помните, что эта операция необратима, она уничтожит все клипы и композиторы на монтажном столе, которые не впишутся в воссозданную версию последовательности и сотрёт историю ваших действий.</li>
50
-</ul>
51
-
52
-<div class="note">
53
-Видеоматериал автоматически подгоняется под размеры профиля, поэтому выбор профиля проекта с меньшими размерами, чем видеофайл, приведёт к снижению качества видео на выходе.
54
-</div>
55
-<div class="note">
56
-Видеоредактор Flowblade обрабатывает данные изображения внутренне как кадры YUV420, поэтому кодирование, связанное с данным профилем, не влияет на качество перед сборкой.
57
-</div>
58
-<div class="note">
59
-Для <b>сохранения качества входной материал, профиль проекта</b> и <b>профиль сборки</b> должны иметь <b>одинаковую кадровую частоту, размер и пропорции</b> кадра и пикселя.
60
-</div>
61
-
62
-<h3>Добавление и удаление новых последовательностей</h3>
63
-<p>
64
-Под понятием «Последовательность» подразумевается всё содержимое монтажного стола. Проект содержит одну или несколько последовательностей.
65
-</p>
66
-
67
-<p>
68
-В сложных проектах, для создания и управления различными частями готового продукта, иногда лучше использовать несколько последовательностей.
69
-</p>
70
-
71
-<p>
72
-<b>Добавление последовательности:</b>
73
-</p>
74
-<ul>
75
-<li> <b>С дополнительной панелью</b>: Щёлкните <b>правой кнопкой мыши</b> в области <b>«Последовательность»</b> и в сплывающем меню выберите пункт <b>«Добавить новую последовательность»</b>.</li>
76
-<li> <b>Без дополнительной панели</b>: Щёлкните <b>правой кнопкой мыши</b> во вкладке <b>«Проект»</b> в области <b>«Последовательность»</b> и в сплывающем меню выберите пункт <b>«Добавить новую последовательность»</b>.</li>
77
-<li> Или в главном меню  выберите <b>Проект →  Последовательность →  Добавить новую последовательность</b>.</li>
78
-</ul>
79
-
80
-<p>
81
-<b>Удалить последовательность</b> можно через тоже меню, через которое её добавили. Например, <b>Проект →  Последовательность →  Удалить выбранную последовательность</b>.
82
-</p>
83
-
84
-<div class="note">
85
-<p>
86
-При создании новой последовательности вы можете выбрать количество дорожек в последовательности. Изменить их количество можно позже, но помните, что эта операция необратима, она уничтожит все клипы и композиторы на монтажном столе, которые не впишутся в воссозданную версию последовательности и сотрёт историю ваших действий.
87
-</p>
88
-</div>
89
-
90
-<h3>Работа с медиафайлами</h3>
91
-
92
-<p>
93
-В видеоредакторе Flowblade файлы хранятся во вкладке <b>Медиа</b>. Слева в виде таблицы перечислены <b>Корзины</b>. Справа, в виде содержимого выбранной корзины расположены клипы. 
94
-</p>
95
-
96
-<p>
97
-Добавление медиафайлов:
98
-</p>
99
-
100
-<ol>
101
-<li> Во вкладке <b>«Медиа»</b> щёлкните правой кнопкой мыши и выберите пункт меню  <b>«Добавить видео, музыку или изображения...»</b>.
102
-<li> Или в главном меню  выберите <b>«Проект → Добавить видео, музыку или изображения…»</b>.
103
-<li> Далее с помощью диалогового окна выберете нужные медиафайлы.</li>
104
-<li> Файлы отобразятся в виде миниатюр.</li>
105
-<li> Обратите внимание, что создание миниатюр для открытых файлов займёт некоторое время.</li>
106
-</ol>
107
-
108
-<div class="note">
109
-<h3 style="margin-top:10px">Медиапроект: абсолютные и относительные пути</h3>
110
-<ul>
111
-<li> Flowblade <b>сохраняет ссылки</b> на медиафайлы, используемые в проекте, как <b>абсолютные пути</b>.</li>
112
-<li> Если медиафайл <b>не найден при загрузке</b>, Flowblade попытается найти его с тем же именем во вложенных папках относительно файла проекта.</li>
113
-<li> Так как, все медиафайлы, используемые проектом, сохраняются во вложенных папках относительно файла проекта, то, <b>файл проекта и медиафайл могут перемещаться как единое целое</b> и проект будет загружаться после копирования данных из другого места.</li>
114
-<li> <b>Файлы сборки проекта</b>, такие как переходы, <b>сохраняются по умолчанию в скрытой папке</b>: <i><Домашняя папка>/.flowblade/rendered_clips/</i>.</li>
115
-<li> Пункт меню <b>Файл -> Создать резервную копию...</b> сохраняет файл проекта, все медиа и файлы сборки в одной папке, так что, ваш проект всегда можно будет загрузить с использованием этих данных.</li>
116
-<li> <b>Сортировка поиска</b> между абсолютными и относительными путями может быть установлена в окне Настройки Flowblade.</li>
117
-<li> Инструментом <b>Медиа компоновщик</b> можно воспользоваться для устранения проблем с путями, которые могут возникнуть.</li>
118
-
119
-</ul>
120
-<p><b>ПРИМЕЧАНИЕ:</b> Информация, приведённая здесь, относится только к версиям Flowblade от 0.18 и выше.</p>
121
-</div>
122
-
123
-<h3>Работа с корзинами</h3>
124
-
125
-<p>
126
-Корзина - место для хранения медиафайлов.
127
-</p>
128
-
129
-<p>
130
-Для простых проектов корзины обычно не требуются, и вы можете скрыть панель Корзины перетаскиванием ручки между панелями.
131
-</p>
132
-
133
-<p>
134
-    <b>Добавление корзины:</b>
135
-<p>
136
-<ul>
137
-<li> <b>С дополнительной панелью</b>: Щёлкните <b>правой кнопкой мыши</b> в области корзины и в всплывающем меню выберите <b>Добавить корзину</b>.</li>
138
-<li> <b>Без дополнительной панели</b>: Во вкладке <b>Медиа</b> щёлкните <b>правой кнопкой мыши</b> в области корзины и в всплывающем меню выберите <b>Добавить корзину</b>.</li>
139
-<li> Или в главном меню выберите <b>Проект → Корзина → Добавить новую корзну</b>.</li>
140
-</ul>
141
-
142
-<p><b>Удалить корзину</b>: можно через тоже меню, через которое её добавили. Например, <b>Проект → Корзина → Удалить выбранную корзину</b>.</p>
143
-<p><b>Переименование корзины</b>: дважды щёлкните по имени корзины (корзина_№) и нажмите кдавишу Enter.</p>
144
-<p><b>Перемещение файлов в другую корзину:</b></p>
145
-<ul>
146
-<li> Перенесите содержимые файлы одной корзины на значок другой.</li>
147
-<li> Выберите файлы и откройте меню во вкладке <b>Медиа</b> слева снизу и выберите пункт меню <b>Отправить выбранное медиа в корзину</b> и выберете корзину назначения.</li>
148
-</ul>
149
-<div class="tabbed">
150
-
151
-</div>
152
-
153
-<h3>Использование монтажного стола</h3>
154
-
155
-<h4>Прокрутка монтажного стола</h4>
156
-<ul>
157
-<li> Осуществляется с помощью <b>Ползунка</b> монтажного стола</li>
158
-<li> Наведения курсора на монтажный стол и нажатием клавиши <b>Ctrl</b> + <b>колёсико мыши</b>.</li>
159
-</ul>
160
-
161
-<h4>Масштабирование монтажного стола</h4>
162
-<ul>
163
-<li> Нажатием кнопки <b>Увеличить</b>, <b>Уменьшить</b> или <b>В размер окна</b>.</li>
164
-<li> Прокруткой <b>Колёсика мыши</b> над монтажным столом. </li>
165
-</ul>
166
-
167
-<h4>Перемещение курсора монтажного стола</h4>
168
-<ul>
169
-<li> Передвиньте курсор и нажмите <b>Правой кнопки мыши</b> в пустом месте на монтажном столе, курсор монтажного стола переместится вслед за курсором мыши.</li>
170
-<li> На линейке времени монтажного стола то же, что и на монтажном столе, только с нажатием <b>Левой кнопки мыши</b>.</li>
171
-<li> Передвиньте курсор с нажатием <b>Любой кнопки мыши</b> на линейке времени монитора.</li>
172
-<li> Нажмите <b>Клавишу со стрелкой влево</b> или <b>Клавишу со стрелкой вправо</b>, чтобы перейти к следующему или предыдущему кадру.</li>
173
-<li> Нажмите <b>Клавишу со стрелкой вверх</b> или <b>Клавишу со стрелкой вниз</b>, чтобы перейти к началу или концу участка клипа на верхней активной дорожке.</li>
174
-<li> Нажмите кнопку перемотки <b>Вперёд</b> или <b>Назад</b> в области кнопок монитора, чтобы перейти к следующему или предыдущему кадру.</li>
175
-</ul>
176
-
177
-<h4>Перемещение текущего кадра при предпросмотре клипа на мониторе</h4>
178
-<ul>
179
-<li> Передвиньте курсор с нажатием <b>Любой кнопки мыши</b> на линейке времени монитора.</li>
180
-<li> Нажмите <b>Клавишу со стрелкой влево</b> или <b>Клавишу со стрелкой вправо</b>, чтобы перейти к следующему или предыдущему кадру.</li>
181
-<li> Нажмите <b>Клавишу со стрелкой вверх</b> или <b>Клавишу со стрелкой вниз</b>, чтобы перейти к началу или концу участка клипа на верхней активной дорожке.</li>
182
-<li> Нажмите кнопку перемотки <b>Вперёд</b> или <b>Назад</b> в области кнопок монитора, чтобы перейти к следующему или предыдущему кадру.</li>
183
-</ul>
184
-
185
-<h4>Переключение между монтажным столом и показом клипов</h4>
186
-<ul>
187
-<li> Нажмите одну из кнопок монитора: Отобразить текущую последовательность с монтажного стола или отобразить клип из Медиа.</li>
188
-<li> Перенесите клип из медиа на <b>Монитор</b>, чтобы отобразить клип.</li>
189
-</ul>
190
-
191
-<h4>Активные дорожки</h4>
192
-<ul>
193
-<li> В правом ряду области столбцов дорожек находятся <b>Кнопки активности дорожек</b>. <b>Кнопка со стрелкой вниз</b> указывает, что начиная с этой дорожки, дорожки расположенные ниже могут быть <b>Активными дорожками</b>.</li>
194
-</ul>
195
-
196
-<div class="note">
197
-<h4>Особенности активных дорожек</h4>
198
-<ul>
199
-<li> Разрезаются клипы только на активных дорожках.</li>
200
-<li> Вставка медиафайла, отображаемого в настоящее время на мониторе <b>Вставить клип, Склеить клип</b> или <b>Перезаписать клип</b> разместит клип на верхней активной дорожке, обозначенной стрелкой.</li>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/blender_clip_editor.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/blender_color_editor.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/blender_script.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/blender_string_editor.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/comp_clips.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/compositor.html Deleted
156
 
1
@@ -1,154 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Создание композитных клипов</title>
7
-  <link rel="stylesheet" href="style.css">
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div class="subject-header">Создание композитных клипов</div>
20
-
21
-<p>Видеоредактор Flowblade использует композиторы для объединения клипов на двух разных дорожках.</p>
22
-
23
-<div id="toc"></div>
24
-
25
-<h3>Режимы композитинга</h3>
26
-<p>Способ работы с композиторами определяется режимом композитинга. Пользователи могут выбрать режим композитинга в соответствии со своими предпочтениями или потребностями редактирования определённой последовательности.</p>
27
-<p>Чтобы установить <b>Режим композитинга</b> для последовательности, выберите его в меню <b><i>Последовательность → Режим композитинга</i></b>.</p>
28
-<h4>Свободное перемещение сверху вниз</h4>
29
-<p>Это самый мощный и сложный режим композитинга. Пользователи могут свободно выбирать дорожки назначения, перемещать композиторы и при необходимости создавать композиции дерева узлов.</p>
30
-<h4>Автосопровождение сверху вниз</h4>
31
-<p>В Flowblade 2.6 данный режим был удалён.</p>
32
-<h4>Стандартное автосопровождение</h4>
33
-<p> Композиторы автоматически сопровождают клипы источника, можно добавить только один композитор к клипу. Для всех композиторов дорожкой назначения всегда будет дорожка V1, создавать композиции дерева узлов не получится.</p>
34
-<h4>Стандартный (без композиторов)</h4>
35
-<p>Это самый простой и лёгкий в использовании режим композитинга. Композиторы не требуются. Затемнение, вытеснение и трансформации создаются с помощью эффектов. Некоторые функции композитинга недоступны. Создавать композиции дерева узлов не получится.</p>
36
-<h2>Режим «Стандартный (без композиторов)»</h2>
37
-<p>Компоновка в стандартном режиме (без композиторов) аналогична использованию слоёв в таких приложениях, как Gimp и Photoshop. Компоновка в стандартном режиме (без композиторов) происходит снизу вверх. Композиторы не используются.</p>
38
-<h3>Работа в стандартном режиме</h3>
39
-<ol>
40
-<li>Добавление клипов на монтажный стол
41
-<ul>
42
-<li>Изображения с альфа-каналом компонуются в порядке снизу вверх.</li>
43
-</ul>
44
-<li>Управление непрозрачностью изображения</li>
45
-<ul>
46
-<li> Добавьте эффект из категории <b>Уход / выход из затемнения</b> и управляя шкалой <b>Непрозрачность</b> добавьте затемнение в начале и/или в конце клипа.</li>
47
-<li> Добавьте эффект <b>Вытеснение</b> для создания перехода вытеснения.</li>
48
-</ul>
49
-<li>Трансформация изображения</li>
50
-<ul>
51
-<li>Добавьте эффект <b>Вращение</b>, <b>Наклон и сдвиг</b> или <b>Позиция и масштаб</b>.</li>
52
-</ul>
53
-</ol>
54
-<h2>Режим «Стандартное автосопровождение»</h2>
55
-<p>Компоновка в режиме стандартного автосопровождения похожа на использование слоёв в таких приложениях, как Gimp или Photoshop. Этот режим работает аналогично тому, как работает большинство других видеоредакторов.</p>
56
-<p>На монтажном столе композитор отображается в виде фиолетового прямоугольника с закругленными углами.</p>
57
-<p>Параметры, определяющие полученное изображение, редактируются во вкладке <b>Композиторы</b>.</p>
58
-<h3>Работа с композиторами</h3>
59
-<ol>
60
-<li>Выбор композитора
61
-<ul>
62
-<li> <b>Правой кнопкой мыши</b> нажмите на любой клип на дорожках с V5 по V2 и в всплывающем меню выберите, к примеру: <b>Добавить композитор → Наплыв</b> или <b>Добавить композитор → Режим смешения → Умножение</b>.</li>
63
-</ul>
64
-<li>Изменение параметров композитора во вкладке «Композиторы»</li>
65
-<ul>
66
-<li> Дважды щёлкните по композитору <b>Левой кнопкой мыши</b>.</li>
67
-<li> Щёлкните по любому композитору <b>Правой кнопкой мыши</b> и выберете «Открыть в редакторе композиторов».</li>
68
-<li> Измените параметры в открывшейся вкладке.</li>
69
-</ul>
70
-<li>Удаление композитора</li>
71
-<ul>
72
-<li> Щёлкните <b>Левой кнопкой мыши</b> по композитору для его выделения и нажмите клавишу <b>Delete</b>.</li>
73
-<li> Щёлкните <b>Правой кнопкой мыши</b> по композитору для его выделения и в всплывающем меню выберите <b>Удалить</b>.</li>
74
-</ul>
75
-</ol>
76
-<h3>ПРИМЕР: при создании композиций с использованием больше 2 дорожек композиторы размещаются на всех дорожках</h3>
77
-<p>В этом режиме во всех композиторах дорожкой назначения будет V1.</p>
78
-<p>Поэтому добавление композитора только к верхней дорожке скроет изображение на ней. </p>
79
-<p>Когда в композиции используется больше 2 дорожек, композиторы должны быть добавлены ко всем клипам, иначе мы не получим ожидаемого результата.</p>
80
-<p><i><b>Композитор размещён только на верхней дорожке</b></i></p>
81
-<img src="only_one_comp.png">
82
-<p>К клипу на дорожке V3 добавлен композитор, который объединяет его с дорожкой V1. Однако отображается клип размещённый на дорожке V2, так как именно он расположен поверх нашей композиции.</p>
83
-</p><i><b>Композиторы размещены на всех дорожках</b></i></p>
84
-<img src="all_comp.png">
85
-<p>
86
-Изображения на всех дорожках комбинируются на дорожке V1, мы получаем ожидаемый результат.
87
-</p>
88
-<h2>Режим «Свободное перемещение сверху вниз»</h2>
89
-<p>В этом режиме композиторы имеют дорожку источника и дорожку назначения.</p></p>
90
-<p>На монтажном столе композитор отображается в виде тёмного прямоугольного объекта поверх двух дорожек. Дорожка источника всегда находится над композитором, но дорожка назначения может быть любой из дорожек ниже.</p>
91
-<p>Параметры, определяющие полученное изображение, редактируются во вкладке <b>Композиторы</b>.</p>
92
-<h3>Работа с композиторами</h3>
93
-<p>Комбинируя несколько композиторов на нескольких дорожках можно получить сложные композитные кадры.</p>
94
-<ol>
95
-<li>Выбор композитора
96
-<ul>
97
-<li> <b>Правой кнопкой мыши</b> нажмите на любой клип на дорожках с V5 по V2 и в всплывающем меню выберите, к примеру: <b>Добавить композитор→Наплыв</b> или <b>Добавить композитор→Режим смешения→Умножение</b>.</li>
98
-</ul>
99
-<li>Изменение размера и перемещение композитора</li>
100
-<ul>
101
-<li> На монтажном столе <b>Левой кнопкой мыши</b> нажмите на композитор и переместите его левую или правую сторону внутрь композитора - при обрезке, или наружу - при растягивании.</li>
102
-<li> <b>Левой кнопкой мыши</b> нажмите на композитор и переместите его в нужное место на монтажном столе.</li>
103
-</ul>
104
-<li>Изменение параметров композитора во вкладке «Композиторы»</li>
105
-<ul>
106
-<li> Дважды щёлкните по композитору <b>Левой кнопкой мыши</b>.</li>
107
-<li> Щёлкните по любому композитору <b>Правой кнопкой мыши</b> и выберете «Открыть в редакторе композиторов».</li>
108
-<li> Измените параметры в открывшейся вкладке.</li>
109
-</ul>
110
-<li>Удаление композитора</li>
111
-<ul>
112
-<li> Щёлкните <b>Левой кнопкой мыши</b>, по композитору для его выделения и нажмите клавишу <b>Delete</b>.</li>
113
-<li> Щёлкните <b>Правой кнопкой мыши</b>, по композитору для его выделения и в всплывающем меню выберите <b>Удалить</b>.</li>
114
-</ul>
115
-</ol>
116
-<h3>Сборка композиций в режимах композитинга сверху вниз</h3>
117
-<p>В видеоредакторе Flowblade <b>порядок сборки композиций выполняется сверху вниз</b>, а не снизу вверх как в Gimp или Photoshop.</p>
118
-<p>На первый взгляд такой метод сборки, особенно при создании определённых типов составных видеоклипов, может показаться не интуитивным, если конечно, не знать о порядке покадровой сборки композита.</p>
119
-<h4>Покадровая сборка композита</h4>
120
-<ol>
121
-<li>Проверяется каждый кадр на наличие перекрывающего его композитора на самой верхней дорожке.</li>
122
-<li>Если композитор найден композиция собирается на дорожке назначения.</li>
123
-<li>Кадр на дорожке назначения теперь изменён и если он используется как источник, то используется его изменённая версия.</li>
124
-<li>Если на следующей дорожке ниже имеется кадр и если композитор найден, создаётся составной клип.</li>
125
-<li>Эта операция выполняется для каждой дорожки.</li>
126
-<li>Выходное изображение подключено к верхней дорожке с клипом и не имеет композитора в кадре.</li>
127
-</ol>
128
-<h3>ПРИМЕР: Создание трёхслойного составного клипа</h3>
129
-<p style="margin-bottom:45px" >В этом примере мы продемонстрируем, как расположение клипа и композитора влияет на композицию в целом. Мы попытаемся разместить изображение с пингвином Tux поверх двухцветного фона, сделанного сочетанием зелёных и синих цветовых клипов с использованием типа вытеснения «Свободные полосы».</p>
130
-<h4>Элементы медиа и желаемый результат</h4>
131
-<p>Чтобы начать работу с прозрачностью, рисунок «Пингвин Tux.png» должен компоноваться с использованием композитора «Наплыв».</p>
132
-<p><i><b>Цветовые клипы СИНИЙ и ЗЕЛЁНЫЙ и графический рисунок «Пингвин Tux.png» с альфа-каналом</b></i></p>
133
-<img src="comp_clips.png">
134
-<p><i><b>Желаемый результат</b></i></p>
135
-<img style="margin-bottom:45px" src="correct_comp.png">
136
-<h4>Порядок расположения клипов, подобно расположению изображения в Gimp или в Photoshop даст неверный результат.</h4>
137
-<p>Здесь мы разместили клипы на дорожках, подобно тому, как они должны быть размещены в Gimp.</p>
138
-<p><i><b>Неправильное расположение (как Gimp)</b></i></p>
139
-<img src="wrong_timeline.png">
140
-<p>Что здесь происходит? «Пингвин Tux.png» компонуется на «Зелёный» цветовой клип, а результирующее изображение компонуется с помощью «Свободных полос», сверху вытесняющего «Синий» цветовой клип. В итоге получаем неверный результат.</p>
141
-<p><i><b>Неверный результат</b></i></p>
142
-<img  style="margin-bottom:45px" src="wrong_comp.png">
143
-<h4>Правильный порядок клипов и композиторов при упорядочивании сверху вниз.</h4>
144
-<p>Здесь для получения желаемого результата, мы установили клипы в правильном порядке.</p>
145
-<p><i><b>Правильное расположение</b></i></p>
146
-<img src="correct_timeline.png">
147
-<p>«Зелёный» цветовой клип сначала компонуется с использованием «Свободных полос» вытесняя «Синий» цветовой клип. После этого «Пингвин Tux.png» компонуется поверх полученного изображения (которое уже отображается на дорожке V1), используя «Наплыв» для получения выходного изображения.</p>
148
-<p><i><b>Дорожка назначения в композиторе «Область» - V1, дорожка источника - V3</b></i></p>
149
-<img src="correct_dest.png">
150
-<p><i><b>Получаем желаемый результат</b></i></p>
151
-<img style="margin-bottom:45px" src="correct_comp.png">
152
-</div>
153
-</body>
154
-
155
-</html> 
156
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/container_clips.html Deleted
201
 
1
@@ -1,274 +0,0 @@
2
- <!DOCTYPE html>
3
-<html>
4
-<head>
5
-  <title>Контейнерные клипы</title>
6
-  <link rel="stylesheet" href="style.css">
7
-<script src="toc.js" type="text/javascript"></script>
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png">
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div class="subject-header">Контейнерные клипы</div>
20
-
21
-
22
-
23
-<div id="toc"></div>
24
-
25
-<h2>Определение контейнерного клипа</h2>
26
-<p>
27
-<b>Контейнерный клип</b> — это медиаэлемент и созданный на его основе клип монтажного стола состоящий из трёх компонентов, упакованных вместе в единый объект: <i>программа, несобранное медиа</i> и <i>собранное медиа</i>.
28
-</p>
29
-<h3>Компоненты</h3>
30
-<ol>
31
-<li><b>Несобранное медиа</b> — несобранное на монтажном столе медиа, которое не отображается в окне просмотра.</li>
32
-<li><b>Программа</b> — данные о сборке клипа на монтажном столе, иногда использующие несобранное медиа в качестве входного материала.</li>
33
-<li><b>Собранное медиа</b> — собранное на монтажном столе медиа, которое отображается в окне просмотра.</li>
34
-</ol>
35
-<h2>Обоснование</h2>
36
-<ul>
37
-<li><b>Производительность</b> 
38
-<p>Контейнерные клипы предоставляют средства для преобразования ресурсоёмких элементов мультимедиа, таких как последовательность клипов, в собранные медиа</p>
39
-</li>
40
-<li><b>Управление ресурсами</b> <p>Например, проектами Blender и сценариями G'Mic можно управлять благодаря их доступности через контейнеры.</p></li>
41
-<li><b>Расширение возможностей</b> <p>Существующие технологии и приложения могут быть созданы для обеспечения функциональности, недоступной в противном случае. В будущем будет больше событий в этой области.</p></li>
42
-<li><b>Взаимообмен</b> <p>В будущем будет создан центральный репозиторий для совместного использования ресурсов контейнерных клипов.</p></li>
43
-</ul>
44
-<h2>Рабочий процесс</h2>
45
-<ol>
46
-<li>Создание контейнерного клипа через меню <b>Проект → Создать контейнерный клип</b>.</li>
47
-<li>Правка контейнерного клипа осуществляется щелчком по нему правой кнопкой мыши и выбором <b>Править данные контейнерного клипа</b> если данные доступны.</li>
48
-<li>Добавление контейнерного клипа на монтажный стол.</li>
49
-<li>Сборка и управление контейнерными клипами на монтажном столе осуществляется щелчком по нему правой кнопкой мыши и выбором подменю <b>Действия с контейнерным клипом</b>.</li>
50
-</ol>
51
-
52
-<h2>Типы контейнерных клипов</h2>
53
-<h3>Контейнерный клип из сценария G'Mic</h3>
54
-
55
-<h5>Компоненты</h5>
56
-<p>
57
-<ul style="list-style-type:none">
58
-<li><b>Несобранное медиа</b> — видеоклип.</li>
59
-<li><b>Программа</b> — сценарий G'Mic созданный и сохранённый в инструменте G'Mic.</li>
60
-<li><b>Собранное медиа</b> — собранный клип с применённым эффектом G'Mic.</li>
61
-</ul>
62
-</p>
63
-<p>
64
-<h5>Случаи использования</h5>
65
-<ul>
66
-<li>Сборка эффектов G'Mic только на участках клипов, используемых на монтажном столе.</li>
67
-<li>Упрощение использования одного пользовательского эффекта G'Mic для нескольких клипов.</li>
68
-</ul>
69
-
70
-<h5>Создание контейнерного клипа из сценария G'Mic</h5>
71
-
72
-<ol>
73
-<li>Откройте <b>инструмент G'Mic</b>.</li>
74
-<li>Создайте сценарий эффекта G'Mic. См. раздел <b>Эффекты G'Mic</b> в главе <b>Автономные инструменты</b>.</li>
75
-<li>Нажмите на кнопку <b>Сохранить сценарий</b> в левом нижнем углу и сохраните эффект.</li>
76
-<li>Выберите в меню <b>Проект → Создать контейнерный клип → из сценария G'Mic</b>.</li>
77
-<li>Выберите сценарий, который вы сохранили и клип, к которому он будет применён для создания контейнера.</li>
78
-</ol>
79
-
80
-<h3>Контейнерный клип из проекта Blender</h3>
81
-<h5>Компоненты</h5>
82
-
83
-<p>
84
-<ul style="list-style-type:none">
85
-<li><b>Несобранное медиа</b> — заполнитель видеоклипа, созданный при создании элемента медиа.</li>
86
-<li><b>Программа</b> — файл проекта с расширением *blend.</li>
87
-<li><b>Собранное медиа</b> — клип собранный из файла проекта.</li>
88
-</ul>
89
-</p>
90
-<h5>Случаи использования</h5>
91
-<ul>
92
-<li>Управление проектами Blender, с помощью дескрипторов Flowblade.</li>
93
-<li>Создание редакторов в проектах Blender, чтобы иметь возможность правки свойств в Flowblade</li>
94
-<li>Возможность внесения изменений и обмена интересными проектами Blender. Например, приятными текстовыми эффектами.</li>
95
-</ul>
96
-
97
-<h5> Создание контейнерного клипа из проекта Blender</h5>
98
-
99
-<ol>
100
-<li>Выберите в меню <b>Проект → Создать контейнерный клип → из проекта Blender</b> и выберите файл проекта Blender с расширением <i>.blend</i>.</li>
101
-<li>При необходимости отредактируйте значения проекта Blender см. раздел <b>Правка контейнерной программы</b>.</li>
102
-</ol>
103
-
104
-<h3>Создание контейнерного клипа из выбранного</h3>
105
-<h5>Компоненты</h5>
106
-<p>
107
-<ul style="list-style-type:none">
108
-<li><b>Несобранное медиа</b> видеоклип MLT XML, созданный из выбранных клипов или последовательности, подобной составным клипам ранее.</li>
109
-<li><b>Программа</b> видеоклип MLT XML, созданный из выбранных клипов или последовательности, подобной составным клипам ранее. Здесь программа та же, что в несобранных медиа </li>
110
-<li><b>Собранное медиа</b> Собранный клип из видеоклипа MLT XML.</li>
111
-</ul>
112
-</p>
113
-<h5>Случаи использования</h5>
114
-
115
-<ul>
116
-<li>Возможность создания медиаэлементов из выбранных клипов или последовательностей.</li>
117
-<li>Улучшение производительности монтажного стола для сложных многодорожечных контейнерных клипов, с предварительной их сборкой на монтажном столе.</li>
118
-</ul>
119
-
120
-<h5>Создание контейнерного клипа из выбранного</h5>
121
-
122
-<ol>
123
-<li> Выберите от двух до нескольких соседних клипов на одной дорожке.</li>
124
-<li> Выберите <b>Проект → Создать контейнерный клип → Из выбранных клипов</b>.</li>
125
-<li> Новый элемент медиа появится в текущей корзине.</li>
126
-</ol>
127
-
128
-<h5>Создание контейнерного клипа из последовательности</h5>
129
-
130
-<ol>
131
-<li> Выберите Проект → Создать контейнерный клип → Из текущей последовательности</b>.</li>
132
-<li> Новый элемент медиа появится в текущей корзине.</li>
133
-</ol>
134
-
135
-<h5> Синхронизация звука слиянием 2 клипов</h5>
136
-
137
-<ol>
138
-<li> Выберите два элемента мультимедиа во вкладке Медиа.</b>
139
-   <ul>
140
-   <li> Предполагается, что вы выберете <b>1 видео и 1 звуковой клип</b>.</li>
141
-   <li> При выборе <b>двух видеоклипов</b>, в зависимости от порядка выбора, один видеоклип будет обработан как видео, другой как звук.
142
-   <li> Звук в клипе, обработанном как видео, отключится.</li>
143
-   </ul>
144
-</li>
145
-<li> Выберите <b>Проект → Создать контейнерный клип → Синхронизация звука слиянием 2 клипов.</b></li>
146
-<li> Если звуковая синхронизация прошла успешно, появится диалоговое окно. В диалоговом окне, присвойте имя новому элементу медиа.</li>
147
-<li> Новый элемент медиа появится в текущей корзине.</li>
148
-</ol>
149
-
150
-<div class="note">
151
-Во время звуковой синхронизации идёт поиск на наилучшее математическое соответствие между двумя звуковыми сигналами, поэтому <b>использование несоответствующего звука приведёт к случайным результатам</b>.
152
-</div>
153
-
154
-<h2>Создание редакторов в контейнерной программе Blender</h2>
155
-
156
-<p>
157
-В контейнерных клипах Blender можно создавать и добавлять редакторы, которые позволяют пользователям изменять клип на выходе.
158
-</p>
159
-<p>
160
-Функция использует Blender Python API и запускает сценарий перед выводом данных для изменения значений атрибутов объектов сцены Blender
161
-</p>
162
-<p>
163
-Это продвинутая функция, требующая практических знаний по написанию сценариев с использованием Python API Blender.
164
-</p>
165
-
166
-<h4>Редактируемые объекты</h4>
167
-<p>
168
-В настоящее время, для редактирования, доступно три типа объекта:
169
-</p>
170
-<ul>
171
-<li> <b>Объекты</b> — это объекты  словаря <b>bpy.data.objects</b>, доступтные для сценария Python;</li>
172
-<li> <b>Кривые</b> — это объекты  словаря <b>bpy.data.curves</b>, доступтные для сценария Python;</li>
173
-<li> <b>Материалы</b> — это объекты  словаря  <b>bpy.data.materials</b>, доступтные для сценария Python.</li>
174
-</ul>
175
-
176
-<h4>Редакторы</h4>
177
-<p>
178
-В настоящее время, для редактирования атрибутов объектов, доступны пять различных типов редакторов:
179
-</p>
180
-<ul>
181
-<li> Редактор <b>строк</b> выводит строку в кавычках в сценарии запуска;</li>
182
-<li> Редактор <b>целого числа</b> выводит целое число в сценарии запуска;</li>
183
-<li> Редактор <b>плавающей</b>  выводит число с плавающей запятой в сценарии запуска;</li>
184
-<li> Редактор <b>цвета</b> выводит последовательность из 4 чисел, разделённых запятыми, которые определяют цвет;</li>
185
-<li> Редактор <b>значений</b> выводит строку без кавычек в сценарии запуска. Это может быть использовано в качестве значения для любого атрибута.</li>
186
-</ul>
187
-
188
-<h3>Пример</h3>
189
-<p>
190
-В этом примере мы создаём редакторы <b>строк</b> и <b>цвета</b> для изменения текста и цвета, отображаемых в проекте Blender.
191
-</p>
192
-<h4>Шаг 1: Установка имён объектов и атрибутов с помощью сценария Blender</h4>
193
-<p>
194
-<img src="blender_script.png">
195
-</p>
196
-<p>
197
-<i>Панель сцен и сценариев Blender с открытым тестовым проектом.</i>
198
-</p>
199
-<p>
200
-Здесь мы установили, что:
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/correct_comp.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/correct_dest.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/correct_timeline.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/edit_tools.html Deleted
201
 
1
@@ -1,419 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Инструменты редактирования и режим работы</title>
7
-  <link rel="stylesheet" href="style.css">
8
-  <META CHARSET="UTF-8">
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-
15
-<img src="header_text_5.png" >
16
-
17
-<script src="tocgen.js"></script>
18
-
19
-<div class="subject-header">Инструменты редактирования и режим работы</div>
20
-
21
-<p>
22
-Видеоредактор Flowblade предостовляет 10 инструментов редактирования, <b>4 инструмента перемещения</b>, <b>4 инструмента обрезки</b>, <b>инструмент Резка</b> и <b>инструмент Ключевой кадр</b>.
23
-</p>
24
-
25
-<div id="toccontent">
26
-<div id="toc"></div>
27
-
28
-<h2>Конфигурация режима работы</h2>
29
-
30
-<p>
31
-Flowblade предлагает настраиваемый режим работы с выбором набора инструментов и поведения монтажного стола.
32
-</p>
33
-
34
-<p>
35
-Режим работы настраивается из меню, запускаемого нажатием на значок <img src="workflow.png">.
36
-</p>
37
-
38
-<p>
39
-Из представленного списка инструментов можно выбрать 9 присвоив каждому порядковый номер. Выбранный инструмент с первым номером автоматически станет инструментом по умолчанию.
40
-</p>
41
-
42
-<p>
43
-Также в режиме работы можно выбрать автосопровождение композитора за их исходными клипами и включать или отключать подсказки по работе с инструментами.
44
-</p>
45
-
46
-<p>
47
-Предустановлено всего два режима работы.
48
-</p>
49
-
50
-
51
-<h3>Предустановленные режимы работы</h3>
52
-<p>
53
-<h4><b>Стандартный</b></h4>
54
-</p>
55
-<p>
56
-«Стандартный» режим работы предлагает инструмент <b>Перемещение</b> в качестве инструмента по умолчанию, а сам режим работы схож с работой большинства видеоредакторов.
57
-</p>
58
-<p>
59
-<b>Инструменты:</b> <b>Перемещение</b>, <b>Мультиобрезка</b>, <b>Распорка</b>, <b>Вставка</b>, <b>Резка</b>, <b>Ключевой кадр</b>.
60
-</p>
61
-<p>
62
-<b>Поведение:</b> В действиях перемещения выбран пункт <i>«Перезаписывать пробелы»</i>, <i>«Автосопровождение композитора»</i> отключено.
63
-</p>
64
-<p>
65
-<h4><b>В стиле фильма</b></h4>
66
-</p>
67
-<p>
68
-Режим работы «В стиле фильма» предлагает инструмент <b>Вставка</b> в качестве инструмента по умолчанию и использует редактирование со склейкой. Этот режим работы использовался в предыдущих версиях приложения.
69
-</p>
70
-<p>
71
-<b>Инструменты:</b> <b>Вставка</b>, <b>Перемещение</b>, <b>Обрезка</b>, <b>Прокрутка</b>, <b>Скольжение</b>, <b>Распорка</b>, <b>Коробка</b>.
72
-</p>
73
-<p>
74
-<b>Поведение:</b> В действиях перемещения выбран пункт <i>«Перезаписывать пробелы, кроме дорожки V1»</i>, <i>«Автосопровождение композитора»</i> отключено.
75
-</p>
76
-
77
-<h3>Управление набором инструментов</h3>
78
-
79
-<ol>
80
-<li>Запуск всплывающего меню настройки режима работы</li>
81
-   <ul>
82
-   <li> Нажмите на значок <img src="workflow.png">.</li>
83
-   </ul>
84
-<li>Включение и выключение инструментов </li>
85
-   <ul>
86
-   <li> Наведите курсор на инструмент и выберите <b><i>«Использовать инструмент»</i></b>
87
-   </ul>
88
-<li>Присвоение номера инструменту</li>
89
-   <ul>
90
-   <li> Наведите курсор на <b><i>инструмент</i> → <i>Присвоить номер</i></b>, выберите порядковый номер под которым будет значится инструмент.</li>
91
-   </ul>
92
-</ol>
93
-
94
-<h3>Настройка поведения монтажного стола</h3>
95
-
96
-<ol>
97
-<li>Запуск всплывающего меню настройки режима работы</li>
98
-   <ul>
99
-   <li> Нажмите на значок <img src="workflow.png">.</li>
100
-   </ul>
101
-    
102
-<li>Выбор поведения drag'n'drop в подменю <b>Поведение → Действия перемещения</b></li>
103
-
104
-<ul>
105
-<li>При выборе <i>«Перезаписывать пробелы»</i>:</li>
106
-<ul>
107
-<li> Перемещаемый клип перезапишет, как доступное пустое пространство, так и определённое количество кадров, уже размещённого на монтажном столе клипа.</li>
108
-</ul>
109
-<li>При выборе <i>«Перезаписывать пробелы, кроме дорожки V1»</i>:</li>
110
-<ul>
111
-<li> На дорожке V1 клип будет вставлен на дорожку на ближайшем срезе.</li>
112
-<li> На дорожках, кроме V1:.</li>
113
-<ul>
114
-<li> Клип будет вставлен, даже если попадает на уже размещённый клип.</li>
115
-<li> Перемещаемый клип перезапишет, как доступное пустое пространство, так и определённое количество кадров, уже размещённого на монтажном столе клипа.</li>
116
-</ul>
117
-</ul>
118
-<li>При выборе <i>«Не перезаписывать пробелы»</i>:</li>
119
-<ul>
120
-<li> Клип будет вставлен на дорожку на ближайшем срезе.</li>
121
-</ul>
122
-</ul>
123
-
124
-<li>Установка поведения «Композитора» с контрольным элементом <b>Автосопровождение композитора</b></li>
125
-<ul>
126
-<li> При <i>«Выкл.»</i>:</li>
127
-<ul>
128
-<li> Композиторы не будут следовать за своими клипами.</li>
129
-<li> Композиторы можно свободно перемещать и обрезать.</li>
130
-</ul>
131
-<li>  При <i>«Вкл.»</i>:</li>
132
-<ul>
133
-<li> Композиторы будут следовать за своими клипами.</li>
134
-<li> Композиторы нельзя свободно перемещать и обрезать.</li>
135
-<ul>
136
-</ul>
137
-</ul>
138
-
139
-</ol>
140
-
141
-<h2>Выбор инструментов</h2>
142
-
143
-<p>
144
-Используйте выпадающее меню <b>Переключателя инструментов</b> или клавиши <b>1 - 9</b>.
145
-</p>
146
-
147
-<div class="note">
148
-<b>Используйте горячие клавиши!</b> Гораздо удобнее и быстрее использовать клавиши <b>1 - 9</b>  для смены инструментов. Обратите внимание, что с помощью клавиш менять инструменты можно, только, если курсор находится в фокусе монтажного стола. 
149
-</div>
150
-
151
-<h2>Инструменты перемещения</h2>
152
-
153
-<a id="insert"></a>
154
-<h3>Вставка</h3>
155
-
156
-<p>
157
- С помощью инструмента «Вставка» можно вставить клип на начало дорожки, или соединить один или несколько клипов и вставить их в желаемом срезе на дорожке. 
158
-</p>
159
-
160
-<ol>
161
-<li>Выбор клипа</li>
162
-   <ul>
163
-   <li><b>Левой кнопкой мыши</b> нажмите на клип.</li>
164
-   </ul>
165
-<li>Выбор группы клипов</li>
166
-   <ul>
167
-   <li> Нажмите <b>Ctrl + Левой кнопкой мыши</b> по тому клипу, который будет использоваться в качестве второй стороны группы клипов для вставки.</li>
168
-   </ul>
169
-<li>Перенос клипа (группы клипов) в новое место</li>
170
-   <ul>
171
-   <li> Нажмите <b>Левой кнопки мыши</b> на клип (группу клипов) и перенесите его в новое место.</li>
172
-   <li> Жёлтая стрелка указывает на место вставки.</li>
173
-   <li> Также можно переместить клипы на другую дорожку.</li>
174
-   </ul>
175
-</ol>
176
-
177
-<p>
178
-ИЗМЕНЕНИЕ ДЛИТЕЛЬНОСТИ КЛИПА.
179
-</p>
180
-
181
-<ol>
182
-<li>Поместите курсор возле среза клипа</li>
183
-   <ul>
184
-   <li>Когда курсор изменится на горизонтальную стрелку с вертикальной полосой, вы можете изменить размер клипа.</li>
185
-   </ul>
186
-<li>Протяните срез клипа с нажатием <b>левой кнопкой мыши</b> в желаемом направлении.</li>
187
-   <ul>
188
-   <li> При увеличении длительности клипа произойдёт перезапись пробелов и пустого пространства</li>
189
-   </ul>
190
-   <ul>
191
-   <li> При увеличении длительности клипа произойдёт вставка на другие клипы</li>
192
-   </ul>
193
-   <ul>
194
-   <li> При уменьшении длительности клипа выполнится склейка с соседним клипом.</li>
195
-   </ul>
196
- </ol> 
197
-
198
-<a id="overwrite"></a>
199
-<h3>Перемещение</h3>
200
-
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/encoding.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/filtering.html Deleted
73
 
1
@@ -1,71 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Видео и звуковые эффекты</title>
7
-  <link rel="stylesheet" href="style.css">
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div class="subject-header">Видео и звуковые эффекты</div>
20
-
21
-<p>
22
-Эффектами в видеоредакторе Flowblade можно воспользоваться для внесения изменений в свойства звуковых и видео данных оригинального материала.
23
-</p>
24
-
25
-
26
-<div id="toc"></div>
27
-
28
-<h3>Работа с эффектами</h3>
29
-
30
-
31
-<h4>  Добавление эффекта</h4>
32
-   <ul>
33
-<li> Щёлкните <b>Правой кнопкой мыши</b> по нужному клипу и выберите из всплывающего меню, например, <b>Добавить эффект→Размывание→Пикселизация</b>.</li>
34
-<li> Во вкладке <b>Эффекты</b> дважды щёлкните по эффекту в текущем списке эффектов.</li>
35
-<li> Во вкладке <b>Эффекты</b> нажмите на кнопку добавить эффект в стек эффектов клипа.</li>
36
-   </ul>
37
-
38
-<h4> Открытие вкладки "Эффекты" для редактирования эффектов</h4>
39
-   <ul>
40
-<li> Щёлкните <b>Правой кнопкой мыши</b> по нужному клипу и в всплывающем меню, выберите <b>Открыть в редакторе эффектов</b>.</li>
41
-<li> <b>Дважды щёлкните</b> по нужному клипу.</li>
42
-   </ul>
43
-
44
-<h4> Изменение параметров</h4>
45
-   <ul>
46
-<li>Параметры, эффектов изменяются во вкладке «Эффекты»</li>
47
-<li> На клипах, с добавленным эффектом, будет отображаться небольшой значок в верхнем правом углу.</li>
48
-<li> Если клип редактируется, то также будет отображаться значок серого эффекта в центре клипа. </li>
49
-<li>Эффекты, изменяющие альфа-канал, будут работать только в том случае, если клип, к которому они прикреплены, смешивается с другими клипами с помощью композитора.</li>
50
-   </ul>
51
-
52
-<h4> Клонирование эффектов из других клипов</h4>
53
-   <ul>
54
-<li> Щёлкните <b>Правой кнопкой мыши</b> по нужному клипу и в всплывающем меню выберите <b>Клонировать эффект→Из следующего клипа</b> или <b>Клонировать эффект→Из предыдущего клипа</b>.</li>
55
-   </ul>
56
-
57
-<h4> Удаление эффектов из клипов</h4>
58
-   <ul>
59
-<li> Выберите эффект в стеке эффектов клипа и нажмите кнопку <b>Удалить</b>.</li>
60
-<li> Выберите эффект в стеке эффектов клипа и нажмите клавишу <b>Delete</b>.</li>
61
-<li> Выберите клип или участок клипа на монтажном столе и в всплывающем меню выберите <b>Удалить эффекты</b>.</li>
62
-   </ul>
63
-
64
-
65
-
66
-</div>
67
-
68
-</div>
69
-
70
-</body>
71
-
72
-</html> 
73
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/filters_list.html Deleted
201
 
1
@@ -1,705 +0,0 @@
2
-
3
- <!DOCTYPE html>
4
-<html>
5
-<head>
6
-<title>Список эффектов</title>
7
-<link rel="stylesheet" href="style.css">
8
-</head>
9
-
10
-<body>
11
-
12
-<div id="content">
13
-<img src="header_text_5.png" >
14
-<script src="tocgen.js"></script>
15
-<div class="subject-header">Эффекты Flowblade</div>
16
-<br/>
17
-<div id="toc"></div>
18
-<br/>
19
-<div id="toccontent">
20
-
21
- <h2>Альфа</h2>
22
-<div class="filter">
23
-        <div class="filter-name"><b>Эффект: </b>Блуждающая маска</div>
24
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Тип маски  (Кривые по точкам, Прямые по точкам)<div class="filter-value">Кривые по точкам</div></div>
25
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Режим (Альфа, Яркостный, RGB)   <div class="filter-value">Альфа</div></div>
26
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Режим альфа (Очищение, Добавление, Вычитание)   <div class="filter-value">Очищение</div></div>
27
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Инвертировать   <div class="filter-value">0</div></div>
28
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Растушёвка   <div class="filter-value">0</div></div>
29
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Проходов растушёвки   <div class="filter-value">1</div></div>
30
-</div>
31
-<div class="filter">
32
-        <div class="filter-name"><b>Эффект: </b>Выделение по цвету</div>
33
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Цвет   <div class="filter-value">#00ff00</div></div>
34
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Инвертировать   <div class="filter-value">0</div></div>
35
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Подпространство    <div class="filter-value">0.0</div></div>
36
-        <div class="filter-property"><b>Параметр по умолчанию: </b>R/A/Оттенок   <div class="filter-value">0=0.2</div></div>
37
-        <div class="filter-property"><b>Параметр по умолчанию: </b>G/B/Цветность   <div class="filter-value">0=0.2</div></div>
38
-        <div class="filter-property"><b>Параметр по умолчанию: </b>B/I/I   <div class="filter-value">0=0.2</div></div>
39
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Режим контура (Жёсткий:0.0,Толстый:0.35,Обычный:0.60,Тонкий:1.0)   <div class="filter-value">0.0</div></div>
40
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Фигура (Прямоугольнк:0.0,Эллипс:0.5,Ромб:1.0)  <div class="filter-value">0.0</div></div>
41
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Операция (Перезапись:0.0,Макс:0.3,Мин:0.5,Добавление:0.7,Вычитание:1.0)   <div class="filter-value">0.0</div></div>
42
-</div>
43
-<div class="filter">
44
-        <div class="filter-name"><b>Эффект: </b>Вытеснение</div>
45
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Тип вытеснения (50 файлов каше) <div class="filter-value">По горизонатали из центра</div></div>
46
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Порог    <div class="filter-value">50</div></div>
47
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Мягкость   <div class="filter-value">0</div></div>
48
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Инвертировать   <div class="filter-value">0</div></div>
49
-</div>
50
-<div class="filter">
51
-        <div class="filter-name"><b>Эффект: </b>Градиент Альфа</div>
52
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Позиция   <div class="filter-value">0=0.5</div></div>
53
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Ширина градиента   <div class="filter-value">0=0.5</div></div>
54
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Наклон   <div class="filter-value">0=0.5</div></div>
55
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Мин.   <div class="filter-value">0=0</div></div>
56
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Макс.   <div class="filter-value">0=1</div></div>
57
-</div>
58
-<div class="filter">
59
-        <div class="filter-name"><b>Эффект: </b>Кадрирование</div>
60
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Слева   <div class="filter-value">0</div></div>
61
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Справа   <div class="filter-value">0</div></div>
62
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Сверху   <div class="filter-value">0</div></div>
63
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Снизу   <div class="filter-value">0</div></div>
64
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Размывание   <div class="filter-value">0</div></div>
65
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Инвертировать   <div class="filter-value">1</div></div>
66
-</div>
67
-<div class="filter">
68
-        <div class="filter-name"><b>Эффект: </b>Ключ Яркости</div>
69
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Порог   <div class="filter-value">128</div></div>
70
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Крутизна   <div class="filter-value">0</div></div>
71
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Низкий уровень   <div class="filter-value">0</div></div>
72
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Высокий уровень   <div class="filter-value">255</div></div>
73
-</div>
74
-<div class="filter">
75
-        <div class="filter-name"><b>Эффект: </b>Модификация альфа</div>
76
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Операция (Сохранить:0.21,Жёсткое сжатие:0.36,Мягкое сжатие:0.50,Жёсткое увеличение:0.64,Мягкое увеличение:0.79)  <div class="filter-value">0.21</div></div>
77
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Сумма   <div class="filter-value">0=0.5</div></div>
78
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Инвертировать   <div class="filter-value">0</div></div>
79
-</div>
80
-<div class="filter">
81
-        <div class="filter-name"><b>Эффект: </b>Нерозрачность</div>
82
-        <div class="filter-property"><b>Параметр по умолчанию: </b> Непрозрачность   <div class="filter-value">100</div></div>
83
-</div>
84
-<div class="filter">
85
-        <div class="filter-name"><b>Эффект: </b>Подавление рассеивания</div>
86
-        <div class="filter-property"><b>Параметр по умолчанию: </b> Подавлять (Зелёный:0.0,Синий:1.0)   <div class="filter-value">0.0</div></div>
87
-</div>
88
-<div class="filter">
89
-        <div class="filter-name"><b>Эффект: </b>Фигуры в альфа</div>
90
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Фигура (Прямоугольник:0.0,Эллипс:0.32,Треугольник:0.68,Ромб:1.0)   <div class="filter-value">0.0</div></div>
91
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Позиция по X   <div class="filter-value">0=0.5</div></div>
92
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Позиция по Y   <div class="filter-value">0=0.5</div></div>
93
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Ширина   <div class="filter-value">0=0.5</div></div>
94
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Высота   <div class="filter-value">0=0.5</div></div>
95
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Наклон   <div class="filter-value">0=0.5</div></div>
96
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Ширина перехода   <div class="filter-value">0=0.2</div></div>
97
-</div>
98
-<div class="filter">
99
-        <div class="filter-name"><b>Эффект: </b>Хромакей</div>
100
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Основной цвет   <div class="filter-value">#00ff00</div></div>
101
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Отклонение   <div class="filter-value">0.15</div></div>
102
-</div>
103
-<!-- Движение -->
104
-<h2>Движение</h2>
105
-<div class="filter">
106
-        <div class="filter-name"><b>Эффект: </b>Балтан (без параметров)</div>
107
-</div>
108
-<div class="filter">
109
-        <div class="filter-name"><b>Эффект: </b>Головокружение</div>
110
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Шаг фазы   <div class="filter-value">0=0.02</div></div>
111
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Масштаб   <div class="filter-value">0=0.202</div></div>
112
-</div>
113
-<div class="filter">
114
-        <div class="filter-name"><b>Эффект: </b>Нервозность (без параметров)</div>
115
-</div>
116
-<div class="filter">
117
-        <div class="filter-name"><b>Эффект: </b>Стоп-кадр</div>
118
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Номер кадра   <div class="filter-value">0</div></div>
119
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Остановить за   <div class="filter-value">0</div></div>
120
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Остановить до   <div class="filter-value">0</div></div>
121
-</div>
122
-<!-- Звук -->
123
-<h2>Звук</h2>
124
-<div class="filter">
125
-        <div class="filter-name"><b>Эффект: </b>Громкость</div>
126
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Громкость  <div class="filter-value">0=1.0</div></div>
127
-</div>
128
-<div class="filter">
129
-        <div class="filter-name"><b>Эффект: </b>Моно в стерео</div>
130
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс  <div class="filter-value">1</div></div>
131
-</div>
132
-<div class="filter">
133
-        <div class="filter-name"><b>Эффект: </b>Нормализация</div>
134
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Режим смешения   <div class="filter-value">-23</div></div>
135
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Длительность анализа   <div class="filter-value">10</div></div>
136
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Максимальное усиление   <div class="filter-value">15</div></div>
137
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Минимальное усиление   <div class="filter-value">-15</div></div>
138
-</div>
139
-<div class="filter">
140
-        <div class="filter-name"><b>Эффект: </b>Панорама</div>
141
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Левый/Правый   <div class="filter-value">0.5</div></div>
142
-</div>
143
-<div class="filter">
144
-        <div class="filter-name"><b>Эффект: </b>Панорама по ключевым кадрам</div>
145
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Левый/Правый   <div class="filter-value">0.5</div></div>
146
-</div>
147
-<div class="filter">
148
-        <div class="filter-name"><b>Эффект: </b>Поменять каналы местами (без параметров)</div>
149
-</div>
150
-<!-- Звуковые фильтры -->
151
-<h2>Звуковые фильтры</h2>
152
-<div class="filter">
153
-        <div class="filter-name"><b>Эффект: </b>Delayorama</div>
154
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Случайная зернистость   <div class="filter-value">0</div></div>
155
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Усиление на входе (дБ)   <div class="filter-value">0.0</div></div>
156
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Обратная связь (%)   <div class="filter-value">0.0</div></div>
157
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Количество отводов   <div class="filter-value">2</div></div>
158
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Первая задержка (c)   <div class="filter-value">0.0</div></div>
159
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Диапазон задержки (c)   <div class="filter-value">6.0</div></div>
160
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Изменения задержки   <div class="filter-value">1.0</div></div>
161
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Случайная задержка (%)   <div class="filter-value">0.0</div></div>
162
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Амплитудные изменения   <div class="filter-value">1.0</div></div>
163
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Случайная амплитуда (%)   <div class="filter-value">0.0</div></div>
164
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс   <div class="filter-value">1.0</div></div>
165
-</div>
166
-<div class="filter">
167
-        <div class="filter-name"><b>Эффект: </b>GSM Симулятор</div>
168
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Проход   <div class="filter-value">1</div></div>
169
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Частота ошибок   <div class="filter-value">0</div></div>
170
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс   <div class="filter-value">1.0</div></div>
171
-</div>
172
-<div class="filter">
173
-        <div class="filter-name"><b>Эффект: </b>Pitchshifter - AM</div>
174
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Транспонирование   <div class="filter-value">1.0</div></div>
175
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Размер буфера   <div class="filter-value">4</div></div>
176
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс   <div class="filter-value">1</div></div>
177
-</div>
178
-<div class="filter">
179
-        <div class="filter-name"><b>Эффект: </b>Виниловая пластинка</div>
180
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Год   <div class="filter-value">1950</div></div>
181
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Оборотов в минуту   <div class="filter-value">33</div></div>
182
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Деформация поверхности   <div class="filter-value">0</div></div>
183
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Потрескивание   <div class="filter-value">0</div></div>
184
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Изношенность  <div class="filter-value">0</div></div>
185
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс   <div class="filter-value">1.0</div></div>
186
-</div>
187
-<div class="filter">
188
-        <div class="filter-name"><b>Эффект: </b>Изменение тона (высокое качество)</div>
189
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Коэффициент тона   <div class="filter-value">1.0</div></div>
190
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс   <div class="filter-value">1.0</div></div>
191
-</div>
192
-<div class="filter">
193
-        <div class="filter-name"><b>Эффект: </b>Искажение (Barry's Satan)</div>
194
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Задержка (образец)   <div class="filter-value">30</div></div>
195
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Угол (дБ)   <div class="filter-value">-30</div></div>
196
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Баланс   <div class="filter-value">1</div></div>
197
-</div>
198
-<div class="filter">
199
-        <div class="filter-name"><b>Эффект: </b>Искажение (Диодный процессор)</div>
200
-        <div class="filter-property"><b>Параметр по умолчанию: </b>Сумма   <div class="filter-value">1.0</div></div>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/help.html Deleted
62
 
1
@@ -1,60 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Руководство пользователя по Flowblade</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-
16
-<div id="help-index">
17
-       <div class="subject-cell">
18
-           <a href="intro.html">Введение</a>
19
-       </div>
20
-       <div class="subject-cell">
21
-           <a href="basic_editing.html">Основы редактирования</a> 
22
-       </div>
23
-       <div class="subject-cell">
24
-           <a href="edit_tools.html">Инструменты редактирования и режим работы</a> 
25
-       </div> 
26
-       <div class="subject-cell">
27
-           <a href="compositor.html">Создание композитных клипов</a>
28
-       </div>
29
-       <div class="subject-cell">
30
-           <a href="filtering.html">Видео и звуковые эффекты</a> 
31
-       </div>
32
-       <div class="subject-cell">
33
-           <a href="advanced.html">Расширенные возможности редактирования</a> 
34
-       </div> 
35
-       <div class="subject-cell">
36
-           <a href="range_log.html">Журнал участков</a>
37
-       </div>
38
-       <div class="subject-cell">
39
-           <a href="proxy.html">Редактирование прокси</a>
40
-       </div>
41
-       <div class="subject-cell">
42
-           <a href="container_clips.html">Контейнерные клипы</a>
43
-       </div>
44
-       <div class="subject-cell">
45
-           <a href="tools.html">Автономные инструменты</a>
46
-       </div>
47
-       <div class="subject-cell">
48
-            <a href="rendering.html">Сборка</a>
49
-   </div>
50
-</div>
51
-
52
-<h6 class="appendix-title">Приложения:</h6>
53
-<a class="appendix-index" href="filters_list.html">Список эффектов</a>
54
-<a class="appendix-index" href="kbshortcuts.html">Комбинации клавиш</a>
55
-
56
-<div class="copyright-info">Справочное руководство по Flowblade (июнь 2020 год).</div> 
57
-
58
-</div>
59
-</body>
60
-
61
-</html> 
62
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/intro.html Deleted
31
 
1
@@ -1,29 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Введение</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-
16
-<h2>Введение</h2>
17
-
18
-<p>
19
-Видеоредактор Flowblade это <b>многодорожечный нелинейный видеоредактор</b> для Linux.
20
-<p/>
21
-<p>
22
-С его помощью вы сможете создавать фильмы из видеоклипов, звуковых и графических файлов. Разрезать клипы на нужные участки, добавлять к ним эффекты. Вы также можете создавать многослойные составные клипы используя элементы композитинга.
23
-</p>
24
-<p>
25
-Flowblade предоставляет возможность настройки <b>режима работы</b> (набор инструментов, его порядок, инструмент по умолчанию и определённое поведение монтажного стола).
26
-</p>
27
-
28
-</div>
29
-</body>
30
-
31
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/kbshortcuts.html Deleted
201
 
1
@@ -1,454 +0,0 @@
2
-<!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Комбинации клавиш</title>
7
-<style>
8
-.tablestyle {
9
-  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
10
-  border-collapse: collapse;
11
-  width: 100%;
12
-}
13
-
14
-.tablestyle  td, .tablestyle th {
15
-  border: 1px solid #ddd;
16
-  padding: 8px;
17
-}
18
-
19
-.tablestyle tr:nth-child(even){background-color: #f2f2f2;}
20
-
21
-.tablestyle  tr:hover {background-color: #ddd;}
22
-
23
-.tablestyle th {
24
-  padding-top: 12px;
25
-  padding-bottom: 12px;
26
-  text-align: left;
27
-  background-color: #1e35b5;
28
-  color: white;
29
-}
30
-
31
-h1, h2, h3, h4, h5, h6 {
32
-   padding-top: 48px;
33
-   padding-bottom: 12px;
34
-   font-family: sans-serif;
35
-   text-transform: uppercase;
36
-   margin:2px 0;
37
-   color: #000000;
38
-   font-weight:400;
39
-}
40
-#content {
41
-  width: 700px ;
42
-  margin-left: auto ;
43
-  margin-right: auto ;
44
-}
45
-
46
-
47
-</style>
48
-</head>
49
-<body>
50
-
51
-<div id="content">
52
-
53
-<h1>Комбинации клавиш в Flowblade по умолчанию</h1>
54
-<h2>Основные</h2>
55
-
56
-<table class="tablestyle">
57
-<thead>
58
-<tr>
59
-<th>Комбинация</th>
60
-<th>Действие</th>
61
-</tr>
62
-</thead>
63
-<tbody>
64
-<tr>
65
-<td>Control + N</td>
66
-<td>Создать новый проект</td>
67
-</tr>
68
-<tr>
69
-<td>Control + S</td>
70
-<td>Сохранить проект</td>
71
-</tr>
72
-<tr>
73
-<td>Delete</td>
74
-<td>Удалить</td>
75
-</tr>
76
-<tr>
77
-<td>ESCAPE</td>
78
-<td>Остановить создание звуковых уровней</td>
79
-</tr>
80
-<tr>
81
-<td>Control + Q</td>
82
-<td>Выйти</td>
83
-</tr>
84
-<tr>
85
-<td>Control + Z</td>
86
-<td>Отменить</td>
87
-</tr>
88
-<tr>
89
-<td>Control + Y</td>
90
-<td>Повторить</td>
91
-</tr>
92
-<tr>
93
-<td>Control + O</td>
94
-<td>Открыть проект</td>
95
-</tr>
96
-<tr>
97
-<td>Tab</td>
98
-<td>Переключить источник предпросмотра</td>
99
-</tr>
100
-<tr>
101
-<td>Alt + N</td>
102
-<td>Открыть следующий клип в мониторе</td>
103
-</tr>
104
-<tr>
105
-<td>Control + L</td>
106
-<td>Добавить отмеченный участок в журнал</td>
107
-</tr>
108
-<tr>
109
-<td>-</td>
110
-<td>Уменьшить</td>
111
-</tr>
112
-<tr>
113
-<td>+</td>
114
-<td>Увеличить</td>
115
-</tr>
116
-</tbody>
117
-</table>
118
-
119
-
120
-<h2>Монтажный стол</h2>
121
-
122
-<table class="tablestyle">
123
-<thead>
124
-<tr>
125
-<th>Комбинация</th>
126
-<th>Действие</th>
127
-</tr>
128
-</thead>
129
-<tbody>
130
-<tr>
131
-<td>I</td>
132
-<td>Выбрать начало участка</td>
133
-</tr>
134
-<tr>
135
-<td>O</td>
136
-<td>Выбрать конец участка</td>
137
-</tr>
138
-<tr>
139
-<td>Alt + I</td>
140
-<td>Перейти к началу участка</td>
141
-</tr>
142
-<tr>
143
-<td>Alt + O</td>
144
-<td>Перейти в конец участка</td>
145
-</tr>
146
-<tr>
147
-<td>Alt + K</td>
148
-<td>Удалить участок</td>
149
-</tr>
150
-<tr>
151
-<td>X</td>
152
-<td>Разрезать на активных дорожках</td>
153
-</tr>
154
-<tr>
155
-<td>Shift + X</td>
156
-<td>Разрезать на всех дорожках</td>
157
-</tr>
158
-<tr>
159
-<td>DELETE</td>
160
-<td>Удалить со вставкой</td>
161
-</tr>
162
-<tr>
163
-<td>Control + DELETE</td>
164
-<td>Удалить без вставки</td>
165
-</tr>
166
-<tr>
167
-<td>Alt + C</td>
168
-<td>Удалить эффекты</td>
169
-</tr>
170
-<tr>
171
-<td>Alt + S</td>
172
-<td>Синхронизировать композитор</td>
173
-</tr>
174
-<tr>
175
-<td>Alt + R</td>
176
-<td>Ресинхронизировать</td>
177
-</tr>
178
-<tr>
179
-<td>Y</td>
180
-<td>Вставка</td>
181
-</tr>
182
-<tr>
183
-<td>U</td>
184
-<td>Склейка</td>
185
-</tr>
186
-<tr>
187
-<td>T</td>
188
-<td>Перезапись по трём точкам</td>
189
-</tr>
190
-<tr>
191
-<td>R</td>
192
-<td>Перезаписать участок</td>
193
-</tr>
194
-<tr>
195
-<td>A</td>
196
-<td>Добавить выбранные из корзины клипы</td>
197
-</tr>
198
-<tr>
199
-<td>M</td>
200
-<td>Добавить маркер</td>
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/proxy.html Deleted
99
 
1
@@ -1,97 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Редактирование прокси</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-
16
-<script src="tocgen.js"></script>
17
-
18
-<div id="toccontent">
19
-
20
-<div class="subject-header">Редактирование прокси</div>
21
-
22
-<p>
23
-Редактирование прокси — это метод редактирования, в котором оригинальные медиаклипы представлены на монтажном столе прокси-клипами.
24
-
25
-</p> 
26
-<div id="toc"></div>
27
-
28
-<h3>Обоснование</h3>
29
-<p>
30
-Прокси-клипы, используемые при редактировании прокси, обычно имеют меньшую скорость передачи данных и потребляют меньше ресурсов процессора для декодирования. Для редактирования с использованием прокси есть две основные причины:
31
-</p>
32
-<ul>
33
-<li> Исходный носитель, с которого выполняется редактирование, предъявляет слишком высокие требования к пропускной способности диска или к мощности процессора для декодирования, что не позволяет обеспечить комфортное редактирование в целом. </li>
34
-<li> Оригинал хранится на сетевом сервере, медленном внешнем диске или другом носителе с ограниченным доступом и не позволяет обеспечить комфортное редактирование при прямом доступе.</li>
35
-</ul>
36
-
37
-
38
-
39
-<h3>Общий процесс редактирования с использованием прокси</h3>
40
-
41
-<p>
42
-Все рабочие процессы редактирования с использованием прокси имеют одни и те же этапы:
43
-</p>
44
-<ol>
45
-<li> Сборка прокси из оригинальных клипов </li>
46
-<li> Замена оригинального клипа на прокси </li>
47
-<li> Редактирование с использованием прокси </li>
48
-<li> Замена прокси на оригинальные клипы </li>
49
-<li> Финальная сборка с использованием оригинальных клипов </li>
50
-</ol>
51
-
52
-<h3>Редактирование прокси во Flowblade</h3>
53
-<ol>
54
-<li> Создание прокси-клипа</li>
55
-<ol>
56
-<li> В главном меню выберите <b>Проект→Менеджер прокси</b> и задайте параметры для прокси в области <b>Кодирование прокси</b>.</li>
57
-<li> Выберите элемент медиа во вкладке <b>«Медиа»</b>.</li>
58
-<li> Нажмите кнопку со значком прокси рядом кнопкой Удалить во вкладке «Медиа».</li>
59
-<li> Если проект уже находится в режиме прокси <b>«Использование прокси-клипов»</b> оригинальные клипы на монтажном столе, на которых были собраны прокси, будут немедленно заменены прокси-клипами.</li>
60
-</ol>
61
-<li>Включение режима «Использование прокси-клипов»</li>
62
-<ol>
63
-<li> В главном меню выберите <b>Проект→Менеджер прокси</b>.</li>
64
-<li> В открывшемся окне нажмите кнопку <b>Использование прокси-клипов</b>.</li>
65
-</ol>
66
-<li>Редактирование с использованием прокси-клипов</li>
67
-<ol>
68
-<li> Клипы, использующие прокси, имеют голубую полосу, указывающую на статус прокси.</li>
69
-<li> Значок индикатора редактирования прокси отображается в левом нижнем углу.</li>
70
-<li> Если на монтажном столе создаётся новый клип использующий оригинальный медиафайл, то он немедленно будет заменён на прокси-клип.</li>
71
-<li> Проект может быть нормально сохранён и преобразован после загрузки, для использования оригинальных клипов.</li>
72
-</ol>
73
-<li>Включение режима «Использование оригинальных клипов»</li>
74
-<ol>
75
-<li> В главном меню выберите <b>Проект→Менеджер прокси</b>.</li>
76
-<li> В открывшемся окне нажмите кнопку <b>Использование оригинальных клипов</b>.</li>
77
-</ol>
78
-</ol>
79
-<h3>Важные замечания о редактировании прокси во Flowblade</h3>
80
-<div class="important">
81
-<li> <b>УНИЧТОЖЕНИЕ ЛЮБОГО МЕДИА во время редактирования прокси СДЕЛАЕТ НЕВОЗМОЖНЫМ ПРЕОБРАЗОВАНИЕ И ВОЗВРАЩЕНИЕ К ИСПОЛЬЗОВАНИЮ ОРИГИНАЛЬНЫХ КЛИПОВ</b> </li>
82
-<li> <b>Можно использовать, либо все <i>существующие</i> прокси-клипы, либо все оригинальные клипы</b>. Нельзя выборочно использовать только некоторые из созданных прокси-клипов.</li>
83
-
84
-</div>
85
-<div class="note">
86
-<p>
87
-Flowblade использует технику программирования, которая изменяет пути, используемые элементами мультимедиа, чтобы указывать, либо на скрытые прокси-клипы, либо на оригинальные.
88
-</p>
89
-<p>
90
-Переход от одного к другому осуществляется путём записи скрытого временного файла проекта на диск и замены путей при чтении проекта. Из-за этого любые отсутствующие оригинальные клипы снова преобразуются в оригинальный медиафайл.
91
-</p>
92
-</div>
93
-
94
-</div>
95
-</div>
96
-</body>
97
-
98
-</html> > 
99
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/range_log.html Deleted
73
 
1
@@ -1,71 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Журнал участков</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-
16
-<script src="tocgen.js"></script>
17
-
18
-<div id="toccontent">
19
-
20
-<div class="subject-header">Журнал участков</div>
21
-
22
-<p>
23
-Flowblade предоставляет функцию сохранения, изменения, переименования и управления <b>участками</b> элементов мультимедиа.
24
-
25
-<div id="toc"></div>
26
-
27
-<h3>Обоснование</h3>
28
-Эта функция в основном полезна, когда есть <b>элементы мультимедиа, которые содержат несколько интересных участков</b>, или если пользователь хочет сохранить и изменить участок для последующего редактирования.
29
-</p>
30
-<p>
31
-Типичным примером использования этой функции будет:
32
-</p>
33
-<ol>
34
-<li> Пользователь редактирует длинный клип с речью, произносимой в каком либо социальном институте — На собрании в производстве, поздравлении, подготовке презинтации и т.д. </li>
35
-<li> Пользователь хочет отметить и присвоить имя интересным участкам клипа.</li>
36
-</ol>
37
-
38
-<h3>Создание элементов журнала участков</h3>
39
-<h4> С помощью монитора:</h4>
40
-<ol>
41
-<li>Открыть элемент мультимедиа в мониторе,</li>
42
-<li>Выбрать начало и конец участка,</li>
43
-<li>Нажать кнопку «Добавить отмеченный участок» в левом нижнем углу вкладки «Журнал участков».</li>
44
-</ol>
45
-<h4>С помощью монтажного стола:</h4>
46
-<ol>
47
-<li>Переместите клип из монтажного в список элементов во вкладке «Журнал участков».</li>
48
-</ol>
49
-
50
-
51
-<h3> Добавление элементов журнала участков на монтажный стол</h3>
52
-<h4>С помощью кнопок:</h4>
53
-<ul>
54
-<li> Нажмите на кнопку «Вставить отображаемые участки на монтажный стол...», в правом нижнем углу, для добавления всех элементов в качестве клипов на активную дорожку.</li>
55
-<li>Нажмите на кнопку «Вставить выбранные участки на монтажный стол...», рядом с кнопкой вставки отображаемых участков, чтобы вставить все выбранные элементы на активной дорожке в ближайшем разрезе из текущего отображаемого положения монтажного стола.</li>
56
-</ul>
57
-<h4>С помощью мыши:</h4>
58
-<ul>
59
-<li> Выберите элемент журнала участков и переместите его в нужную позицию на монтажном столе.</li>
60
-</ul>
61
-
62
-<h3>Управление элементами журнала участков</h3>
63
-<ul>
64
-<li> В выпадающем меню верхней строки выберите отображаемую группу элементов.</li>
65
-<li> Используйте кнопку выпадающего меню, в верхнем левом углу, для создания, переименования и удаления групп элементов.</li>
66
-</ul>
67
-
68
-</div>
69
-</div>
70
-</body>
71
-
72
-</html> 
73
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/rendering.html Deleted
117
 
1
@@ -1,115 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Сборка</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-<script src="tocgen.js"></script>
16
-
17
-<div id="toccontent">
18
-
19
-<div class="subject-header">Сборка</div>
20
-<p>
21
-В Flowblade есть два способа сборки вашего фильма в файл: 
22
-</p>
23
-<ul>
24
-<li> Вкладка <b>«Сборка»</b> расположена слева от Монитора.</li>
25
-<li> Инструмент <b>«Очередь пакетной сборки»</b>, который расположен в главном меню «Сборка».</li>
26
-</ul>
27
-
28
-<p>
29
-Почти все кодировки, доступные для приложений FLOSS, могут использоваться в Flowblade. 
30
-</p>
31
-
32
-<div id="toc"></div>
33
-
34
-<h3>Вкладка «Сборка»</h3>
35
-
36
-<h4>Виджеты</h4>
37
-<h5>Выпадающее меню <b>«Папка»</b> </h5> <div class="r-widget">Выберите папку для размещения выходного файла.</div>
38
-<h5>Поле ввода <b>«Имя»</b></h5> <div class="r-widget"> Присвойте имя выходному файлу.</div>
39
-<h5>Выпадающее меню <b>«Тип»</b> сборки</h5> <div class="r-widget">Выберите между сборкой с параметрами заданными пользователем или используйте предустановленные параметры сборки и типа файла.</div>
40
-<h5>Выпадающее меню <b>«Предустановки»</b></h5> <div class="r-widget">Выберите предустановленные параметры сборки и тип файла.</div>
41
-<h5>Флажок <b>«С профилем проекта»</b></h5> <div class="r-widget">Снимите флажок с «С профилем проекта», если нужно выбрать профиль для сборки фильма, отличный от профиля вашего проекта.</div>
42
-<h5>Выпадающее меню <b>«Профиль»</b> сборки</h5> <div class="r-widget">Выберите профиль сборки.</div>
43
-<h5>Выпадающее меню <b>«Формат кодирования»</b></h5> <div class="r-widget">Выберите формат кодирования и расширение файла для сборки.</div>
44
-<h5>Выпадающее меню <b>«Качества сборки»</b></h5> <div class="r-widget">Выберите скорость потока для сборки.</div>
45
-<h5>Использование <b>«Аргументов сборки»</b></h5> <div class="r-widget">Сборка с использованием аргументов, заданных в области редактирования текста.</div>
46
-<h5>Кнопка <b>загрузки аргументов</b></h5></h5> <div class="r-widget">Загрузите аргументы сборки, взятые из текстового файла.</div>
47
-<h5>Кнопка <b>сохранения аргументов</b></h5> <div class="r-widget">Сохраните аргументы сборки в текстовом файле.</div>
48
-<h5>Кнопка <b>«Изменение аргументов»</b></h5> <div class="r-widget">Установите аргументы сборки в области текста.</div>
49
-<h5>Выбор <b>расширения</b> файла</b></h5> <div class="r-widget">Введите расширение для собираемого файла.</div>
50
-<h5>Выпадающее меню <b>«Участка сборки»</b></h5> <div class="r-widget">Выберите между всей последовательностью и определённым участком.</div>
51
-<h5>Кнопка <b>«Сборка»</b></h5> <div class="r-widget">После нажатия, содержимое монтажного стола собирётся в файл. </div>
52
-</ul>
53
-
54
-<h4>Отображение результатов</h4>
55
-<ol>
56
-<li> Нажмите кнопку <b>«Сборка»</b> для запуска процесса сборки.</li>
57
-<li> Откроется окно процесса сборки, которое отображает информацию о пути собираемого файла, предполагаемом времени, времени сборки.</li>
58
-<li> После завершения сборки окно процесса сборки закроется автоматически.</li>
59
-</ol>
60
-
61
-<h3> Очередь пакетной сборки </h3>
62
-
63
-<p>
64
-Flowblade предлагает специализированное приложение очереди пакетной обработки. «Очередь пакетной сборки»- это автономное приложение, работающее в собственном процессе и не влияющее на проект, поэтому закрытие Flowblade, не затронет текущую пакетную сборку.
65
-</p>
66
-<p>
67
-Пакетная сборка - это постоянная структура данных элементов сборки на диске. Каждый элемент состоит из файла проекта и сохранённых параметров сборки. Пользователи могут добавлять объекты сборки в очередь пакетной сборки, а затем собрать всю очередь без дальнейших действий пользователя.
68
-</p>
69
-
70
-<h4>Добавление элементов в очередь пакетной сборки</h4>
71
-<ul>
72
-<li> В главном меню выберете пункт <b>Сборка→ Добавить в очередь пакетной сборки...</b></li>
73
-</ul>
74
-
75
-<h4>Использование приложения очереди пакетной сборки</h4>
76
-<ol>
77
-<li> Откройте приложение в главном меню <b>Сборка→ Очередь пакетной сборки</b>.</li>
78
-<li> Используйте кнопки <b>«Удалить выбранные»</b> и <b>« Удалить завершённые»</b>, чтобы удалить элементы из очереди.</li>
79
-<li> Используйте флажок в столбце <b>«Сборка»</b>, чтобы выбрать, какие элементы будут собираться. </li>
80
-<li> Нажмите кнопку <b>«Сборка»</b>, для запуска процесса сборки.</li>
81
-</ol>
82
-<p>
83
-Дополнительные действия:
84
-</p>
85
-<ul>
86
-<li> <b>Щёлкните правой кнопкой мыши</b> по элементу проекта, для отображения его всплывающего меню.</li>
87
-<li> <b>Сохранить элемент проекта как...</b> позволяет пользователю сохранять в файл проекта, выбранный элемент в другом месте.</li>
88
-<li> <b>Свойства сборки</b> отображает информацию о параметрах, которые были установлены, во время добавления элемента в очередь сборки.</li>
89
-<li> <b>Удалить</b> удаляет элемент из очереди.</li>
90
-</ul>
91
-<h3>Сборка за кулисами: MLT и libavformat (FFMpeg)</h3>
92
-<p>
93
-Видеоредактор Flowblade - это приложение написанное на Python, взаимодействующее с мультимедийной средой MLT. Другими приложениями для редактирования видео, использующими MLT в качестве платформы, являются OpenShot и Kdenlive.
94
-</p>
95
-<p>
96
-MLT использует C-library libavformat (FFMpeg) для сборки выходных файлов, а сборка определяется настройкой параметров кодирования FFMpeg. Эти параметры доставляются из видеоредактора Flowblade в MLT, с помощью потребителя «avformat» для данного профиля Сборки, а затем задаются аргументы сборки.
97
-Аргументы задаются точно такие же, которые используются в FFmpeg для кодирования видеофайлов.
98
-</p>
99
-<p>
100
-Аргументы сборки для кодирования различных типов видеофайлов предварительно упаковывается и могут быть определены с помощью меню «Формат кодирования». Аргументы можно уточнить, проверив Сборку с помощью флажка «Использование аргументов сборки» и изменив и/или добавив/удалив значения аргументов.
101
-</p>
102
-<p>
103
-Любые видеоролики, поддерживаемые установленной версией MLT, могут быть перекодированы путём создания пользовательского профиля Сборки и установки аргументов сборки. В поисковых системах, например в Google, можно найти различные комбинации использования аргументов для кодирования видеофайлов в FFMpeg.
104
-</p>
105
-<p>
106
-Посмотрите в интернете информацию о кодировании файлов с помощью FFMpeg, для ознакомления с примерами использования аргументов сборки.
107
-</p>
108
-<h3>Модель сборки в Flowblade</h3>
109
-
110
-<img src="encoding.png">
111
-
112
-</div>
113
-</div>
114
-</body>
115
-
116
-</html> 
117
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/style.css Deleted
201
 
1
@@ -1,279 +0,0 @@
2
-html {
3
-   font-size: 100%;
4
-   -webkit-text-size-adjust: 100%;
5
-   -ms-text-size-adjust: 100%;
6
-}
7
-
8
-body {
9
-   font-family: Georgia, "Times New Roman", Times, serif;
10
-   color:#222222;
11
-   background-color: #ffffff; 
12
-   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
13
-   font-family: sans-serif;
14
-   word-wrap: break-word;
15
-   line-height: 1.4;
16
-   vertical-align: baseline;
17
-}
18
-
19
-#content {
20
-  width: 700px ;
21
-  margin-left: auto ;
22
-  margin-right: auto ;
23
-}
24
-
25
-#help-index{
26
-   margin-top: 80px;
27
-   width: 900px;
28
-   margin-bottom: 80px;
29
-   display: flex;
30
-   justify-content: center;
31
-   flex-direction: column;
32
-   text-align: center;
33
-}
34
-
35
-.appendix-index{
36
-   margin-top: 10px;
37
-   width: 900px;
38
-   margin-bottom: 10px;
39
-   display: flex;
40
-   justify-content: center;
41
-   flex-direction: column;
42
-   text-align: left;
43
-   color: #666666;
44
-   font-size:18px;
45
-}
46
-
47
-.subject-cell {
48
-   padding-right: 20px;
49
-   color:#222222;
50
-   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
51
-   font-family: sans-serif;
52
-   word-wrap: break-word;
53
-   line-height: 1.4;
54
-   vertical-align: baseline;
55
-   font-weight:400;
56
-   font-size:30px;
57
-   margin-bottom: 35px;
58
-}
59
-
60
-.grid-container {
61
-   margin-top: 80px;
62
-        width: 700px;
63
-   margin-bottom: 80px;
64
-}
65
-
66
-.row:before, 
67
-.row:after {
68
-   content:"";
69
-   display: table ;
70
-   clear:both;
71
-}
72
-
73
-.column4 {
74
-   float: left; 
75
-   width: 33.3%;
76
-   margin-bottom: 50px;
77
-}
78
-
79
-.subject-cell {
80
-   padding-right: 20px;
81
-   color:#222222;
82
-   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
83
-   font-family: sans-serif;
84
-   word-wrap: break-word;
85
-   line-height: 1.4;
86
-   vertical-align: baseline;
87
-   font-weight:400;
88
-   font-size:22px;
89
-   text-transform: uppercase;
90
-}
91
-
92
-.appendix-pad {
93
-   color: #666666;
94
-   font-size:14px;
95
-}
96
-.appendix-title {
97
-   color: #666666;
98
-   font-size:20px;
99
-}
100
-
101
-.note {
102
-   background-color: #f3f3f0;
103
-   padding: 25px;
104
-   margin-bottom: 10px ;
105
-}
106
-
107
-.important {
108
-   background-color: #f5d77d;
109
-   padding: 25px;
110
-   margin-bottom: 10px ;
111
-}
112
-
113
-.tabbed {
114
-   padding-left: 25px;
115
-   margin-bottom: 10px ;
116
-}
117
-
118
-.tabbed_line {
119
-   padding-left: 25px;
120
-}
121
-
122
-.tocitem {
123
-   font-size:12px;
124
-   line-height: 1.0;
125
-
126
-}
127
-
128
-.tocli {
129
-   list-style-type: none;
130
-}
131
-
132
-.copyright-info {
133
-   font-family: Georgia, "Times New Roman", Times, serif;
134
-   margin-top:80px;
135
-   color: #444444;
136
-   font-weight:400;
137
-   font-size:12px;
138
-}
139
-
140
-.subject-header {
141
-   text-transform: uppercase;
142
-   margin-top:10px;
143
-   color: #000000;
144
-   font-weight:400;
145
-   font-size:26px;
146
-}
147
-
148
-.filter {
149
-   margin-bottom: 25px;
150
-   color: #000000;
151
-   font-weight:400;
152
-   font-family: sans-serif;
153
-   word-wrap: break-word;
154
-   line-height: 1.4;
155
-   vertical-align: baseline;
156
-}
157
-
158
-.filter-name {
159
-   padding-left: 20px;
160
-}
161
-
162
-.filter-property {
163
-   padding-left: 50px;
164
-   font-size:12px;
165
-}
166
-.filter-value {
167
-   display:inline-block;
168
-   color: #0000bb;
169
-   font-size: 8;
170
-}
171
-
172
-.filter-group {
173
-   color: #000000;
174
-   font-size: 26;
175
-   text-transform: uppercase;
176
-   margin-top: 50px;
177
-   margin-bottom: 10px;
178
-}
179
-
180
-.r-widget {
181
-   display: inline-block;
182
-   margin-top:0px;
183
-   margin-left:15px;
184
-   margin-bottom:10px;
185
-}
186
-
187
-#advtoc {
188
-   margin-top:50px;
189
-   margin-bottom:30px;
190
-}
191
-
192
-
193
-/* Otsikot 1 */
194
-h1, h2, h3, h4, h5, h6{
195
-   text-transform: uppercase;
196
-   margin:2px 0;
197
-   color: #000000;
198
-   font-weight:400;
199
-}
200
-
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/tools.html Deleted
95
 
1
@@ -1,93 +0,0 @@
2
- <!DOCTYPE html>
3
-<html class="client-nojs" lang="ru" dir="ltr">
4
-<head>
5
-<meta charset="UTF-8"/>
6
-   <title>Автономные инструменты</title>
7
-  <link rel="stylesheet" href="style.css">
8
-<script src="toc.js" type="text/javascript"></script>
9
-</head>
10
-
11
-<body>
12
-
13
-<div id="content">
14
-<img src="header_text_5.png" >
15
-
16
-<script src="tocgen.js"></script>
17
-
18
-<div id="toccontent">
19
-
20
-<div class="subject-header">Автономные инструменты</div>
21
-
22
-<p>
23
-Flowblade предоставляет автономные инструменты для важных функций, которые не могут быть логически или удобно представлены с помощью вкладок или на монтажном столе.
24
-</p>
25
-
26
-
27
-<div id="toc"></div>
28
-
29
-<h3> Редактор титров </h3>
30
-<p>Особенности:</p>
31
-<ul>
32
-<li> Добавление и удаление слоёв в области слоёв</li>
33
-<li> Изменение свойств слоя и текста в области активного слоя</li>
34
-<li> Установка текстового положения, перетаскиванием активного слоя в окне просмотра</li>
35
-<li> Установка фонового изображения из монтажного стола, для правильного позиционирования текста, перетаскиванием курсора по линейке времени</li>
36
-<li> Загрузка и сохранение данных слоёв в области слоёв</li>
37
-</ul>
38
-<h3> Звуковой микшер </h3>
39
-<p>Особенности:</p>
40
-<ul>
41
-<li> Контроль уровней звука в VU-метрах во время воспроизведения</li>
42
-<li> Использование ползунков для установки громкости на дорожках или на выходе</li>
43
-<li> Использование кнопки <b>Панорама</b>, для активации ползунка панорамы и панорамирования звука  </li>
44
-</ul>
45
-<h3> Перелинковщик медиа </h3>
46
-<p>
47
-<b>Перелинковщик медиа</b> — это автономное приложение, работающее в собственном процессе и не влияющее на проект, открытый в Flowblade. 
48
-</p>
49
-<ol>
50
-<li> Начните с нажатия кнопки <b>Загрузить проект для перелинковки</b> и выберите проект, который хотите восстановить.</li>
51
-<li> Выберите медиафайл, который вы хотите заменить каким-либо другим медиафайлом. Нажмите кнопку <b>Указать путь к файлу</b> или щёлкните <b>Правой кнопкой мыши</b> по элементу, для выбора нового файла. Клипы и типы вытеснения в проекте будут связаны новым медиафайлом. </li>
52
-<li> Используйте выпадающее меню внизу слева, чтобы отобразить отсутствующие или найденные мультимедийные файлы.</li>
53
-<li> Нажмите <b>Сохранить проект как...</b> для повторного сохранения подключенной версии проекта.</li>
54
-<li> Откройте перелинкованный проект в Flowblade и продолжайте работать с ним.</li>
55
-<li> Перелинковщик медиа запускается в собственном процессе и не влияет на общее состояние и данные запущенного приложения.</li>
56
-<li> При повторном открытии проекта в Flowblade, убедитесь, что при сохранении не перезапишите подключенную версию открытого в Flowblade проекта </li>
57
-</ol>
58
-
59
-<h3> Эффекты G'Mic</h3>
60
-<p>
61
-G'Mic — полнофункциональная среда с открытым исходным кодом для обработки изображений.
62
-</p>
63
-<p>
64
-Инструмент Flowblade G'Mic представляет пользователю набор кодов, которые могут использоваться для достижения сложной фильтрации видеороликов.</p>
65
-<p>
66
-<b>ПРИМЕЧАНИЕ. Если в системе нет предустановленных команд, соответствующий выбор эффектов работать не будет.</b>
67
-</p>
68
-<p>
69
-Команды в основном встроены в двоичный файл <b>/usr/bin/gmic</b> поэтому для получения доступа к большему количеству команд, вам скорее всего потребуется обновить двоичный файл в вашей системе.
70
-</p>
71
-<p>
72
-Тем не менее, можно добавлять пользовательские команды и использовать их в качестве эффектов для видео, более подробно можно ознакомится <a href="  http://gmic.eu/reference.shtml#section11">здесь</a> (eng). 
73
-</p>
74
-
75
-<h4>Загрузка клипов и предпросмотр сборки</h4>
76
-<ul>
77
-<li> Начните с нажатия кнопки <b>Загрузить клип</b> и выберите видеоклип, к которому хотите применить эффект.</li>
78
-<li> Нажмите на треугольник внизу над <b>областью редактирования скриптов</b> в левой части окна, для выбора команды G'Mic.</li>
79
-<li> В <b>области редактирования скриптов</b> можно менять значения команд.</li>
80
-<li> Чтобы просмотреть изображение с применённым эффектом, нажмите кнопку <b>Предпросмотр</b> в правой части экрана.</li>
81
-<li> После того, как вы, просмотрели изображение, под <b>областью редактирования скриптов</b> может последовать текстовый вывод из G'Mic с возможными сообщениями об ошибках.</li>
82
-<li> Вы можете применить несколько команд, установив флажок <b>Добавить в скрипт</b>.</li>
83
-</ul>
84
-<h4>Сборка</h4>
85
-<ul>
86
-<li> Для сборки последовательности кадров, необходимо выбрать <b>Начало и конец участка</b> и  <b>выбрать папку</b> для хранения отображаемой последовательности кадров. </li>
87
-<li> Для сборки видеофайла из отфильтрованной последовательности кадров, установите флажок <b>Кодировать видео</b> и нажмите кнопку <b>Параметры кодирования</b>, для определения свойств собираемого видеофайла.</li>
88
-</ul>
89
-
90
-</div>
91
-</div>
92
-</body>
93
-
94
-</html> 
95
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/wrong_comp.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/ru/wrong_timeline.png Deleted
_service:obs_scm:flowblade-2.18.1.obscpio/README.md -> _service:obs_scm:flowblade-2.20.obscpio/README.md Changed
45
 
1
@@ -2,6 +2,8 @@
2
 
3
 !Flowblade(flowblade-trunk/Flowblade/res/darktheme/header_text.png "Flowblade")
4
 
5
+**New release 2.20 available. See release notes here,(./flowblade-trunk/docs/RELEASE_NOTES.md)**
6
+
7
 1. Introduction(https://github.com/jliljebl/flowblade#introduction)
8
 2. Features(https://github.com/jliljebl/flowblade#features)
9
 3. Releases(https://github.com/jliljebl/flowblade#releases)
10
@@ -16,13 +18,13 @@
11
 
12
 **--- FIX FOR NON_WORKING VIDEO PREVIEW ISSUE ---**
13
 
14
-**Start application from terminal with command:**
15
+**Fix is to update to the latest version 2.20.**
16
+
17
+**If not possible, start application from terminal with command:**
18
 
19
 ```
20
 SDL12COMPAT_NO_QUIT_VIDEO=1 GDK_BACKEND=x11 SDL_VIDEODRIVER=x11  /usr/bin/flowblade 
21
 ```
22
-**More info on Issue here: Issue #1134(https://github.com/jliljebl/flowblade/issues/1134)**
23
-
24
 **--- FIX FOR NON_WORKING VIDEO PREVIEW ISSUE ---**
25
 
26
 # Introduction
27
@@ -56,7 +58,7 @@
28
 **Advanced features:**
29
 * **Generators:** Powerful media generator plugin framework available to create e.g. animated texts and backgrounds.
30
 * **Range Log:** Save and edit clip in/out ranges to easily utilize best parts of your material
31
-* **G'Mic Tool:** Create media with beatiful, complex effects not available in any other editor
32
+* **G'Mic Tool:** Create media with beautiful, complex effects not available in any other editor
33
 * **Text Tool:** Create text plates with a handy purpose build tool with large set of features like text shadow, outline etc.
34
 * **Batch Encoding:** Render multiple output clips automatically 
35
 * **Media re-linking:** Fix projects with missing media to be editable again.
36
@@ -75,7 +77,7 @@
37
 
38
 # Releases
39
 
40
-**Latest release:** Flowblade Movie Editor 2.16 was released in May 2024.
41
+**Latest release:** Flowblade Movie Editor 2.20 was released in March 2025.
42
 
43
 # Installing Flowblade
44
 
45
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/app.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/app.py Changed
49
 
1
@@ -449,6 +449,8 @@
2
             GLib.idle_add(_create_sdl_2_consumer)
3
 
4
         self.add_window(_window)
5
+        if editorpersistance.prefs.global_layout != appconsts.SINGLE_WINDOW:
6
+            self.add_window(gui.editor_window.window2)
7
 
8
 # --------------------------------------- display
9
 def _create_sdl_2_consumer():
10
@@ -478,11 +480,13 @@
11
     callbackbridge.compositeeditor_get_compositor = compositeeditor.get_compositor
12
     callbackbridge.compositormodes_get_snapped_x = compositormodes.get_snapped_x
13
     callbackbridge.compositormodes_get_pointer_context = compositormodes.get_pointer_context
14
+    callbackbridge.dialogs_show_cyclic_error = dialogs.show_cyclic_error 
15
     callbackbridge.editevent_do_multiple_clip_insert = editevent.do_multiple_clip_insert
16
     callbackbridge.medialog_clips_drop = medialog.clips_drop
17
     callbackbridge.mediaplugin_get_clip = mediaplugin.get_clip
18
     callbackbridge.mediaplugin_set_plugin_to_be_edited = mediaplugin.set_plugin_to_be_edited
19
     callbackbridge.modesetting_set_default_edit_mode = modesetting.set_default_edit_mode
20
+    callbackbridge.modesetting_kftool_mode_from_kf_editor = modesetting.kftool_mode_from_kf_editor
21
     callbackbridge.movemodes_select_clip = movemodes.select_clip
22
     callbackbridge.movemodes_select_from_box_selection = movemodes.select_from_box_selection
23
     callbackbridge.projectaction_open_rendered_file = projectaction.open_rendered_file
24
@@ -561,6 +565,8 @@
25
     editorlayout.set_positions_frames_visibility()
26
         
27
     # All widgets are now realized and references captured so can find out theme colors.
28
+    # TODO: Delete this code, we are not detecting anything anymore and theme colors not
29
+    # variable anymore.
30
     gui.set_theme_colors()
31
     tlinewidgets.set_dark_bg_color()
32
     gui.pos_bar.set_dark_bg_color()
33
@@ -1190,13 +1196,13 @@
34
     stop_usb_hid_input()
35
 
36
     # Now that autosave file is deleted, the data folder contents for unsaved
37
-    # projects are unreachable and can be destoyed.
38
+    # projects are unreachable and can be destroyed.
39
     projectdatavault.delete_unsaved_data_folders()
40
 
41
     # Calling _app.quit() will block if Gio.Application.hold() has been called,
42
     # and the documentation helpfully says "(Note that you may have called 
43
     # Gio.Application.hold() indirectly, for example through gtk_application_add_window().)"
44
-    # I'm not calling add_window() on render processess but somehow those call Gio.Application.hold()
45
+    # I'm not calling add_window() on render processes but somehow those call Gio.Application.hold()
46
     # but I don't know where. 
47
     #
48
     # However, those processes complete and exit cleanly and the only problem 
49
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/appconsts.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/appconsts.py Changed
36
 
1
@@ -41,7 +41,7 @@
2
 SHOW_AUDIO_FILES = 2
3
 SHOW_GRAPHICS_FILES = 3
4
 SHOW_IMAGE_SEQUENCES = 4
5
-SHOW_PATTERN_PRODUCERS = 5
6
+SHOW_CONTAINERS = 5
7
 SHOW_UNUSED_FILES = 6
8
 
9
 # These are used to draw indicators that tell if more frames are available while trimming.
10
@@ -309,6 +309,7 @@
11
 CONTAINER_CLIP_CAIRO_SCRIPT = 2
12
 CONTAINER_CLIP_BLENDER = 3 # DEPRECATED
13
 CONTAINER_CLIP_FLUXITY = 4
14
+CONTAINER_CLIP_SEQUENCE_LINK = 5
15
 
16
 CONTAINER_CLIP_VIDEO_CLIP_NAME = "container_clip"
17
 
18
@@ -386,7 +387,7 @@
19
 STABILIZE_DATA_EXTENSION = ".stabdata"
20
 MOTION_TRACKING_DATA_EXTENSION = ".trackdata"
21
 
22
-# magic values string propertie that have not been set yet.
23
+# magic values string properties that have not been set yet.
24
 FILE_PATH_NOT_SET = "!!##PATHNOTSET##!!"
25
 TRACKING_DATA_NOT_SET = "!!##TRACKINGDATANOTSET##!!"
26
 
27
@@ -418,3 +419,8 @@
28
 DEFAULT_RENDER_CLIP = "clip"
29
 DEFAULT_RENDER_ALPHA_CLIP = "alphaclip"
30
 DEFAULT_RENDER_FRAME_SEQUENCE = "framesequecne"
31
+
32
+AUDIO_AUTO_SPLIT_OFF = 0
33
+AUDIO_AUTO_SPLIT_ALL_TACKS = 1
34
+AUDIO_AUTO_SPLIT_V1_V2 = 2
35
+AUDIO_AUTO_SPLIT_V1 = 3
36
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/boxmove.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/boxmove.py Changed
65
 
1
@@ -19,7 +19,7 @@
2
 """
3
 
4
 """
5
-Handles Box tool functionality.
6
+Handles box selection functionality, moves and deletes.
7
 """
8
 
9
 import appconsts
10
@@ -97,7 +97,7 @@
11
         
12
     if box_selection_data == None: # mouse action is to select
13
         box_selection_data = BoxMoveData(edit_data"press_point", (x, y))
14
-        
15
+
16
         locked_track = box_selection_data.get_possible_locked_track()
17
         if locked_track != None:
18
             dialogutils.track_lock_check_and_user_info(locked_track)
19
@@ -298,7 +298,7 @@
20
     def __init__(self, i, start_frame, end_frame):
21
         self.track_id = i
22
         self.selected_range_in  = -1
23
-        self.selected_range_out = -1
24
+        self.selected_range_out = -1 # inclusive
25
         self.range_frame_in  = -1
26
         self.range_frame_out = -1
27
         self.clip_lengths = 
28
@@ -372,4 +372,36 @@
29
 
30
         return False
31
 
32
+def box_selection_splice_out():
33
+    global box_selection_data, edit_data
34
+    
35
+    # Do edit
36
+    data = {"box_selection_data":box_selection_data}
37
+    action = edit.box_splice_out_action(data)
38
+    action.do_edit()
39
+
40
+    # Back to start state
41
+    edit_data = None
42
+    box_selection_data = None
43
+    
44
+    # Exit box mode if entered from overwrite with empty selection
45
+    if entered_from_overwrite == True:
46
+        _exit_to_overwrite()
47
+        return
48
+
49
+def box_selection_lift():
50
+    global box_selection_data, edit_data
51
+    
52
+    # Do edit
53
+    data = {"box_selection_data":box_selection_data}
54
+    action = edit.box_lift_action(data)
55
+    action.do_edit()
56
 
57
+    # Back to start state
58
+    edit_data = None
59
+    box_selection_data = None
60
+    
61
+    # Exit box mode if entered from overwrite with empty selection
62
+    if entered_from_overwrite == True:
63
+        _exit_to_overwrite()
64
+        return
65
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/callbackbridge.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/callbackbridge.py Changed
20
 
1
@@ -40,7 +40,9 @@
2
 clipmenuaction_set_compositor_data = None
3
 
4
 compositeeditor_get_compositor = None
5
- 
6
+
7
+dialogs_show_cyclic_error = None
8
+    
9
 editevent_tline_range_item_drop = None
10
 editevent_do_multiple_clip_insert = None
11
 
12
@@ -50,6 +52,7 @@
13
 mediaplugin_set_plugin_to_be_edited = None
14
 
15
 modesetting_set_default_edit_mode = None
16
+modesetting_kftool_mode_from_kf_editor = None
17
 
18
 movemodes_select_clip = None
19
 movemodes_select_from_box_selection = None
20
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/clipeffectseditor.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/clipeffectseditor.py Changed
105
 
1
@@ -248,20 +248,60 @@
2
         surface = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "trash.png")
3
         trash_button = guicomponents.PressLaunch(self.trash_pressed, surface, w=22, h=22)
4
         
5
+        surface = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "filters_up_arrow.png")
6
+        up_button = guicomponents.PressLaunch(self.up_pressed, surface, w=10, h=22)
7
+        up_button.surface_x = 0
8
+
9
+        surface = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "filters_down_arrow.png")
10
+        down_button = guicomponents.PressLaunch(self.down_pressed, surface, w=10, h=22)
11
+        down_button.surface_x = 0
12
+        down_button.surface_y = 10
13
+        
14
         self.trash_vbox = Gtk.VBox(False, 0)
15
         self.trash_vbox.pack_start(trash_button.widget, False, False, 0)
16
         self.trash_vbox.pack_start(Gtk.Label(), True, True, 0)
17
+
18
+        self.up_vbox = Gtk.VBox(False, 0)
19
+        self.up_vbox.pack_start(up_button.widget, False, False, 0)
20
+        self.up_vbox.pack_start(Gtk.Label(), True, True, 0)
21
+
22
+        self.down_vbox = Gtk.VBox(False, 0)
23
+        self.down_vbox.pack_start(down_button.widget, False, False, 0)
24
+        self.down_vbox.pack_start(Gtk.Label(), True, True, 0)
25
         
26
         self.widget = Gtk.HBox(False, 0)
27
         self.widget.pack_start(self.active_check_vbox, False, False, 0)
28
         self.widget.pack_start(self.expander_frame, True, True, 0)
29
         self.widget.pack_start(self.trash_vbox, False, False, 0)
30
+        self.widget.pack_start(self.up_vbox, False, False, 0)
31
+        self.widget.pack_start(self.down_vbox, False, False, 0)
32
         self.widget.pack_start(guiutils.pad_label(10,2), False, False, 0)
33
+
34
         self.widget.show_all()
35
 
36
     def trash_pressed(self, w, e):
37
         self.filter_stack.delete_filter_for_stack_item(self)
38
-    
39
+
40
+    def up_pressed(self, w, e):
41
+        from_index = self.filter_stack.get_filter_index(self.filter_object)
42
+        if len(self.filter_stack.filter_stack) == 1:
43
+            return
44
+        if from_index == 0:
45
+            return
46
+        to_index = from_index - 1
47
+
48
+        do_stack_move(self.filter_stack.clip, to_index, from_index, False)
49
+
50
+    def down_pressed(self, w, e):
51
+        from_index = self.filter_stack.get_filter_index(self.filter_object)
52
+        if len(self.filter_stack.filter_stack) == 1:
53
+            return
54
+        if from_index == len(self.filter_stack.filter_stack) - 1:
55
+            return
56
+        to_index = from_index + 1
57
+
58
+        do_stack_move(self.filter_stack.clip, to_index, from_index, False)
59
+
60
     def toggle_filter_active(self, widget):
61
         self.filter_object.active = (self.filter_object.active == False)
62
         self.filter_object.update_mlt_disabled_value()
63
@@ -322,7 +362,7 @@
64
             edit_panel.pack_start(guiutils.pad_label(12,12), False, False, 0)
65
             stack_item = FilterStackItem(filter_object, edit_panel, self)
66
             
67
-            # Put eveything back
68
+            # Put everything back
69
             self.filter_stack.insert(stack_index, stack_item)
70
             for stack_item in self.filter_stack:
71
                 self.widget.pack_start(stack_item.widget,False, False, 0)
72
@@ -461,6 +501,11 @@
73
 
74
     gui.editor_window.edit_multi.set_visible_child_name(appconsts.EDIT_MULTI_FILTERS)
75
 
76
+
77
+def set_clip_and_filter(clip, track, clip_index, filter_index):
78
+    set_clip(clip, track, clip_index, True)
79
+    _filter_stack.set_single_expanded(filter_index)
80
+
81
 def refresh_clip():
82
     if _filter_stack == None:
83
         return 
84
@@ -688,7 +733,7 @@
85
     update_stack(clip, track, clip_index)
86
     _filter_stack.set_expanded(expanded_panels)
87
 
88
-def do_stack_move(clip, insert_row, delete_row):
89
+def do_stack_move(clip, insert_row, delete_row, expand=True):
90
     data = {"clip":clip,
91
             "insert_index":insert_row,
92
             "delete_index":delete_row,
93
@@ -696,7 +741,10 @@
94
     action = edit.move_filter_action(data)
95
     set_stack_update_blocked()
96
     action.do_edit()
97
-    _filter_stack.set_single_expanded(insert_row)
98
+    if expand:
99
+        _filter_stack.set_single_expanded(insert_row)
100
+    else:
101
+        _filter_stack.set_all_filters_expanded_state(False)
102
     set_stack_update_unblocked()
103
 
104
 def reinit_stack_if_needed(force_update):
105
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/clipenddragmode.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/clipenddragmode.py Changed
201
 
1
@@ -22,6 +22,7 @@
2
 Module handles clip end dragging edits.
3
 """
4
 
5
+from gi.repository import Gdk
6
 
7
 import appconsts
8
 import gui
9
@@ -35,8 +36,16 @@
10
 _enter_mode = None
11
 _enter_draw_func = None
12
 
13
+# we are handling difference between insert on overwrite drags internally in
14
+# this module.
15
+INSERT_DRAG = 0
16
+OVERWRITE_DRAG = 1
17
+_submode = INSERT_DRAG
18
 
19
-def maybe_init_for_mouse_press(event, frame): 
20
+def get_submode():
21
+    return _sub_mode
22
+
23
+def maybe_init_for_mouse_press(event, frame):
24
     # See if we actually hit a clip
25
     track = tlinewidgets.get_track(event.y)
26
     if track == None:
27
@@ -53,10 +62,20 @@
28
     
29
     if clip.is_blanck_clip:
30
         return
31
-    
32
+
33
+    cut_frame = current_sequence().get_closest_cut_frame(track.id, frame)
34
+
35
+    if (event.get_state() & Gdk.ModifierType.MOD1_MASK):
36
+        _init_overwrite_drag(clip, clip_index, track, frame, cut_frame)
37
+    else:
38
+        _init_insert_drag(clip, clip_index, track, frame, cut_frame)
39
+
40
+def _init_insert_drag(clip, clip_index, track, frame, cut_frame):
41
+    global _submode
42
+    _submode = INSERT_DRAG
43
+
44
     # Now we will in fact enter CLIP_END_DRAG edit mode
45
     # See if we're dragging clip end or start
46
-    cut_frame = current_sequence().get_closest_cut_frame(track.id, frame)
47
     editing_clip_end = True
48
     if frame >= cut_frame:
49
         editing_clip_end = False
50
@@ -70,7 +89,7 @@
51
             bound_end = bound_end - 1
52
     else: # clip beginning drags
53
         bound_start = cut_frame - clip.clip_in 
54
-        bound_end =  cut_frame + (clip.clip_out - clip.clip_in) + 1
55
+        bound_end = cut_frame + (clip.clip_out - clip.clip_in) + 1
56
 
57
     global _enter_mode, _enter_draw_func, _edit_data
58
 
59
@@ -88,21 +107,113 @@
60
     _edit_data"editing_clip_end" = editing_clip_end
61
     _edit_data"bound_end" = bound_end
62
     _edit_data"bound_start" = bound_start
63
+    _edit_data"clip_end" = bound_end
64
+    _edit_data"clip_start" = bound_start
65
     _edit_data"track_height" = track.height
66
     _edit_data"orig_in" = cut_frame - 1
67
     _edit_data"orig_out" = cut_frame + (clip.clip_out - clip.clip_in)
68
+    _edit_data"submode" = _submode
69
+
70
+    _enter_mouse_drag_edit(editing_clip_end)
71
+
72
+def _init_overwrite_drag(clip, clip_index, track, frame, cut_frame):
73
+    global _submode
74
+    _submode = OVERWRITE_DRAG
75
+    
76
+    # Now we will in fact enter CLIP_END_DRAG edit mode
77
+    # See if we're dragging clip end or start
78
+    editing_clip_end = True
79
+    edit_frame = cut_frame 
80
+        
81
+    if frame >= cut_frame:
82
+        editing_clip_end = False
83
+
84
+    # Can't do overwrite drag on track first clip start or last clip end. 
85
+    if clip_index == 0 and editing_clip_end == False:
86
+        _init_insert_drag(clip, clip_index, track, frame, cut_frame)
87
+        return
88
+    elif clip_index == (len(track.clips) - 1) and editing_clip_end == True:
89
+        _init_insert_drag(clip, clip_index, track, frame, cut_frame)
90
+        return
91
+
92
+    from_clip, to_clip = _get_from_clip_and_to_clip(editing_clip_end, track, clip_index)
93
+
94
+    # Get edit bounds and clip start/end on tline for draw func
95
+    if editing_clip_end == True: # clip end drags
96
+
97
+        clip_start = cut_frame - (clip.clip_out - clip.clip_in)
98
+        clip_end = cut_frame
99
+
100
+        to_clip_start = track.clip_start(clip_index + 1) - to_clip.clip_in
101
+        to_clip_end = track.clip_start(clip_index + 1) + to_clip.clip_length() 
102
+        from_clip_start = track.clip_start(clip_index) 
103
+        from_clip_end = track.clip_start(clip_index) + from_clip.get_length() - from_clip.clip_in
104
+    else: # clip beginning drags
105
+        clip_start = cut_frame
106
+        clip_end = cut_frame + (to_clip.clip_out - to_clip.clip_in) + 1
107
+        
108
+        to_clip_start = track.clip_start(clip_index) - to_clip.clip_in
109
+        to_clip_end = track.clip_start(clip_index) + to_clip.clip_length()
110
+        from_clip_start = track.clip_start(clip_index - 1)
111
+        from_clip_end = track.clip_start(clip_index - 1) - from_clip.clip_in + from_clip.get_length() 
112
+        
113
+    if to_clip_start > from_clip_start:
114
+        bound_start = to_clip_start
115
+    else:
116
+        bound_start = from_clip_start
117
+    
118
+    if from_clip_end < to_clip_end:
119
+        bound_end = from_clip_end
120
+    else:
121
+        bound_end = to_clip_end
122
+            
123
+    global _enter_mode, _enter_draw_func, _edit_data
124
+
125
+    _enter_mode = editorstate.edit_mode
126
+    editorstate.edit_mode = editorstate.CLIP_END_DRAG
127
+
128
+    _enter_draw_func = tlinewidgets.canvas_widget.edit_mode_overlay_draw_func
129
 
130
+    _edit_data = {}
131
+    _edit_data"track" = track
132
+    _edit_data"clip_index" = clip_index
133
+    _edit_data"clip_media_type" = clip.media_type
134
+    _edit_data"frame" = frame
135
+    _edit_data"press_frame" = frame
136
+    _edit_data"edit_frame" = edit_frame
137
+    _edit_data"editing_clip_end" = editing_clip_end
138
+    _edit_data"bound_end" = bound_end
139
+    _edit_data"bound_start" = bound_start
140
+    _edit_data"clip_end" = clip_end
141
+    _edit_data"clip_start" = clip_start
142
+    _edit_data"track_height" = track.height
143
+    _edit_data"orig_in" = clip_start - 1
144
+    _edit_data"orig_out" = clip_end
145
+    _edit_data"submode" = _submode
146
+
147
+    _enter_mouse_drag_edit(editing_clip_end)
148
+
149
+def _enter_mouse_drag_edit(editing_clip_end):
150
     tlinewidgets.set_edit_mode(_edit_data, tlinewidgets.draw_clip_end_drag_overlay)
151
 
152
     if tlinewidgets.pointer_context == appconsts.POINTER_CONTEXT_NONE:
153
-        # We did CTRL + Mouse Right to get here, we need to set pointer context to left or right
154
         if editing_clip_end == True:
155
             tlinewidgets.pointer_context = appconsts.POINTER_CONTEXT_END_DRAG_RIGHT
156
         else:
157
             tlinewidgets.pointer_context = appconsts.POINTER_CONTEXT_END_DRAG_LEFT
158
 
159
     gui.editor_window.tline_cursor_manager.set_cursor_to_mode()
160
-
161
+    
162
+def _get_from_clip_and_to_clip(editing_clip_end, track, clip_index):
163
+    if editing_clip_end == True:
164
+        from_clip = track.clipsclip_index
165
+        to_clip = track.clipsclip_index + 1
166
+    else:
167
+        from_clip = track.clipsclip_index - 1
168
+        to_clip = track.clipsclip_index
169
+    
170
+    return (from_clip, to_clip)
171
+    
172
 def mouse_press(event, frame):
173
     frame = _legalize_frame(frame)
174
     _edit_data"frame" = frame
175
@@ -115,6 +226,13 @@
176
     updater.repaint_tline()
177
 
178
 def mouse_release(x, y, frame, state):
179
+    if _submode == INSERT_DRAG:
180
+        _do_insert_trim(x, y, frame, state)
181
+    else:
182
+        _do_overwrite_trim(x, y, frame, state)
183
+
184
+
185
+def _do_insert_trim(x, y, frame, state):
186
     frame = _legalize_frame(frame)
187
     _edit_data"frame" = frame
188
     updater.repaint_tline()
189
@@ -201,7 +319,51 @@
190
     _exit_clip_end_drag()
191
 
192
     updater.repaint_tline()
193
-        
194
+
195
+def _do_overwrite_trim(x, y, frame, state):
196
+    frame = _legalize_frame(frame)
197
+
198
+    updater.repaint_tline()
199
+
200
+    track = _edit_data"track"
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/clipmenuaction.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/clipmenuaction.py Changed
201
 
1
@@ -27,9 +27,11 @@
2
 from gi.repository import GLib
3
 from gi.repository import Gtk
4
 
5
+import copy
6
 from operator import itemgetter
7
 import os
8
 import time
9
+import hashlib
10
 
11
 import audiosync
12
 import appconsts
13
@@ -53,12 +55,14 @@
14
 import movemodes
15
 import projectaction
16
 import render
17
+import renderconsumer
18
 import singletracktransition
19
 import syncsplitevent
20
 import titler
21
 import tlinewidgets
22
 import tlineaction
23
 import updater
24
+import userfolders
25
 import utils
26
 
27
 # --------------------------------------------- menu data for each invocation.
28
@@ -472,7 +476,48 @@
29
 
30
 def _lift(data):
31
     tlineaction.lift_button_pressed()
32
+
33
+def _ripple_delete(data):
34
+    clip, track, item_id, item_data = data
35
+    clip_index = track.clips.index(clip)
36
+    clip_start_in_tline = track.clip_start(clip_index)
37
+    clip_end_in_tline = clip_start_in_tline + (clip.clip_out - clip.clip_in)
38
+
39
+    orig_mark_in = current_sequence().tractor.mark_in 
40
+    orig_mark_out = current_sequence().tractor.mark_out
41
+    
42
+    current_sequence().tractor.mark_in = clip_start_in_tline
43
+    current_sequence().tractor.mark_out = clip_end_in_tline
44
+
45
+    tlineaction.delete_range_button_pressed()
46
+
47
+    current_sequence().tractor.mark_in = orig_mark_in
48
+    current_sequence().tractor.mark_out = orig_mark_out
49
+    
50
+    updater.repaint_tline()
51
+
52
+def _ripple_delete_selection(data):
53
+    clip, track, item_id, item_data = data
54
+
55
+    start_clip_start_in_tline = track.clip_start(movemodes.selected_range_in)
56
+
57
+    end_clip = track.clipsmovemodes.selected_range_out
58
+    end_clip_start_in_tline = track.clip_start(movemodes.selected_range_out)
59
+    end_clip_end_in_tline = end_clip_start_in_tline + (end_clip.clip_out - end_clip.clip_in)
60
+
61
+    orig_mark_in = current_sequence().tractor.mark_in 
62
+    orig_mark_out = current_sequence().tractor.mark_out
63
+    
64
+    current_sequence().tractor.mark_in = start_clip_start_in_tline
65
+    current_sequence().tractor.mark_out = end_clip_end_in_tline
66
+
67
+    tlineaction.delete_range_button_pressed()
68
+
69
+    current_sequence().tractor.mark_in = orig_mark_in
70
+    current_sequence().tractor.mark_out = orig_mark_out
71
     
72
+    updater.repaint_tline()
73
+
74
 def _set_length(data):
75
     clip, track, item_id, item_data = data
76
     dialogs.clip_length_change_dialog(_change_clip_length_dialog_callback, clip, track)
77
@@ -707,8 +752,10 @@
78
     source_clip = paste_clips0
79
 
80
     # Currently selected clips are target clips
81
-    target_clips = clip
82
-    
83
+    target_clips = 
84
+    for i in range(movemodes.selected_range_in, movemodes.selected_range_out + 1):
85
+         target_clips.append(track.clipsi)
86
+
87
     actions =     
88
     for target_clip in target_clips:
89
         data = {"clip":target_clip,"clone_source_clip":source_clip}
90
@@ -777,6 +824,32 @@
91
     movemodes._select_multiple_clips(track.id, 0, track.clips.index(clip))
92
     updater.repaint_tline()
93
 
94
+def _mark_clip_range(data):
95
+    clip, track, item_id, item_data = data
96
+
97
+    clip_index = track.clips.index(clip)
98
+    clip_start_in_tline = track.clip_start(clip_index)
99
+    clip_end_in_tline = clip_start_in_tline + (clip.clip_out - clip.clip_in)
100
+    
101
+    current_sequence().tractor.mark_in = clip_start_in_tline
102
+    current_sequence().tractor.mark_out = clip_end_in_tline
103
+
104
+    updater.repaint_tline()
105
+
106
+def _mark_selection_range(data):
107
+    clip, track, item_id, item_data = data
108
+
109
+    start_clip_start_in_tline = track.clip_start(movemodes.selected_range_in)
110
+
111
+    end_clip = track.clipsmovemodes.selected_range_out
112
+    end_clip_start_in_tline = track.clip_start(movemodes.selected_range_out)
113
+    end_clip_end_in_tline = end_clip_start_in_tline + (end_clip.clip_out - end_clip.clip_in)
114
+    
115
+    current_sequence().tractor.mark_in = start_clip_start_in_tline
116
+    current_sequence().tractor.mark_out = end_clip_end_in_tline
117
+    
118
+    updater.repaint_tline()
119
+    
120
 def _add_clip_marker(data):
121
     clip, track, item_id, item_data = data
122
     current_frame = PLAYER().current_frame()
123
@@ -788,7 +861,6 @@
124
         current_frame_clip = None
125
     
126
     if current_frame_clip != clip:
127
-        # Playhead is not on popup clip
128
         return
129
 
130
     clip_start_in_tline = track.clip_start(current_frame_clip_index)
131
@@ -887,23 +959,78 @@
132
 def _set_audio_sync_clip(data):
133
     audiosync.init_select_tline_sync_clip(_get_data_with_xpos(data))
134
 
135
+def _set_container_default_enconding(data):
136
+    containerclip.set_project_default_video_endoding(data)
137
+
138
 def _render_tline_generator(data):
139
     clip, track, item_id, item_data = data
140
     clip, track, x = _popover_clip_data
141
     containerclip.render_tline_generator_clip(clip, _render_tline_generator_callback)
142
 
143
 def _render_tline_generator_callback(combo):
144
+    # Use selected render options are saved in clip.container_data.render_data 
145
     clip, track, x = _popover_clip_data
146
-    render_data = (clip, None, None, None) # We keep old data package format for now.
147
+    render_data_packet = (clip, None, None, None) # We keep old data package format for now.
148
     if combo.get_active() == 0: # 0 is render full media, see containeractions.set_video_endoding()
149
-        containerclip.render_full_media(render_data)
150
+        containerclip.render_full_media(render_data_packet)
151
     else:
152
-        containerclip.render_clip_length(render_data)
153
+        containerclip.render_clip_length(render_data_packet)
154
 
155
     """
156
     TODO: see if "cc_render_full_media", "cc_render_settings" can be deleted below.
157
     """
158
 
159
+def _update_seq_link(data):
160
+    clip, track, item_id, item_data = data
161
+
162
+    link_sequence = PROJECT().get_sequence_for_uid(clip.link_seq_data)
163
+    if link_sequence == None:
164
+        # Sequence has been deleted.
165
+        # TODO: info
166
+        return 
167
+
168
+    # Create unique file path in hidden render folder
169
+    folder = userfolders.get_render_dir()
170
+    uuid_str = hashlib.md5(str(os.urandom(32)).encode('utf-8')).hexdigest()
171
+    write_file = folder + uuid_str + ".xml"
172
+    
173
+    render_player = renderconsumer.XMLRenderPlayer( write_file, _sequence_link_update_xml_render_done_callback, 
174
+                                                    (clip, track, write_file), link_sequence, 
175
+                                                    PROJECT(), PLAYER())
176
+    render_player.start()
177
+
178
+def _sequence_link_update_xml_render_done_callback(data):
179
+    # We need to do this in a Gdk lock holding thread because it does GUI updates.
180
+    GLib.idle_add(_do_seq_link_tline_edit, data)
181
+
182
+def _do_seq_link_tline_edit(data):
183
+    # We do GUI updates on add, so we need GLib thread.
184
+    clip, track, write_file = data
185
+
186
+    # Container clips, create new container_data object and generate uuid for clip so it gets it own folder in.$XML_DATA/.../container_clips
187
+    new_clip = current_sequence().create_file_producer_clip(write_file, clip.name, False, clip.ttl)
188
+    new_clip.container_data = copy.deepcopy(clip.container_data)
189
+    # Unlike every other seq link update clip replace we need updated container data, e.g. 'unrendered_media' in container data is different between 
190
+    # new clip and old clip, and 'unrendered_media' is used if this updated xml clip is rendered.
191
+    new_clip.container_data.unrendered_media = write_file
192
+    new_clip.container_data.program = write_file # for consistencys sake, not used in this container type.
193
+    new_clip.container_data.rendered_media = None # updated sequence has not been rendered to video.
194
+    new_clip.container_data.rendered_media_range_in = -1
195
+    new_clip.container_data.rendered_media_range_out = -1
196
+    new_clip.container_data.unrendered_length = new_clip.get_length() - 1
197
+    new_clip.link_seq_data = copy.deepcopy(clip.link_seq_data)
198
+    
199
+    clip_index = track.clips.index(clip)
200
+    
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/compositorfades.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/compositorfades.py Changed
10
 
1
@@ -201,7 +201,7 @@
2
         # Remove all but first keyframe
3
         for i in range(0, len(keyframes) - 1):
4
             keyframes.pop(1)
5
-        # nOw this the same action as addin default keyframe on creation
6
+        # Now this the same action as addin default keyframe on creation
7
         keyframes = _add_default_fade_in(keyframe_property, property_klass, keyframes, fade_in_length)
8
     # Case keyframes exists after fade in length
9
     else:
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/containeractions.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/containeractions.py Changed
201
 
1
@@ -37,6 +37,7 @@
2
 
3
 import appconsts
4
 import callbackbridge
5
+import ccrutils
6
 import dialogutils
7
 import edit
8
 import editorstate
9
@@ -65,7 +66,7 @@
10
 all actions on container clips data.
11
 
12
 Objects of class containerclips.ContainerData are persistent data for container clips, 
13
-objects in this module created and discarded as needed.
14
+objects in this module are created and discarded as needed.
15
 """
16
 
17
 FULL_RENDER = 0
18
@@ -78,6 +79,7 @@
19
 MLT_XML_TYPE_ICON = None
20
 BLENDER_TYPE_ICON = None # Deprecated
21
 FLUXITY_TYPE_ICON = None
22
+SEQUENCE_LINK_TYPE_ICON = None
23
 
24
 NEWLINE = '\n'
25
 
26
@@ -90,11 +92,13 @@
27
          return MLTXMLContainerActions(container_data)
28
     elif container_data.container_type == appconsts.CONTAINER_CLIP_FLUXITY:
29
          return FluxityContainerActions(container_data)
30
+    elif container_data.container_type == appconsts.CONTAINER_CLIP_SEQUENCE_LINK:
31
+         return SequenceLinkContainerActions(container_data)
32
          
33
 # ------------------------------------------------------------ thumbnail creation helpers
34
 def _get_type_icon(container_type):
35
-    # TODO: When we get third move this into action objects.
36
-    global GMIC_TYPE_ICON, MLT_XML_TYPE_ICON, FLUXITY_TYPE_ICON
37
+    # TODO: We should move this into action objects.
38
+    global GMIC_TYPE_ICON, MLT_XML_TYPE_ICON, FLUXITY_TYPE_ICON, SEQUENCE_LINK_TYPE_ICON
39
     
40
     if GMIC_TYPE_ICON == None:
41
         GMIC_TYPE_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "container_clip_gmic.png")
42
@@ -102,6 +106,8 @@
43
         MLT_XML_TYPE_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "container_clip_mlt_xml.png")
44
     if FLUXITY_TYPE_ICON == None:
45
         FLUXITY_TYPE_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "container_clip_fluxity.png")
46
+    if SEQUENCE_LINK_TYPE_ICON == None:
47
+        SEQUENCE_LINK_TYPE_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "container_sequence_link_icon.png")
48
         
49
     if container_type == appconsts.CONTAINER_CLIP_GMIC:
50
         return GMIC_TYPE_ICON
51
@@ -109,7 +115,9 @@
52
         return MLT_XML_TYPE_ICON
53
     elif container_type == appconsts.CONTAINER_CLIP_FLUXITY:  
54
         return FLUXITY_TYPE_ICON
55
-        
56
+    elif container_type == appconsts.CONTAINER_CLIP_SEQUENCE_LINK:
57
+        return SEQUENCE_LINK_TYPE_ICON
58
+
59
 def _write_thumbnail_image(profile, file_path, action_object):
60
     """
61
     Writes thumbnail image from file producer
62
@@ -158,7 +166,8 @@
63
         self.container_data = container_data
64
         self.render_type = -1 # to be set in methods below
65
         self.do_filters_clone = False
66
-        
67
+        self.video_file_name = None
68
+
69
     def create_data_dirs_if_needed(self):
70
         session_folder = self.get_session_dir()
71
         clip_frames_folder = session_folder + appconsts.CC_CLIP_FRAMES_DIR
72
@@ -170,6 +179,25 @@
73
         if not os.path.exists(rendered_frames_folder):
74
             os.mkdir(rendered_frames_folder)
75
 
76
+    def clone_container_data_files(self, orig_clip):
77
+        if orig_clip.container_data.rendered_media != None:
78
+            orig_clip_action = get_action_object(orig_clip.container_data)
79
+            src_dir = orig_clip_action.get_session_dir()
80
+            dst_dir = self.get_session_dir()
81
+            
82
+            shutil.copytree(src_dir, dst_dir)
83
+            
84
+            # Fix 'rendered_media' path.
85
+            rendered_path = None
86
+            for f in os.listdir(orig_clip_action.get_session_dir()):
87
+                if os.path.basename(f).split()0 == "caintainer_clip":
88
+                    rendered_path = f
89
+
90
+            self.container_data.rendered_media = rendered_path
91
+
92
+        # This is only used between containers in same project so not cloning 
93
+        # file pointed to by 'container_data.unrendered_media' is acceptable.
94
+
95
     def validate_program(self):
96
         print("AbstractContainerActionObject.validate_program() not impl")
97
 
98
@@ -180,7 +208,7 @@
99
         job_proxy = self.get_launch_job_proxy()
100
         jobs.add_job(job_proxy)
101
         
102
-        # Render starts on callback from jobs.py
103
+        # Render starts on callback from jobs.py self._launch_render()
104
         
105
     def render_clip_length_media(self, clip):
106
         self.render_type = CLIP_LENGTH_RENDER
107
@@ -290,9 +318,13 @@
108
 
109
     def get_rendered_video_clip_path(self):
110
         if self.container_data.render_data.save_internally == True:
111
-            resource_path = self.get_session_dir() +  "/" + appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME + self.container_data.render_data.file_extension
112
+            if self.video_file_name == None:
113
+                file_name = appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME
114
+            else:
115
+                file_name = self.video_file_name
116
+            resource_path = self.get_session_dir() + "/" + appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME + self.container_data.render_data.file_extension
117
         else:
118
-            resource_path = self.container_data.render_data.render_dir +  "/" + self.container_data.render_data.file_name + self.container_data.render_data.file_extension
119
+            resource_path = self.container_data.render_data.render_dir + "/" + self.container_data.render_data.file_name + self.container_data.render_data.file_extension
120
     
121
         return resource_path
122
     
123
@@ -310,7 +342,7 @@
124
     def abort_render(self):
125
         print("AbstractContainerActionObject.abort_render not impl")
126
 
127
-    def create_producer_and_do_update_edit(self, unused_data):
128
+    def create_producer_and_do_update_edit(self, unused_data, video_file_name=None):
129
 
130
         # Using frame sequence as clip
131
         if  self.container_data.render_data.do_video_render == False:
132
@@ -362,7 +394,7 @@
133
         # Create default render data if not available, we need to know profile to do this.
134
         if self.container_data.render_data == None:
135
             self.container_data.render_data = toolsencoding.create_container_clip_default_render_data_object(current_sequence().profile)
136
-            
137
+    
138
         encoding_panel = toolsencoding.get_encoding_panel(self.container_data.render_data, True)
139
         if show_render_buttons == True:
140
             render_combo = Gtk.ComboBoxText()
141
@@ -410,7 +442,36 @@
142
                     self.external_encoding_callback(self.render_combo)
143
                     
144
         dialog.destroy()
145
+
146
+    def set_project_default_video_endoding(self):
147
+        current_profile_index = mltprofiles.get_profile_index_for_profile(current_sequence().profile)
148
+        # These need to re-initialized always when using this module.
149
+        toolsencoding.create_widgets(current_profile_index, True, True)
150
+
151
+        encoding_panel = toolsencoding.get_default_encoding_setting_panel(PROJECT().container_default_encoding)
152
+        encoding_panel.set_margin_right(150)
153
+        align = dialogutils.get_default_alignment(encoding_panel)
154
         
155
+        dialog = Gtk.Dialog(_("Set Container Default Encoding"),
156
+                            gui.editor_window.window,
157
+                            Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
158
+                            (_("Cancel"), Gtk.ResponseType.REJECT,
159
+                             (_("Set Default Encoding")), Gtk.ResponseType.ACCEPT))
160
+        dialog.vbox.pack_start(align, True, True, 0)
161
+        dialogutils.set_outer_margins(dialog.vbox)
162
+        dialog.set_resizable(False)
163
+        dialog.connect('response', self.default_encode_settings_callback)
164
+        dialog.show_all()
165
+
166
+    def default_encode_settings_callback(self, dialog, response_id):
167
+        if response_id == Gtk.ResponseType.ACCEPT:
168
+            encoding_panel = toolsencoding.widgets.encoding_panel
169
+            encoding_option_index = encoding_panel.encoding_selector.get_selected_encoding_index()
170
+            quality_option_index = encoding_panel.quality_selector.widget.get_active()
171
+            default_encoding = (encoding_option_index, quality_option_index)
172
+            PROJECT().container_default_encoding = default_encoding
173
+        dialog.destroy()
174
+
175
     def clone_clip(self, old_clip):
176
         new_container_data = copy.deepcopy(old_clip.container_data)
177
         new_container_data.generate_clip_id()
178
@@ -463,6 +524,7 @@
179
     def create_image_surface(self, icon_path):
180
         return _create_image_surface(icon_path)
181
 
182
+
183
 class GMicContainerActions(AbstractContainerActionObject):
184
 
185
     def __init__(self, container_data):
186
@@ -545,7 +607,9 @@
187
         for arg in args:
188
             command_list.append(arg)
189
 
190
-        subprocess.Popen(command_list)
191
+        # We need to wait() in thread.
192
+        command_list_runner = ProcessCommandListRunner(command_list)
193
+        command_list_runner.start()
194
         
195
     def update_render_status(self):
196
         GLib.idle_add(self._do_update_render_status)
197
@@ -617,6 +681,7 @@
198
         cr.set_source_surface(type_icon, 1, 30)
199
         cr.set_operator (cairo.OPERATOR_OVERLAY)
200
         cr.paint_with_alpha(0.5)
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/containerclip.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/containerclip.py Changed
98
 
1
@@ -20,6 +20,7 @@
2
 
3
 from gi.repository import Gtk, GLib
4
 
5
+import copy
6
 import hashlib
7
 import os
8
 import shutil
9
@@ -61,15 +62,17 @@
10
             self.container_clip_uid = -1 # This is set at clip creation time.
11
 
12
             self.container_type = container_type
13
-            self.program = program # path to program file
14
+            self.program = program # path to program file, used by Generators and Gmic containers.
15
 
16
-            self.rendered_media = None
17
+            self.rendered_media = None # lives in directory specified by 'self.container_clip_uid' in vault 'container_data' directory.
18
             self.rendered_media_range_in = -1
19
             self.rendered_media_range_out = -1
20
             self.last_render_type = containeractions.FULL_RENDER
21
             
22
-            self.unrendered_media = unrendered_media
23
+            self.unrendered_media = unrendered_media # 'unrendered_media' is created before ContainerClipData and 
24
+                                                     # lives in user file system (GMic) or vault 'rendered_clips' directory (rest).
25
             self.unrendered_length = None # This is also maximum length for media produced using this container data.
26
+                                          
27
             # This gets set later for some container types
28
             if unrendered_media != None:
29
                 self.unrendered_type = utils.get_media_type(unrendered_media)
30
@@ -112,7 +115,7 @@
31
 
32
 def render_tline_generator_clip(clip, callback):
33
     action_object = containeractions.get_action_object(clip.container_data)
34
-    action_object.set_video_endoding(None, callback, True)
35
+    action_object.set_video_endoding(None, callback, True) # All generator tline rendering goes via render settins and continues from given callback.
36
 
37
 def render_full_media(data):
38
     clip, track, item_id, item_data = data
39
@@ -143,6 +146,10 @@
40
     action_object = containeractions.get_action_object(clip.container_data)
41
     action_object.edit_program(clip)
42
 
43
+def set_project_default_video_endoding(data):
44
+    clip, track, item_id, item_data = data
45
+    action_object = containeractions.get_action_object(clip.container_data)
46
+    action_object.set_project_default_video_endoding()
47
 
48
 #------------------------------------------------------------- Cloning
49
 def clone_clip(clip):
50
@@ -415,6 +422,13 @@
51
     _update_gui_for_media_object_add()
52
 
53
 
54
+# ---------------------------------------------------------------------- SEQUENCE LINK
55
+def create_sequence_link_media_item(xml_file_path, media_name, linked_sequence_uid):
56
+    container_clip_data = ContainerClipData(appconsts.CONTAINER_CLIP_SEQUENCE_LINK, xml_file_path, xml_file_path)
57
+    media_item = ContainerClipMediaItem(PROJECT().next_media_file_id, media_name, container_clip_data)
58
+    PROJECT().add_sequence_link_media_object(media_item, linked_sequence_uid)
59
+    _update_gui_for_media_object_add()
60
+    
61
 
62
 # ---------------------------------------------------------------- MEDIA FILE OBJECT
63
 
64
@@ -440,7 +454,8 @@
65
         self.has_proxy_file = False
66
         self.is_proxy_file = False
67
         self.second_file_path = None
68
-
69
+        self.link_seq_data = None
70
+        
71
         self.ttl = None
72
 
73
         self.current_frame = 0
74
@@ -454,6 +469,9 @@
75
         print("create_mlt_producer() not implemented")
76
 
77
     def create_icon(self):
78
+        # NOTE: self.container_data.unrendered_length GETS SET HERE!!!!
79
+        # it IS NOT VERY OBVIOUS OR EXPECTED THAT THIS IS THE PLACE WHERE THIS GETS DONE!!!
80
+        # TODO: CHANGE FUNCTION NAME.
81
         try:
82
             action_object = containeractions.get_action_object(self.container_data)
83
             if self.icon_path == None:
84
@@ -470,3 +488,12 @@
85
             cr, scaled_icon = containeractions._create_image_surface(self.icon_path)
86
             self.icon = scaled_icon
87
 
88
+# ---------------------------------------------------------------- cloning
89
+def container_clone(clone_clip, old_clip):
90
+    clone_clip.container_data = copy.deepcopy(old_clip.container_data)
91
+    clone_clip.container_data.generate_clip_id()
92
+
93
+    action_object = containeractions.get_action_object(clone_clip.container_data)
94
+    action_object.clone_container_data_files(old_clip)
95
+    
96
+    
97
\ No newline at end of file
98
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/dialogs.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/dialogs.py Changed
194
 
1
@@ -41,6 +41,7 @@
2
 import mltprofiles
3
 import mltfilters
4
 import mlttransitions
5
+import mltplayer
6
 import panels
7
 import projectdatavaultgui
8
 import projectdatavault
9
@@ -403,6 +404,38 @@
10
     dialog.connect('response', callback)
11
     dialog.show()
12
 
13
+def save_generator_template(callback, default_name, data):
14
+    dialog = Gtk.FileChooserDialog( _("Save Generator Template"), None,
15
+                                   Gtk.FileChooserAction.SAVE,
16
+                                   (_("Cancel"), Gtk.ResponseType.CANCEL,
17
+                                    _("Save"), Gtk.ResponseType.ACCEPT), None)
18
+    dialog.set_action(Gtk.FileChooserAction.SAVE)
19
+    dialog.set_current_name(default_name)
20
+    dialog.set_do_overwrite_confirmation(True)
21
+
22
+    dialog.set_select_multiple(False)
23
+    file_filter = Gtk.FileFilter()
24
+    file_filter.set_name(_("Flowblade Generator Template"))
25
+    file_filter.add_pattern("*" + "generatortemplate")
26
+    dialog.add_filter(file_filter)
27
+    
28
+    dialog.connect('response', callback, data)
29
+    dialog.show()
30
+
31
+def load_generator_template(callback):
32
+    dialog = Gtk.FileChooserDialog(_("Load Generator Properties"), None,
33
+                                   Gtk.FileChooserAction.OPEN,
34
+                                   (_("Cancel"), Gtk.ResponseType.CANCEL,
35
+                                    _("OK"), Gtk.ResponseType.ACCEPT))
36
+    dialog.set_action(Gtk.FileChooserAction.OPEN)
37
+    dialog.set_select_multiple(False)
38
+    file_filter = Gtk.FileFilter()
39
+    file_filter.set_name(_("Flowblade Generator Template"))
40
+    file_filter.add_pattern("*" + "generatortemplate")
41
+    dialog.add_filter(file_filter)
42
+    dialog.connect('response', callback)
43
+    dialog.show()
44
+    
45
 def get_media_plugin_length(callback, data):
46
     dialog = Gtk.Dialog(_("Create Cloned Media Item"), gui.editor_window.window,
47
                         Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
48
@@ -488,18 +521,6 @@
49
         dialog.connect('response', callback, (data, name_entry))
50
     dialog.show_all()
51
     
52
-def save_env_data_dialog(callback):
53
-    dialog = Gtk.FileChooserDialog(_("Save Runtime Environment Data"),  gui.editor_window.window,
54
-                                   Gtk.FileChooserAction.SAVE,
55
-                                   (_("Cancel"), Gtk.ResponseType.CANCEL,
56
-                                   _("Save"), Gtk.ResponseType.ACCEPT))
57
-    dialog.set_action(Gtk.FileChooserAction.SAVE)
58
-    dialog.set_current_name("flowblade_runtime_environment_data")
59
-    dialog.set_do_overwrite_confirmation(True)
60
-    dialog.set_select_multiple(False)
61
-    dialog.connect('response', callback)
62
-    dialog.show()
63
-
64
 def save_cont_clip_edit_data(callback, default_name, edit_data):
65
     dialog = Gtk.FileChooserDialog(_("Save Container Clip Edit Data"),  gui.editor_window.window,
66
                                    Gtk.FileChooserAction.SAVE,
67
@@ -579,7 +600,7 @@
68
     # Application tab
69
     img = Gtk.Image.new_from_file(respaths.IMAGE_PATH + "flowbladeappicon.png")
70
     flow_label = Gtk.Label(label="Flowblade Movie Editor")
71
-    ver_label = Gtk.Label(label="2.18.1")
72
+    ver_label = Gtk.Label(label="2.20")
73
     janne_label = Gtk.Label(label="Copyright 2024 Janne Liljeblad and contributors.")
74
     page_label = Gtk.Label(label=_("Project page:") + " " + "<a href=\"https://github.com/jliljebl/flowblade\">https://github.com/jliljebl/flowblade</a>")
75
     page_label.set_use_markup(True)
76
@@ -720,14 +741,20 @@
77
         run_type = "FLATPAK"
78
     else:
79
         run_type = _("DEVELOPER VERSION")
80
-
81
     r4 = guiutils.get_left_justified_box(Gtk.Label(label=_("Running from: ")), Gtk.Label(label=run_type))
82
 
83
+    if mltplayer.get_sdl_consumer_version() == mltplayer.SDL_1:
84
+        p_ver = "SDL 1"
85
+    else:
86
+        p_ver = "SDL 2"
87
+    r5 = guiutils.get_left_justified_box(Gtk.Label(label=_("Consumer type: ")), Gtk.Label(label=p_ver))
88
+
89
     vbox = Gtk.VBox(False, 4)
90
     vbox.pack_start(r1, False, False, 0)
91
     vbox.pack_start(r2, False, False, 0)
92
     vbox.pack_start(r3, False, False, 0)
93
     vbox.pack_start(r4, False, False, 0)
94
+    vbox.pack_start(r5, False, False, 0)
95
 
96
 
97
     filters = sorted(mltenv.services)
98
@@ -1121,7 +1148,7 @@
99
                 "\u2022" + _(" It is recommended that you save Project before completing this operation.\n") + \
100
                 "\u2022" + _(" There is no Undo for this operation.\n") + \
101
                 "\u2022" + _(" Current Undo Stack will be destroyed.\n") + \
102
-                "\u2022" + _(" Replacing current media with shorter or othervise unsuitable media may result in\n   crashes or corrupted project data.")
103
+                "\u2022" + _(" Replacing current media with shorter or otherwise unsuitable media may result in\n   crashes or corrupted project data.")
104
     info_label = Gtk.Label(label=info_text)
105
     info_label.set_use_markup(True)
106
     info_box = guiutils.get_left_justified_box(info_label)
107
@@ -1831,7 +1858,7 @@
108
     dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
109
 
110
 def active_jobs_info(active_jobs_count):
111
-    primary_txt =  _("There are currenly ") + str(active_jobs_count) + _(" active job/s!")
112
+    primary_txt =  _("There are currently ") + str(active_jobs_count) + _(" active job/s!")
113
     secondary_txt = _("Let active jobs complete or cancel them before closing the application.")
114
     dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
115
 
116
@@ -1843,7 +1870,7 @@
117
 
118
 def no_timeline_ranges_dialog():
119
     primary_txt = _("Cannot log Ranges from Timelime!")
120
-    secondary_txt = _("'Range Log' functionality is intented to log areas of interest\nin Media Items.\n\nTo save interesting positions or ranges on Timeline use\nthe 'Timeline Markers' functionality.")
121
+    secondary_txt = _("'Range Log' functionality is intended to log areas of interest\nin Media Items.\n\nTo save interesting positions or ranges on Timeline use\nthe 'Timeline Markers' functionality.")
122
     dialogutils.info_message(primary_txt, secondary_txt, gui.editor_window.window)
123
 
124
 def add_compositor_dialog(compositors, callback):
125
@@ -1888,5 +1915,66 @@
126
 
127
     dialogutils.panel_ok_cancel_dialog(title, panel, accept_text, callback, value_spin)
128
 
129
+def set_parent_track_dialog(child_track, callback):
130
+    title = _("Set Track Clips Sync")
131
+    accept_text = _("Set")
132
+    
133
+    child_track_name = utils.get_track_name(child_track, editorstate.current_sequence())
134
+    label_text = _("Set Sync for all Clips on Track {} with Track:").format(child_track_name)
135
+    info_label = Gtk.Label(label=label_text)
136
+    info_label.set_margin_right(4)
137
+
138
+    tracks_combo = Gtk.ComboBoxText()
139
+    selection_data = 
140
+    active_index = 0
141
+    for i in range(len(editorstate.current_sequence().tracks) - 2, 0, -1):
142
+        track = editorstate.current_sequence().tracksi
143
+        if track is child_track:
144
+            continue
145
+        selection_data.append(track)
146
+        tracks_combo.append_text(utils.get_track_name(track, editorstate.current_sequence()))
147
+
148
+    active_index = 0
149
+    for i in range(0, len(selection_data)):
150
+        if selection_datai is editorstate.current_sequence().first_video_track():
151
+            active_index = i
152
+    tracks_combo.set_active(active_index)
153
+
154
+    hbox = Gtk.HBox(False, 2)
155
+    hbox.pack_start(info_label, False, False, 0)
156
+    hbox.pack_start(tracks_combo, False, False, 0)
157
+
158
+    panel = dialogutils.get_alignment2(hbox)
159
+
160
+    dialogutils.panel_ok_cancel_dialog(title, panel, accept_text, callback, (child_track, selection_data, tracks_combo))
161
+
162
+def select_link_sequence_for_container(callback):
163
+    title = _("Create Sequence Link Container Clip")
164
+    accept_text = _("Create Sequence Link Container")
165
+    
166
+    label_text = _("Create Sequence Link Container for Sequence:")
167
+    info_label = Gtk.Label(label=label_text)
168
+    info_label.set_margin_right(4)
169
+
170
+    sequences_combo = Gtk.ComboBoxText()
171
+    selection_data = 
172
+    active_index = 0
173
+    for i in range(0, len(editorstate.PROJECT().sequences)):
174
+        seq = editorstate.PROJECT().sequencesi
175
+        selection_data.append(seq)
176
+        sequences_combo.append_text(seq.name)
177
+    sequences_combo.set_active(0)
178
+
179
+    hbox = Gtk.HBox(False, 2)
180
+    hbox.pack_start(info_label, False, False, 0)
181
+    hbox.pack_start(sequences_combo, False, False, 0)
182
+
183
+    panel = dialogutils.get_alignment2(hbox)
184
+
185
+    dialogutils.panel_ok_cancel_dialog(title, panel, accept_text, callback, (sequences_combo, selection_data))
186
+    
187
 
188
-    
189
\ No newline at end of file
190
+def show_cyclic_error():
191
+    primary_txt = _("Cyclic relation detected!")
192
+    secondary_txt = _("Edit would create a cyclink linked sequence relation and was cancelled!")
193
+    dialogutils.warning_message(primary_txt, secondary_txt, gui.editor_window.window)
194
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/edit.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/edit.py Changed
201
 
1
@@ -35,6 +35,7 @@
2
 from editorstate import current_sequence
3
 from editorstate import get_track
4
 from editorstate import PLAYER
5
+from editorstate import PROJECT
6
 import mltfilters
7
 import movemodes
8
 import mediaplugin
9
@@ -186,6 +187,13 @@
10
     new_clip.name = clip.name
11
     new_clip.titler_data = copy.deepcopy(clip.titler_data)
12
     new_clip.slowmo_data = copy.deepcopy(clip.slowmo_data)
13
+    new_clip.link_seq_data = copy.deepcopy(clip.link_seq_data)
14
+    if clip.sync_data != None:
15
+        new_clip.sync_data = SyncData()
16
+        new_clip.sync_data.pos_offset = clip.sync_data.pos_offset
17
+        new_clip.sync_data.master_clip = clip.sync_data.master_clip
18
+        new_clip.sync_data.master_clip_track = clip.sync_data.master_clip_track
19
+        new_clip.sync_data.sync_state = clip.sync_data.sync_state 
20
     return new_clip
21
 
22
 def _create_mute_volume_filter(seq): 
23
@@ -355,13 +363,11 @@
24
 
25
         trackaction.maybe_do_auto_expand(tracks_clips_count_before)
26
         
27
+        undo.force_revert_if_cyclic_seq_links(PROJECT())
28
+        
29
     def undo(self):
30
         PLAYER().stop_playback()
31
 
32
-        # HACK, see above in __init()__
33
-        if self.stop_for_edit:
34
-            PLAYER().consumer.stop()
35
-
36
         movemodes.clear_selected_clips()  # selection not valid after change in sequence
37
         _remove_trailing_blanks_undo(self)
38
         _consolidate_all_blanks_undo(self)
39
@@ -371,22 +377,13 @@
40
         _remove_all_trailing_blanks(None)
41
 
42
         resync.calculate_and_set_child_clip_sync_states()
43
-    
44
-        # HACK, see above.
45
-        if self.stop_for_edit:
46
-            PLAYER().consumer.start()
47
         
48
         if do_gui_update:
49
-            #print("undo() _update_gui")
50
             self._update_gui()
51
             
52
     def redo(self):
53
         PLAYER().stop_playback()
54
 
55
-        # HACK, see above in __init()__
56
-        if self.stop_for_edit and self.is_part_of_consolidated_group == False:
57
-            PLAYER().consumer.stop()
58
-
59
         movemodes.clear_selected_clips() # selection is not valid after a change in sequence
60
 
61
         self.redo_func(self)
62
@@ -395,10 +392,6 @@
63
         _remove_trailing_blanks_redo(self)
64
 
65
         resync.calculate_and_set_child_clip_sync_states()
66
-
67
-        # HACK, see above.
68
-        if self.stop_for_edit and self.is_part_of_consolidated_group == False:
69
-            PLAYER().consumer.start()
70
                 
71
         # Update GUI.
72
         if do_gui_update:
73
@@ -449,24 +442,36 @@
74
     def do_consolidated_edit(self):
75
         # There is 1 - n edits in these,
76
         # and they are assumed to be all of the same type.
77
-        # ...well, they need to have properties:
78
+        # More precisely, they need to have properties:
79
         #    .exit_active_trimmode_on_edit
80
         #    .turn_on_stop_for_edit
81
-        #    .exit_active_trimmode_on_edit
82
         # same for all the consolidated edits for this to work reliably.
83
         if self.edit_actions0.exit_active_trimmode_on_edit:
84
             trimmodes.set_no_edit_trim_mode()
85
 
86
-        # We only want to do one consumer stop per group.
87
-        if self.edit_actions0.stop_for_edit or self.edit_actions0.turn_on_stop_for_edit:
88
-            PLAYER().consumer.stop()
89
-            
90
+        # We only do one gui update.
91
+        global do_gui_update
92
+        do_gui_update = False
93
+
94
         for edit_action in self.edit_actions:
95
             edit_action.is_part_of_consolidated_group = True
96
             
97
             # Tracks autoexpand-on-drop feature needs to be here to avoid caching data.
98
             tracks_clips_count_before = current_sequence().get_tracks_clips_counts()
99
 
100
+            # Some actions like audio splice may need the previous edit_action to 
101
+            # complete before they can be created, so for these we provide a lambda 
102
+            # that cretes the edit action.
103
+            if callable(edit_action) == True:
104
+                new_edit_action = edit_action()
105
+                old_index = self.edit_actions.index(edit_action)
106
+                self.edit_actionsold_index = new_edit_action
107
+                edit_action = new_edit_action
108
+
109
+            # Enable GUI update for last action.
110
+            if edit_action is self.edit_actionslen(self.edit_actions) - 1:
111
+                do_gui_update = True
112
+
113
             edit_action.redo()
114
 
115
             if edit_action.turn_on_stop_for_edit:
116
@@ -476,22 +481,38 @@
117
             edit_done_since_last_save = True
118
 
119
             trackaction.maybe_do_auto_expand(tracks_clips_count_before)
120
-        
121
+
122
+        do_gui_update = True
123
+                
124
         undo.register_edit(self)
125
 
126
-        # We only want to do one consumer start per group.
127
-        if self.edit_actions0.stop_for_edit or self.edit_actions0.turn_on_stop_for_edit:
128
-            PLAYER().consumer.start()
129
-            
130
+        undo.force_revert_if_cyclic_seq_links(PROJECT())
131
+        
132
     def redo(self):
133
+        # We only do one gui update.
134
+        global do_gui_update
135
+        do_gui_update = False
136
+        
137
         for edit_action in self.edit_actions:
138
+            if edit_action is self.edit_actionslen(self.edit_actions) - 1:
139
+                do_gui_update = True
140
+
141
             edit_action.redo()
142
             
143
     def undo(self):
144
+        # We only do one gui update.
145
+        global do_gui_update
146
+        do_gui_update = False
147
+        
148
         for edit_action in reversed(self.edit_actions):
149
-            #edit_action = self.edit_actionsi
150
+            if edit_action is self.edit_actions0:
151
+                do_gui_update = True
152
+
153
             edit_action.undo()
154
-        
155
+
156
+
157
+
158
+
159
 # ---------------------------------------------------- compositor sync methods
160
 def get_full_compositor_sync_data():
161
     # Returns list of tuples in form (compositor, orig_in, orig_out, clip_start, clip_end)
162
@@ -555,9 +576,22 @@
163
         self.clip_in = None
164
         self.clip_out = None
165
         self.master_clip = None
166
+        self.master_clip_track = None
167
         self.master_inframe = None
168
         self.master_audio_index = None # this does nothing? try to remove.
169
-           
170
+
171
+def _switch_synched_clip(child_clip, child_track, old_child_clip):
172
+    # Set sync data
173
+    resync.clip_added_to_timeline(child_clip, child_track)
174
+    resync.clip_removed_from_timeline(old_child_clip)
175
+
176
+def _clone_sync_data(new_clip, clip):
177
+    new_clip.sync_data = SyncData()
178
+    new_clip.sync_data.pos_offset = clip.sync_data.pos_offset
179
+    new_clip.sync_data.master_clip = clip.sync_data.master_clip
180
+    new_clip.sync_data.master_clip_track = clip.sync_data.master_clip_track
181
+    new_clip.sync_data.sync_state = clip.sync_data.sync_state 
182
+    
183
 #-------------------- APPEND CLIP
184
 # "track","clip","clip_in","clip_out"
185
 # Appends clip to track
186
@@ -572,6 +606,21 @@
187
     self.clip.index = self.track.count()
188
     append_clip(self.track, self.clip, self.clip_in, self.clip_out)
189
 
190
+#-------------------- APPEND MULTIPLE CLIPS
191
+# "track","clips"
192
+# Appends clip to track
193
+def append_multiple_action(data):
194
+    action = EditAction(_append_multiple_undo,_append_multiple_redo, data)
195
+    return action
196
+
197
+def _append_multiple_undo(self):
198
+    for add_clip in self.clips:
199
+        self.clip = _remove_clip(self.track, self.append_index)
200
+
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/editevent.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/editevent.py Changed
127
 
1
@@ -95,17 +95,13 @@
2
             "clip_in":clip_in,
3
             "clip_out":clip_out}
4
     action = edit.insert_action(data)
5
-    action.do_edit()
6
+    _do_action_and_maybe_autosplit_action(action, new_clip, track)
7
     
8
     updater.display_tline_cut_frame(track, index)
9
 
10
 def do_multiple_clip_insert(track, clips, tline_pos, use_as_action_build_func_for_paste=False):
11
     index = _get_insert_index(track, tline_pos)
12
     
13
-    if use_as_action_build_func_for_paste == True:
14
-        # For this use case there happens a cut before the insert is done.
15
-        index += 1
16
-    
17
     # Can't put audio media on video track
18
     for new_clip in clips:
19
         if isinstance(new_clip, int):
20
@@ -137,6 +133,7 @@
21
     # Dropping on first available frame after last clip is append 
22
     # and is handled by insert code
23
     if track.get_length() == frame:
24
+        print("insert")
25
         return False
26
 
27
     # Clip dropped after last clip on track
28
@@ -152,7 +149,8 @@
29
                 "clip_in":clip.mark_in,
30
                 "clip_out":clip.mark_out}
31
         action = edit.dnd_after_track_end_action(data)
32
-        action.do_edit()
33
+        _do_action_and_maybe_autosplit_action(action, clip, track)
34
+
35
 
36
         updater.display_tline_cut_frame(track, index + 1)
37
         return True
38
@@ -181,7 +179,7 @@
39
                         "index":index,
40
                         "clip_in":clip.mark_in}
41
                 action = edit.dnd_on_blank_replace_action(data)
42
-                action.do_edit()
43
+                _do_action_and_maybe_autosplit_action(action, clip, track)
44
             else: # If dropped clip shorter then blank, replace start part of blank
45
                 data = {"track":track,
46
                         "clip":clip,
47
@@ -190,7 +188,7 @@
48
                         "clip_in":clip.mark_in,
49
                         "clip_out":clip.mark_out}
50
                 action = edit.dnd_on_blank_start_action(data)
51
-                action.do_edit()
52
+                _do_action_and_maybe_autosplit_action(action, clip, track)
53
 
54
             updater.display_tline_cut_frame(track, index)
55
             return True
56
@@ -206,7 +204,7 @@
57
                     "clip_in":clip.mark_in,
58
                     "clip_out":clip.mark_out}
59
             action = edit.dnd_on_blank_end_action(data)
60
-            action.do_edit()
61
+            _do_action_and_maybe_autosplit_action(action, clip, track)
62
         else: # Overwrite part of blank ei toimi
63
             data = {"track":track,
64
                     "clip":clip,
65
@@ -216,13 +214,32 @@
66
                     "clip_in":clip.mark_in,
67
                     "clip_out":clip.mark_out}
68
             action = edit.dnd_on_blank_middle_action(data)
69
-            action.do_edit()
70
+            _do_action_and_maybe_autosplit_action(action, clip, track)
71
             
72
         updater.display_tline_cut_frame(track, index + 1)
73
         return True
74
 
75
     return False # this won't be hit
76
+
77
+def _do_action_and_maybe_autosplit_action(action, clip, track):
78
     
79
+    if editorpersistance.prefs.sync_autosplit == appconsts.AUDIO_AUTO_SPLIT_ALL_TACKS:
80
+        auto_split = True
81
+    elif editorpersistance.prefs.sync_autosplit == appconsts.AUDIO_AUTO_SPLIT_V1_V2 and (track.id == current_sequence().first_video_index or track.id == current_sequence().first_video_index + 1):
82
+        auto_split = True
83
+    elif editorpersistance.prefs.sync_autosplit == appconsts.AUDIO_AUTO_SPLIT_V1 and track.id == current_sequence().first_video_index:
84
+        auto_split = True
85
+    else:
86
+        auto_split = False
87
+    
88
+    if track.type == appconsts.AUDIO or auto_split == False:
89
+        action.do_edit()
90
+    else:
91
+        split_action = lambda : syncsplitevent.get_synched_split_action_for_clip_and_track(clip, track)
92
+        edit_actions = action, split_action
93
+        action = edit.ConsolidatedEditAction(edit_actions)
94
+        action.do_consolidated_edit()
95
+
96
 def _get_insert_index(track, tline_pos):
97
     cut_frame = current_sequence().get_closest_cut_frame(track.id, tline_pos)
98
     index = current_sequence().get_clip_index(track, cut_frame)
99
@@ -559,6 +576,7 @@
100
             new_clip = current_sequence().create_file_producer_clip(media_file.path, media_file.name, False, media_file.ttl)
101
             new_clip.container_data = copy.deepcopy(media_file.container_data)
102
             new_clip.container_data.generate_clip_id()
103
+            new_clip.link_seq_data = media_file.link_seq_data
104
     else:
105
         new_clip = current_sequence().create_pattern_producer(media_file)
106
 
107
@@ -602,9 +620,9 @@
108
                 if media_file.type == appconsts.IMAGE_SEQUENCE:
109
                     new_clip.mark_out = media_file.length
110
 
111
-    # Images fom media panel get bin default length.
112
+    # Images from media panel get bin default length.
113
     use_clip_in = False
114
-    if dnd.drag_source != dnd.SOURCE_MONITOR_WIDGET and  new_clip.media_type == appconsts.IMAGE:
115
+    if dnd.drag_source != dnd.SOURCE_MONITOR_WIDGET and new_clip.media_type == appconsts.IMAGE:
116
         default_grfx_length = PROJECT().get_current_bin_graphics_default_length()
117
         in_fr = (new_clip.get_length() - 1) // 2 - (default_grfx_length // 2)
118
         out_fr = in_fr + default_grfx_length - 1
119
@@ -651,7 +669,6 @@
120
     if clip.container_data == None:
121
         return
122
 
123
-    print("---------------renderdata:", clip.container_data.render_data)
124
     if editorpersistance.prefs.auto_render_media_plugins == True:
125
         if clip.container_data.container_type == appconsts.CONTAINER_CLIP_FLUXITY:
126
             action_object = containeractions.get_action_object(clip.container_data)
127
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/editorpersistance.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/editorpersistance.py Changed
50
 
1
@@ -82,6 +82,7 @@
2
     prefs.buttons_style = NO_DECORATIONS 
3
     prefs.show_tool_tooltips = True
4
     prefs.theme = appconsts.FLOWBLADE_THEME_NEUTRAL
5
+    prefs.icons_scale = appconsts.ICONS_SCALE_DEFAULT
6
 
7
     try:
8
         recent_projects = utils.unpickle(recents_file_path)
9
@@ -117,7 +118,7 @@
10
             write_file = afw.get_file()
11
             pickle.dump(prefs, write_file)
12
         print("prefs updated to new version, new param count:", len(prefs.__dict__))
13
-        
14
+            
15
 def save():
16
     """
17
     Write out prefs and recent_projects files
18
@@ -192,7 +193,7 @@
19
     auto_center_check, play_pause_button, timeline_start_end_button, auto_center_on_updown, \
20
     ffwd_rev_shift_spin, ffwd_rev_caps_spin, follow_move_range, loop_clips = playback_prefs_widgets
21
     
22
-    force_language_combo, disp_splash, window_mode_combo, full_names, tracks_combo, icons_combo, project_panel_width_spin, \
23
+    force_language_combo, disp_splash, window_mode_combo, full_names, tracks_combo, project_panel_width_spin, \
24
     edit_panel_width_spin, media_panel_width_spin, layout_monitor, filter_select_width_spin = view_prefs_widgets
25
 
26
     perf_render_threads, perf_drop_frames = performance_widgets
27
@@ -230,7 +231,6 @@
28
     prefs.show_full_file_names = full_names.get_active()
29
     prefs.center_on_arrow_move = auto_center_on_updown.get_active()
30
     prefs.tracks_scale = tracks_combo.get_active()
31
-    prefs.icons_scale = icons_combo.get_active()
32
     prefs.playback_follow_move_tline_range = follow_move_range.get_active()
33
     prefs.auto_save_delay_value_index = autosave_combo.get_active()
34
     prefs.layout_display_index = layout_monitor.get_active()
35
@@ -383,7 +383,13 @@
36
         self.zoom_to_playhead = True
37
         self.filter_select_width = 220
38
         self.tracks_scale = appconsts.TRACKS_SCALE_DEFAULT
39
-        self.icons_scale = appconsts.ICONS_SCALE_DEFAULT
40
+        self.icons_scale = appconsts.ICONS_SCALE_DEFAULT  # DEPRECATED, we are not ever getting useful results with this.
41
         self.project_panel_width = PROJECT_PANEL_WIDTH_MIN
42
         self.editor_panel_width = EDIT_PANEL_WIDTH_MIN 
43
         self.media_panel_width = MEDIA_PANEL_WIDTH_MIN
44
+        self.sync_autosplit = appconsts.AUDIO_AUTO_SPLIT_OFF
45
+        self.sync_mirror = True
46
+        self.sync_dualtrim = False
47
+        self.show_sync = True
48
+        self.wide_multitrim_slip = False
49
+        self.disable_drag_when_selected = True
50
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/editorstate.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/editorstate.py Changed
28
 
1
@@ -29,6 +29,8 @@
2
 
3
 import appconsts
4
 
5
+# NOTE: This cannot ever be made to import anything else.
6
+
7
 # Edit modes
8
 INSERT_MOVE = 0
9
 OVERWRITE_MOVE = 1
10
@@ -96,7 +98,7 @@
11
 # Runtime environment data
12
 gtk_version = None
13
 mlt_version = None
14
-appversion = "2.18.1"
15
+appversion = "2.20"
16
 RUNNING_FROM_INSTALLATION = 0
17
 RUNNING_FROM_DEV_VERSION = 1
18
 RUNNING_FROM_FLATPAK = 2
19
@@ -150,7 +152,7 @@
20
 gmic_path = None
21
 
22
 # For development and test use.
23
-force_sdl2 = False 
24
+force_sdl2 = True 
25
 
26
 def current_is_move_mode():
27
     if ((edit_mode == INSERT_MOVE) or (edit_mode == OVERWRITE_MOVE) or (edit_mode == MULTI_MOVE)):
28
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/editorwindow.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/editorwindow.py Changed
201
 
1
@@ -74,6 +74,7 @@
2
 import shortcuts
3
 import shortcutsdialog
4
 import singletracktransition
5
+import syncsplitevent
6
 import titler
7
 import tlineaction
8
 import tlinecursors
9
@@ -373,6 +374,10 @@
10
 
11
         # Effects select panel
12
         effect_select_panel, effect_select_list_view, effect_select_combo_box  = panels.get_effect_selection_panel(clipeffectseditor.effect_select_row_double_clicked)
13
+        # example code for using widget css from deleted test dev branch
14
+        #gui.apply_widget_css_class(effect_select_list_view.treeview, "bold-text", "bold-text-class.css")
15
+        #effect_select_list_view.treeview.set_name("light-text")
16
+        #gui.apply_widget_css(effect_select_list_view.treeview, "light-text", "light-text-id.css")
17
         self.effect_select_panel = effect_select_panel
18
         self.effect_select_list_view = effect_select_list_view
19
         self.effect_select_combo_box = effect_select_combo_box
20
@@ -514,19 +519,8 @@
21
         self._create_monitor_buttons()
22
         self._create_monitor_row_widgets()
23
 
24
-        self.player_buttons = glassbuttons.PlayerButtons()
25
-        if (editorpersistance.prefs.play_pause == True):
26
-            if (editorpersistance.prefs.timeline_start_end is True):
27
-            # ------------------------------ timeline_start_end_button
28
-                tooltips = _("Start - Home key"), _("End - End key"),_("Prev Frame - Arrow Left"), _("Next Frame - Arrow Right"), _("Play/Pause- Space"), _("Mark In - I"), _("Mark Out - O"), _("Clear Marks"), _("To Mark In"), _("To Mark Out")
29
-            else:
30
-                tooltips = _("Prev Frame - Arrow Left"), _("Next Frame - Arrow Right"), _("Play/Pause - Space"), _("Mark In - I"), _("Mark Out - O"), _("Clear Marks"), _("To Mark In"), _("To Mark Out")
31
-        else:
32
-            if (editorpersistance.prefs.timeline_start_end is True):
33
-                tooltips = _("Start - Home key"), _("End - End key"),_("Prev Frame - Arrow Left"), _("Next Frame - Arrow Right"), _("Play - Space"), _("Stop - Space"), _("Mark In - I"), _("Mark Out - O"), _("Clear Marks"), _("To Mark In"), _("To Mark Out")
34
-            else:
35
-                tooltips = _("Prev Frame - Arrow Left"), _("Next Frame - Arrow Right"), _("Play - Space"), _("Stop - Space"), _("Mark In - I"), _("Mark Out - O"), _("Clear Marks"), _("To Mark In"), _("To Mark Out")
36
-            # ------------------------------End of timeline_start_end_button
37
+        self.player_buttons = glassbuttons.PlayerButtonsCompact()
38
+        tooltips = _("Prev Frame - Arrow Left"),  _("Play/Pause - Space"), _("Next Frame - Arrow Right")
39
         tooltip_runner = glassbuttons.TooltipRunner(self.player_buttons, tooltips)
40
         if editorpersistance.prefs.buttons_style == 2: # NO_DECORATIONS
41
             self.player_buttons.no_decorations = True
42
@@ -535,14 +529,33 @@
43
         self.view_mode_select.widget.set_margin_end(10)
44
         self.trim_view_select = guicomponents.get_trim_view_select_launcher(monitorevent.trim_view_menu_launched)
45
 
46
+        callbacks = monitorevent.mark_in_pressed,
47
+                     monitorevent.mark_out_pressed,
48
+                     monitorevent.marks_clear_pressed
49
+        markbuttons = glassbuttons.MarkButtons(callbacks)
50
+        markbuttons.widget.set_margin_right(12)
51
+        mbtooltips = _("Mark In - I"),  _("Mark Out - O"), _("Clear Marks - Alt + K")
52
+        tooltip_runner = glassbuttons.TooltipRunner(markbuttons, mbtooltips)
53
+        
54
         player_buttons_row = Gtk.HBox(False, 0)
55
         player_buttons_row.pack_start(self.monitor_switch.widget, False, False, 0)
56
         player_buttons_row.pack_start(Gtk.Label(), True, True, 0)
57
+        #player_buttons_row.pack_start(self.monitor_clip_type.widget, False, False, 0)
58
+        #player_buttons_row.pack_start(Gtk.Label(), True, True, 0)
59
         player_buttons_row.pack_start(self.player_buttons.widget, False, False, 0)
60
         player_buttons_row.pack_start(Gtk.Label(), True, True, 0)
61
+        #player_buttons_row.pack_start(Gtk.Label(), True, True, 0)
62
+        player_buttons_row.pack_start(markbuttons.widget, False, False, 0)
63
         player_buttons_row.pack_start(self.trim_view_select.widget, False, False, 0)
64
         player_buttons_row.pack_start(self.view_mode_select.widget, False, False, 0)
65
-        player_buttons_row.set_margin_top(4)
66
+        player_buttons_row.set_margin_top(8)
67
+        player_buttons_row.set_margin_bottom(6)
68
+        player_buttons_row.set_margin_left(12)
69
+        player_buttons_row.set_margin_right(12)
70
+
71
+        player_buttons_row.set_name("player-bar")
72
+        gui.apply_widget_css(player_buttons_row, "player-bar", "player-bar-id.css")
73
+        
74
         self.player_buttons_row = player_buttons_row
75
 
76
         # Switch / pos bar row
77
@@ -575,7 +588,9 @@
78
         guiutils.set_margins(self.edit_buttons_frame, 1, 0, 0, 0)
79
 
80
         self.edit_buttons_frame.override_background_color(Gtk.StateFlags.NORMAL, gui.get_mid_neutral_color())
81
-            
82
+        #self.edit_buttons_frame.set_name("middlebar")
83
+        #gui.apply_widget_css(player_buttons_row, "middlebar", "middlebar-id.css")
84
+                    
85
     def _init_tline(self):
86
         self.tline_scale = tlinewidgets.TimeLineFrameScale(modesetting.set_default_edit_mode,
87
                                                            updater.mouse_scroll_zoom)
88
@@ -589,11 +604,8 @@
89
         info_h.pack_start(Gtk.Label(), True, True, 0)
90
         # Aug-2019 - SvdB - BB - Height doesn't need to be doubled. 1.4x is nicer
91
         size_adj = 1
92
-        size_x = tlinewidgets.COLUMN_WIDTH - 22 - 22 - 22
93
+        size_x = tlinewidgets.COLUMN_WIDTH - 22 - 22 - 22 - 22
94
         size_y = tlinewidgets.SCALE_HEIGHT
95
-        if editorpersistance.prefs.double_track_hights:
96
-            size_adj = 1.4
97
-            size_x = tlinewidgets.COLUMN_WIDTH - (66*size_adj)
98
 
99
         info_h.set_size_request(size_x, size_y)
100
 
101
@@ -607,9 +619,13 @@
102
         levels_launcher_surface = guiutils.get_cairo_image("audio_levels_menu_launch")
103
         levels_launcher = guicomponents.PressLaunchPopover(trackaction.tline_properties_menu_launch_pressed, levels_launcher_surface, 22*size_adj, 22*size_adj)
104
 
105
+        sync_launcher_surface = guiutils.get_cairo_image("sync_menu_launch")
106
+        sync_launcher = guicomponents.PressLaunchPopover(syncsplitevent.sync_menu_launch_pressed, sync_launcher_surface, 22*size_adj, 22*size_adj)
107
+
108
         # Timeline top row
109
         tline_hbox_1 = Gtk.HBox()
110
         tline_hbox_1.pack_start(info_h, False, False, 0)
111
+        tline_hbox_1.pack_start(sync_launcher.widget, False, False, 0)
112
         tline_hbox_1.pack_start(levels_launcher.widget, False, False, 0)
113
         tline_hbox_1.pack_start(tracks_launcher.widget, False, False, 0)
114
         tline_hbox_1.pack_start(markers_launcher.widget, False, False, 0)
115
@@ -823,6 +839,7 @@
116
             ('RangeOverWriteClip', None, _('Range Overwrite'), None, None, lambda a:tlineaction.range_overwrite_pressed()),
117
             ('CutClip', None, _('Cut Clip At Playhead'), None, None, lambda a:tlineaction.cut_pressed()),
118
             ('SequenceSplit', None, _('Split to new Sequence at Playhead Position'), None, None, lambda a:tlineaction.sequence_split_pressed()),
119
+            ('SequenceDuplicate', None, _('Duplicate Sequence'), None, None, lambda a:projectaction.duplicate_sequence()),
120
             ('DeleteClip', None, _('Lift'), None, None, lambda a:tlineaction.lift_button_pressed()),
121
             ('SpliceOutClip', None, _('Splice Out'), None, None, lambda a:tlineaction.splice_out_button_pressed()),
122
             ('ResyncSelected', None, _('Resync Track'),  resync_shortcut, None, lambda a:tlineaction.resync_button_pressed()),
123
@@ -861,6 +878,7 @@
124
             ('LoadMediaPluginScript', None, _('Load Generator Script...'), None, None,lambda w: containerclip.create_fluxity_media_item()),
125
             ('CreateSelectionCompound', None, _('From Selected Clips'), None, None, lambda a:projectaction.create_selection_compound_clip()),
126
             ('CreateSequenceCompound', None, _('From Current Sequence'), None, None, lambda a:projectaction.create_sequence_compound_clip()),
127
+            ('CreateSequenceLinkContainerItem', None, _("Add Sequence Link Container Clip..."), None, None, lambda a:projectaction.create_sequence_link_container()),
128
             ('CreateSequenceFreezeCompound', None, _('From Current Sequence With Freeze Frame at Playhead Position'), None, None, lambda a:projectaction.create_sequence_freeze_frame_compound_clip()),
129
             ('AudioSyncCompoundClip', None, _('Audio Sync Merge Clip From 2 Media Items '), None, None, lambda a:audiosync.create_audio_sync_compound_clip()),
130
             ('ImportProjectMedia', None, _('Import Media From Project...'), None, None, lambda a:projectaction.import_project_media()),
131
@@ -974,6 +992,7 @@
132
                         <separator/>
133
                         <menuitem action='CreateGMicContainerItem'/>
134
                     </menu>
135
+                    <menuitem action='CreateSequenceLinkContainerItem'/>
136
                     <separator/>
137
                     <menuitem action='AddMediaFolder'/>
138
                     <menuitem action='ImportProjectMedia'/>
139
@@ -1004,6 +1023,7 @@
140
                     <separator/>
141
                     <menuitem action='CombineSequences'/>
142
                     <menuitem action='SequenceSplit'/>
143
+                    <menuitem action='SequenceDuplicate'/>
144
                     <separator/>
145
                     <menuitem action='AddVideoTrack'/>
146
                     <menuitem action='AddAudioTrack'/>
147
@@ -1230,15 +1250,6 @@
148
             menu.append(new_item)
149
             new_item.show()
150
 
151
-    """
152
-    def hide_tline_render_strip(self):
153
-        guiutils.remove_children(self.tline_renderer_hbox)
154
-
155
-    def show_tline_render_strip(self):
156
-        self.tline_renderer_hbox.pack_start(self.pad_box, False, False, 0)
157
-        self.tline_renderer_hbox.pack_start(self.tline_render_strip.widget, True, True, 0)
158
-    """
159
-    
160
     def _change_windows_preference(self, widget, new_window_layout):
161
         if widget.get_active() == False:
162
             return
163
@@ -1299,6 +1310,11 @@
164
     # ----------------------------------------------------------- GUI components monitor, middlebar.
165
     def _create_monitor_buttons(self):
166
         self.monitor_switch = guicomponents.MonitorSwitch(self._monitor_switch_handler)
167
+        self.monitor_switch.widget.set_margin_top(2)
168
+        self.monitor_switch.widget.set_margin_right(57)
169
+
170
+        self.monitor_clip_type = guicomponents.MonitorClipType()
171
+        #self.monitor_clip_type.widget.set_margin_right(17)
172
 
173
     def _create_monitor_row_widgets(self):
174
         self.monitor_tc_info = guicomponents.MonitorMarksTCInfo()
175
@@ -1312,54 +1328,11 @@
176
             updater.display_clip_in_monitor()
177
 
178
     def connect_player(self, mltplayer):
179
-        # Buttons
180
-        # NOTE: ORDER OF CALLBACKS IS THE SAME AS ORDER OF BUTTONS FROM LEFT TO RIGHT
181
-        # Jul-2016 - SvdB - For play/pause button
182
-        if editorpersistance.prefs.play_pause == False:
183
-            # ------------------------------timeline_start_end_button
184
-            if (editorpersistance.prefs.timeline_start_end is True):
185
-                pressed_callback_funcs = monitorevent.start_pressed,  #  go to start
186
-                                          monitorevent.end_pressed,   #  go to  end
187
-                                          monitorevent.prev_pressed,
188
-                                          monitorevent.next_pressed,
189
-                                          monitorevent.play_pressed,
190
-                                          monitorevent.stop_pressed,
191
-                                          monitorevent.mark_in_pressed,
192
-                                          monitorevent.mark_out_pressed,
193
-                                          monitorevent.marks_clear_pressed,
194
-                                          monitorevent.to_mark_in_pressed,
195
-                                          monitorevent.to_mark_out_pressed
196
-            else:
197
-                pressed_callback_funcs = monitorevent.prev_pressed,
198
-                                          monitorevent.next_pressed,
199
-                                          monitorevent.play_pressed,
200
-                                          monitorevent.stop_pressed,
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/extraeditors.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/extraeditors.py Changed
201
 
1
@@ -34,6 +34,7 @@
2
 import appconsts
3
 import cairo
4
 import cairoarea
5
+import dialogutils
6
 from editorstate import PROJECT
7
 import guiutils
8
 import guicomponents
9
@@ -1209,12 +1210,16 @@
10
         clip_path = self.editable_properties0.clip.path
11
         accuracy_prop = ep for ep in self.editable_properties if ep.name == "accuracy"0
12
         shakiness_prop = ep for ep in self.editable_properties if ep.name == "shakiness"0
13
+        smoothing_prop = ep for ep in self.editable_properties if ep.name == "smoothing"0
14
+        zoom_prop = ep for ep in self.editable_properties if ep.name == "zoom"0
15
         
16
         args = ("session_id:" + str(session_id),
17
                 "profile_desc:" + str(profile_desc),
18
                 "clip_path:" + str(clip_path),
19
                 "shakiness:" + str(shakiness_prop.value),
20
-                "accuracy:" + str(accuracy_prop.value))
21
+                "accuracy:" + str(accuracy_prop.value),
22
+                "smoothing:" + str(smoothing_prop.value),
23
+                "zoom:" + str(zoom_prop.value))
24
 
25
         job = jobs.StablizeDataRenderJobQueueObject(session_id, self.filter, self.editable_properties, self, args)
26
         job.add_to_queue()
27
@@ -1229,8 +1234,8 @@
28
 class AnalyzeMotionTrackingFilterEditor:
29
     def __init__(self, filter, editable_properties):
30
         self.filter = filter
31
-        # We need to turn this because otherwise filter keeps attemting to 
32
-        # analyze tracking continuosly. We want analyzing to happen in the 
33
+        # We need to turn this because otherwise filter keeps attempting to 
34
+        # analyze tracking continuously. We want analyzing to happen in the 
35
         # dedicated process and only results be displayed.
36
         # ...aaand this only has effect if we have some results?
37
         self.filter.mlt_filter.set("analyze", "0")
38
@@ -1324,7 +1329,7 @@
39
         if len(data_label) == 0:
40
             data_label = self.get_default_data_label()
41
         
42
-        job = jobs.MotionTrackingDataRenderJobQueueObject(session_id, self.filter, self.editable_properties, self, args, data_label)
43
+        job = jobs.TrackingDataRenderJobQueueObject(session_id, self.filter, self.editable_properties, self, args, data_label)
44
         job.add_to_queue()
45
 
46
     def analysis_complete(self, final_label, data_file_path):
47
@@ -1345,7 +1350,7 @@
48
             self.box_gui_editor.geom_kf_edit.widget.queue_draw()
49
             self.set_buttons_state()
50
         except Exception as e :
51
-            # GUI might havenn destoyed during rendering.
52
+            # GUI might havenn destroyed during rendering.
53
             print(e)
54
 
55
     def clear_button_clicked(self, button):
56
@@ -1374,16 +1379,21 @@
57
         self.non_mlt_editors = non_mlt_editors
58
         self.non_mlt_properties = non_mlt_properties
59
 
60
-        select_label = Gtk.Label(label=_("Select Motion Tracking Data:"))
61
-        select_label.set_margin_right(4)
62
+        self.select_label = Gtk.Label(label=_("Select Motion Tracking Data:"))
63
+        self.select_label.set_margin_right(4)
64
 
65
         selected_tracking_data = ep for ep in self.non_mlt_properties if ep.name == "selected_tracking_data"0.value
66
         self.data_select_keys, self.data_select_combo = motiontracking.get_tracking_data_select_combo(_("No Tracking Data Available"), selected_tracking_data)
67
 
68
-        hbox1 = Gtk.HBox()
69
-        hbox1.pack_start(select_label, False, False, 0) 
70
-        hbox1.pack_start(self.data_select_combo, True, True, 0)
71
-        hbox1.set_margin_bottom(24)
72
+        self.delete_button = Gtk.Button(label=_("Delete"))
73
+        self.delete_button.connect("clicked", self.delete_data)
74
+        self.delete_button.set_margin_left(12)
75
+    
76
+        self.hbox1 = Gtk.HBox()
77
+        self.hbox1.pack_start(self.select_label, False, False, 0) 
78
+        self.hbox1.pack_start(self.data_select_combo, True, True, 0)
79
+        self.hbox1.pack_start(self.delete_button, False, False, 0) 
80
+        self.hbox1.set_margin_bottom(24)
81
 
82
         self.info_label = Gtk.Label("<small>No Tracking Data Applied</small>")
83
         last_applied_date_str = ep for ep in self.non_mlt_properties if ep.name == "last_applied_tracking_data"0.value
84
@@ -1391,11 +1401,12 @@
85
             self.show_last_applied_date(last_applied_date_str)
86
         self.info_label.set_use_markup(True)
87
         self.info_label.set_margin_right(4)
88
-
89
+        
90
         self.button = Gtk.Button(label=_("Apply Motion Tracking Data"))
91
         self.button.connect("clicked", self.apply_tracking)
92
 
93
         hbox2 = Gtk.HBox()
94
+        hbox2.pack_start(self.delete_button, False, False, 0)
95
         hbox2.pack_start(Gtk.Label(), True, True, 0) 
96
         hbox2.pack_start(self.info_label, False, False, 0) 
97
         hbox2.pack_start(self.button, False, False, 0)
98
@@ -1403,7 +1414,7 @@
99
         hbox2.set_margin_bottom(24)
100
         
101
         self.widget = Gtk.VBox()
102
-        self.widget.pack_start(hbox1, False, False, 0)
103
+        self.widget.pack_start(self.hbox1, False, False, 0)
104
         for row in self.non_mlt_editors:
105
             self.widget.pack_start(row, False, False, 0)
106
         self.widget.pack_start(hbox2, False, False, 0)
107
@@ -1415,14 +1426,14 @@
108
         interpretation = ep for ep in self.non_mlt_properties if ep.name == "interpretation"0.value
109
         size = ep for ep in self.non_mlt_properties if ep.name == "size"0.value
110
         clip_in = self.editable_properties0.clip.clip_in
111
-        
112
+
113
         info = utils.get_file_producer_info(self.editable_properties0.clip)
114
         source_w = int(info"width")
115
         source_h = int(info"height")
116
         if self.editable_properties0.clip.media_type == appconsts.IMAGE:
117
             graphic_img = Image.open(self.editable_properties0.clip.path)
118
             source_w, source_h = graphic_img.size
119
-            
120
+
121
         motiontracking.apply_tracking(  tracking_data_id, self.filter, self.editable_properties, 
122
                                         int(float(xoff)), int(float(yoff)), interpretation, size, clip_in,
123
                                         source_w, source_h)
124
@@ -1440,6 +1451,47 @@
125
         self.info_label.set_use_markup(True)
126
         self.info_label.queue_draw()
127
 
128
+    def delete_data(self, button):
129
+        used_data = motiontracking.get_used_motion_tracking_data()
130
+        tracking_data_id = self.data_select_keysself.data_select_combo.get_active()
131
+        
132
+        if tracking_data_id in used_data:
133
+            self.confirm_delete()
134
+        else:
135
+            self.delete_selected()
136
+
137
+    def confirm_delete(self):
138
+        title = _("Confirm Motion Tracking Data Delete")
139
+        text = Gtk.Label(label=_("Current selected motion tracking data was applied somewhere in the project.\n\nDelete anyway?"))
140
+        panel = guiutils.get_left_justified_box(text)
141
+        accept_text = _("Delete")
142
+        dialogutils.panel_ok_cancel_dialog(title, panel, accept_text, self.delete_dialog_callback)
143
+
144
+    def delete_dialog_callback(self, dialog, response_id):
145
+        dialog.destroy()
146
+        if response_id == Gtk.ResponseType.ACCEPT:
147
+            self.delete_selected()
148
+
149
+    def delete_selected(self):
150
+        tracking_data_id = self.data_select_keysself.data_select_combo.get_active()
151
+        if tracking_data_id == None:
152
+            return # no tracking data exists.
153
+
154
+        PROJECT().delete_tracking_data(tracking_data_id)
155
+
156
+        children = self.hbox1.get_children()
157
+        for child in children:
158
+            self.hbox1.remove(child)
159
+
160
+        self.data_select_keys, self.data_select_combo = motiontracking.get_tracking_data_select_combo(_("No Tracking Data Available"), -1)
161
+        self.data_select_combo.show() 
162
+
163
+        self.hbox1.pack_start(self.select_label, False, False, 0) 
164
+        self.hbox1.pack_start(self.data_select_combo, True, True, 0)
165
+        self.hbox1.pack_start(self.delete_button, False, False, 0) 
166
+        
167
+        self.widget.queue_draw() 
168
+            
169
 
170
 class FilterMaskApplyMotionTrackingEditor:
171
     def __init__(self, filter, editable_properties, non_mlt_editors, non_mlt_properties):
172
@@ -1448,16 +1500,21 @@
173
         self.non_mlt_properties = non_mlt_properties
174
         self.non_mlt_editors = non_mlt_editors
175
         
176
-        select_label = Gtk.Label(label=_("Select Motion Tracking Data:"))
177
-        select_label.set_margin_right(4)
178
+        self.select_label = Gtk.Label(label=_("Select Motion Tracking Data:"))
179
+        self.select_label.set_margin_right(4)
180
 
181
         selected_tracking_data = ep for ep in self.non_mlt_properties if ep.name == "selected_tracking_data"0.value
182
         self.data_select_keys, self.data_select_combo = motiontracking.get_tracking_data_select_combo(_("No Tracking Data Available"), selected_tracking_data)
183
 
184
-        hbox1 = Gtk.HBox()
185
-        hbox1.pack_start(select_label, False, False, 0) 
186
-        hbox1.pack_start(self.data_select_combo, True, True, 0)
187
-        hbox1.set_margin_bottom(24)
188
+        self.delete_button = Gtk.Button(label=_("Delete"))
189
+        self.delete_button.connect("clicked", self.delete_data)
190
+        self.delete_button.set_margin_left(12)
191
+        
192
+        self.hbox1 = Gtk.HBox()
193
+        self.hbox1.pack_start(self.select_label, False, False, 0) 
194
+        self.hbox1.pack_start(self.data_select_combo, True, True, 0)
195
+        self.hbox1.pack_start(self.delete_button, False, False, 0) 
196
+        self.hbox1.set_margin_bottom(24)
197
 
198
         self.info_label = Gtk.Label("<small>No Tracking Data Applied</small>")
199
         last_applied_date_str = ep for ep in self.non_mlt_properties if ep.name == "last_applied_tracking_data"0.value
200
@@ -1469,18 +1526,18 @@
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/glassbuttons.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/glassbuttons.py Changed
157
 
1
@@ -25,6 +25,7 @@
2
 import editorpersistance
3
 import gui
4
 import guiutils
5
+import respaths
6
 
7
 BUTTONS_GRAD_STOPS =    (1, 1, 1, 1, 0.2),
8
                         (0.8, 1, 1, 1, 0),
9
@@ -277,6 +278,7 @@
10
             x += self.button_width
11
 
12
     def show_prelight_icons(self):
13
+        self.prelight_icons = 
14
         for icon in self.icons:
15
             surface_prelight = cairo.ImageSurface(cairo.FORMAT_ARGB32, icon.get_width(), icon.get_height())
16
             cr = cairo.Context(surface_prelight)
17
@@ -339,7 +341,7 @@
18
                 self.icons = prev_icon, next_icon, play_pause_icon,
19
                           mark_in_icon, mark_out_icon,
20
                           marks_clear_icon, to_mark_in_icon, to_mark_out_icon
21
-                self.image_x =  5*size_adj, 7*size_adj, 5*size_adj, 3*size_adj, 11*size_adj, 2*size_adj, 7*size_adj, 6*size_adj
22
+                self.image_x =  5*size_adj, 7*size_adj, 11*size_adj, 3*size_adj, 11*size_adj, 2*size_adj, 7*size_adj, 0*size_adj
23
         else:
24
             #  go to start end
25
             if (editorpersistance.prefs.timeline_start_end == True):
26
@@ -423,7 +425,110 @@
27
         self.button_x = mid_x - (buttons_width // 2)
28
         self._draw_buttons(cr, w, h)
29
 
30
+class PlayerButtonsCompact(AbstractGlassButtons):
31
+
32
+    def __init__(self):
33
+        # Aug-2019 - SvdB - BB - Multiple changes - size_ind, size_adj, get_cairo_image
34
+        size_ind = 0
35
+        AbstractGlassButtons.__init__(self, MB_BUTTON_WIDTHsize_ind, MB_BUTTON_HEIGHTsize_ind, MB_BUTTON_Y, MB_BUTTONS_WIDTHsize_ind, MB_BUTTONS_HEIGHTsize_ind - 2)
36
+
37
+        # Force no decorations for player buttons, this cannot be made to work.
38
+        self.no_decorations = True 
39
+
40
+        self.play_icon = guiutils.get_cairo_image("play_2_s")
41
+        self.stop_icon = guiutils.get_cairo_image("stop_s")
42
+        self.next_icon = guiutils.get_cairo_image("next_frame_s")
43
+        self.prev_icon = guiutils.get_cairo_image("prev_frame_s")
44
+
45
+        self.icons = self.prev_icon, self.play_icon, self.next_icon
46
+        self.image_x = 0, 0, -1
47
+
48
+
49
+        for i in range(0, len(self.icons)):
50
+            self.image_y.append(MB_BUTTON_IMAGE_Y - 6)
51
+        
52
+        self.pressed_callback_funcs = None # set using set_callbacks()
53
+
54
+        self.set_sensitive(True)
55
+
56
+        focus_groupsDEFAULT_FOCUS_GROUP.append(self.widget)
57
+
58
+        self.show_prelight_icons()
59
+        self.stopped_prelight_icons = self.prelight_icons 
60
+        self.icons = self.prev_icon, self.stop_icon, self.next_icon
61
+        self.show_prelight_icons()
62
+        self.playing_prelight_icons = self.prelight_icons 
63
+        
64
+        self.icons = self.prev_icon, self.play_icon, self.next_icon
65
+        self.prelight_icons = self.stopped_prelight_icons 
66
+        
67
+    def set_normal_sensitive_pattern(self):
68
+        self.set_sensitive(True)
69
+        self.widget.queue_draw()
70
+
71
+    def show_playing_state(self, is_playing):
72
+        if is_playing == True:
73
+            self.icons = self.prev_icon, self.stop_icon, self.next_icon
74
+            self.prelight_icons = self.playing_prelight_icons 
75
+        else:
76
+            self.icons = self.prev_icon, self.play_icon, self.next_icon
77
+            self.prelight_icons = self.stopped_prelight_icons
78
+                
79
+        self.widget.queue_draw()
80
+        
81
+    # ------------------------------------------------------------- mouse events
82
+    def _press_event(self, event):
83
+        """
84
+        Mouse button callback
85
+        """
86
+        self.pressed_button = self._get_hit_code(event.x, event.y)
87
+        if self.pressed_button >= 0 and self.pressed_button < len(self.icons):
88
+            callback_func = self.pressed_callback_funcsself.pressed_button # index is set to match at editorwindow.py where callback func list is created
89
+            callback_func()
90
+        self.widget.queue_draw()
91
+
92
+    def _motion_notify_event(self, x, y, state):
93
+        """
94
+        Mouse move callback
95
+        """
96
+        button_under = self._get_hit_code(x, y)
97
+        if self.pressed_button != button_under: # pressed button is released
98
+            self.pressed_button = NO_HIT
99
+
100
+        if len(self.prelight_icons) > 0:
101
+            self.prelight_index = button_under
102
+            
103
+        self.widget.queue_draw()
104
+
105
+    def _release_event(self, event):
106
+        """
107
+        Mouse release callback
108
+        """
109
+        self.pressed_button = -1
110
+        self.widget.queue_draw()
111
+
112
+    def _leave_notify_event(self, event):
113
+        self.prelight_index = -1
114
+        self.widget.queue_draw()
115
+
116
+    def _enter_notify_event(self, event):
117
+        self.prelight_index = -1
118
+        
119
+    def set_callbacks(self, pressed_callback_funcs):
120
+        self.pressed_callback_funcs = pressed_callback_funcs
121
+
122
+    # ---------------------------------------------------------------- painting
123
+    def _draw(self, event, cr, allocation):
124
+        x, y, w, h = allocation
125
+        self.allocation = allocation
126
 
127
+        mid_x = w // 2
128
+        buttons_width = self.button_width * len(self.icons)
129
+        # Jul-2016 - SvdB - No changes made here, but because of the calculation of button_x the row of buttons is slightly moved right if play/pause
130
+        # is enabled. This could be solved by setting self.button_x = 1, if wished.
131
+        self.button_x = mid_x - (buttons_width // 2)
132
+        self._draw_buttons(cr, w, h)
133
+        
134
 class GmicButtons(AbstractGlassButtons):
135
 
136
     def __init__(self):
137
@@ -603,6 +708,19 @@
138
         pass
139
 
140
 
141
+class MarkButtons(GlassButtonsGroup):
142
+    
143
+    def __init__(self, callbacks):
144
+            
145
+        GlassButtonsGroup.__init__(self, 16, 18, 0, 0, 2)
146
+            
147
+        self.add_button(cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "mark_in_xs.png"), callbacks0)
148
+        self.add_button(cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "mark_out_xs.png"), callbacks1)
149
+        self.add_button(cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "mark_clear_xs.png"), callbacks2)
150
+        self.no_decorations = True 
151
+        
152
+        self.show_prelight_icons()
153
+
154
 
155
 class TooltipRunner:
156
 
157
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/gtkbuilder.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/gtkbuilder.py Changed
29
 
1
@@ -74,6 +74,7 @@
2
     b.set_current_folder = lambda fp : _set_current_folder(b, fp)
3
     b.get_current_folder = lambda : _get_current_folder(b)
4
     b.set_current_folder_uri = lambda : _set_current_folder_uri(b)
5
+    b.set_filename = lambda fn : _set_filename(b, fn)
6
     b.get_filenames = lambda : _get_filenames(b)
7
     b.get_filename = lambda : _get_filename(b)
8
     b.add_filter = lambda ff :_add_filter(b, ff)
9
@@ -134,7 +135,6 @@
10
     
11
     if b.priv_selection_changed_listener != None:
12
         b.priv_selection_changed_listener(b, b.priv_selection_changed_data)
13
-    
14
 
15
 def _set_file_action(b, action):
16
     b.priv_action = action
17
@@ -167,6 +167,11 @@
18
     except:
19
         return None
20
 
21
+def _set_filename(b, fn):
22
+    b.priv_filenames = 
23
+    b.priv_filenames.append(fn)
24
+    b.set_label(_filename(b.priv_filenames0))
25
+
26
 def _get_current_folder(b):
27
     return b.priv_current_folder
28
     
29
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/gui.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/gui.py Changed
33
 
1
@@ -182,6 +182,31 @@
2
 
3
     return True
4
 
5
+def apply_widget_css(widget, widget_css_name, css_file):
6
+    css_path = respaths.ROOT_PATH + "/res/css3/" + css_file
7
+
8
+    provider = Gtk.CssProvider()
9
+    provider.load_from_path(css_path)
10
+    
11
+    widget.set_name(widget_css_name)
12
+    widget.get_style_context().add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
13
+
14
+def apply_widget_css_class(widget, widget_css_class_name, css_file):
15
+    css_path = respaths.ROOT_PATH + "/res/css3/" + css_file
16
+    provider = Gtk.CssProvider()
17
+    provider.load_from_path(css_path)
18
+    
19
+    widget.get_style_context().add_class(widget_css_class_name)
20
+    widget.get_style_context().add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
21
+
22
+def apply_widget_css_class_style_from_string(widget, css_str):#, widget_css_class_name, css_file):
23
+    css_data = css_str.encode("utf-8")
24
+    provider = Gtk.CssProvider()
25
+    provider.load_from_data(css_data)
26
+    
27
+    #widget.get_style_context().add_class(widget_css_class_name)
28
+    widget.get_style_context().add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
29
+    
30
 def get_default_filter_icon():
31
     return GdkPixbuf.Pixbuf.new_from_file(respaths.IMAGE_PATH + "filter.png")
32
     
33
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/guicomponents.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/guicomponents.py Changed
201
 
1
@@ -66,6 +66,7 @@
2
 CLIP_EDITOR_LEFT_WIDTH = 200
3
 
4
 TC_COLOR = (0.7, 0.7, 0.7)
5
+TC_ZEROS_COLOR = (0.4, 0.4, 0.4)
6
 
7
 BIG_TC_GRAD_STOPS =    (1, 1, 1, 1, 0.2),
8
                         (0.8, 1, 1, 1, 0),
9
@@ -526,44 +527,6 @@
10
                 self.double_click_counter = 0
11
                 self.double_click_cb()
12
 
13
-class MediaListView(ImageTextTextListView):
14
-    """
15
-    GUI component displaying list of media files.
16
-    """
17
-
18
-    def __init__(self, row_activated_cb, file_name_edited_cb):
19
-        ImageTextTextListView.__init__(self)
20
-
21
-        # Connect double-click listener and allow multiple selection
22
-        self.treeview.connect("row-activated",
23
-                              row_activated_cb)
24
-
25
-        tree_sel = self.treeview.get_selection()
26
-        tree_sel.set_mode(Gtk.SelectionMode.MULTIPLE)
27
-        self.text_rend_1.set_property("editable", True)
28
-        self.text_rend_1.set_property("font-desc", Pango.FontDescription("sans bold 9"))
29
-        self.text_rend_1.connect("edited",
30
-                                 file_name_edited_cb,
31
-                                 (self.storemodel, 1))
32
-
33
-        self.text_rend_2.set_property("font-desc", Pango.FontDescription("sans 8"))
34
-        self.text_rend_2.set_property("yalign", 0.5)
35
-
36
-    def fill_data_model(self):
37
-        """
38
-        Creates displayed data.
39
-        Displays thumbnail icon, file name and length
40
-        """
41
-        self.storemodel.clear()
42
-        for file_id in current_bin().file_ids:
43
-            media_file = PROJECT().media_filesfile_id
44
-            row_data = media_file.icon,
45
-                        media_file.name,
46
-                        utils.clip_length_string(media_file.length)
47
-            self.storemodel.append(row_data)
48
-            self.scroll.queue_draw()
49
-
50
-
51
 class FilterListView(ImageTextImageListView):
52
     """
53
     GUI component displaying list of available filters.
54
@@ -1236,7 +1199,8 @@
55
                     self.selected_objects.append(media_object)
56
 
57
         elif event.button == 3:
58
-            self.clear_selection()
59
+            if self.media_object_selected_test(media_object) == False:
60
+                self.clear_selection()
61
             self.media_file_popup_cb(media_object.widget,
62
                                      media_object.media_file,
63
                                      event)
64
@@ -1406,8 +1370,8 @@
65
             if ((editorstate.media_view_filter == appconsts.SHOW_IMAGE_SEQUENCES)
66
                 and (media_file.type != appconsts.IMAGE_SEQUENCE)):
67
                 continue
68
-            if ((editorstate.media_view_filter == appconsts.SHOW_PATTERN_PRODUCERS)
69
-                and (media_file.type != appconsts.PATTERN_PRODUCER)):
70
+            if ((editorstate.media_view_filter == appconsts.SHOW_CONTAINERS)
71
+                and (media_file.container_data == None)):
72
                 continue
73
             if ((editorstate.media_view_filter == appconsts.SHOW_UNUSED_FILES)
74
                 and (media_file not in unused_list)):
75
@@ -1698,12 +1662,13 @@
76
     if guiutils.double_icon_size():
77
        size_adj = 2
78
     surface = guiutils.get_cairo_image("program_view_2")
79
-    menu_launch = PressLaunchPopover(callback, surface, w=24*size_adj, h=20*size_adj)
80
+    menu_launch = PressLaunchPopover(callback, surface, w=24*size_adj, h=16*size_adj)
81
     if guiutils.double_icon_size():
82
         menu_launch.surface_y = 8*size_adj
83
     else:
84
         menu_launch.surface_y = 3
85
-        
86
+    
87
+    menu_launch.widget.set_margin_top(2)
88
     return menu_launch
89
 
90
 def get_trim_view_select_launcher(callback):
91
@@ -1714,12 +1679,13 @@
92
     if guiutils.double_icon_size():
93
        size_adj = 2
94
     surface = guiutils.get_cairo_image("trim_view")
95
-    menu_launch = PressLaunchPopover(callback, surface, w=24*size_adj, h=20*size_adj)
96
+    menu_launch = PressLaunchPopover(callback, surface, w=24*size_adj, h=16*size_adj)
97
     if guiutils.double_icon_size():
98
         menu_launch.surface_y = 8*size_adj
99
     else:
100
         menu_launch.surface_y = 3
101
-        
102
+
103
+    menu_launch.widget.set_margin_top(2)
104
     return menu_launch
105
     
106
 def get_compositor_track_select_combo(source_track, target_track, callback):
107
@@ -1932,9 +1898,6 @@
108
         self.TEXT_X = 18
109
         self.TEXT_Y = 1
110
 
111
-        global TC_COLOR
112
-        TC_COLOR = (0.55, 0.55, 0.55)
113
-
114
         self.widget.connect("button-press-event", self._button_press)
115
         self.widget.set_margin_top(1)
116
 
117
@@ -1971,6 +1934,23 @@
118
 
119
         PangoCairo.update_layout(cr, layout)
120
         PangoCairo.show_layout(cr, layout)
121
+        
122
+        try:
123
+            frame = PLAYER().tracktor_producer.frame()
124
+            frame_str = utils.get_tc_zeros_overlay_fine_grained(frame)
125
+        except:
126
+            print("execpt")
127
+            frame_str = "00:00:00:00"
128
+            
129
+        layout = PangoCairo.create_layout(cr)
130
+        layout.set_text(frame_str, -1)
131
+        layout.set_font_description(self.font_desc)
132
+
133
+        cr.set_source_rgb(*TC_ZEROS_COLOR)
134
+        cr.move_to(self.TEXT_X, self.TEXT_Y)
135
+        
136
+        PangoCairo.update_layout(cr, layout)
137
+        PangoCairo.show_layout(cr, layout)
138
                 
139
     def _round_rect_path(self, cr):
140
         x, y, width, height, aspect, corner_radius, radius, degrees = self._draw_consts
141
@@ -2132,7 +2112,7 @@
142
         self.monitor_source = Gtk.Label()
143
         self.monitor_source.modify_font(Pango.FontDescription(font_desc))
144
         self.monitor_source.set_ellipsize(Pango.EllipsizeMode.END)
145
-        self.monitor_source.set_sensitive(False)
146
+        #self.monitor_source.set_sensitive(False)
147
         
148
         self.monitor_tc = Gtk.Label()
149
         self.monitor_tc.modify_font(Pango.FontDescription(font_desc))
150
@@ -2142,25 +2122,17 @@
151
         self.widget = Gtk.HBox()
152
         self.widget.pack_start(self.marks_tc_display.widget, False, False, 0)
153
 
154
-            
155
     def set_source_name(self, source_name):
156
         self.monitor_source.set_text(source_name)
157
         
158
     def set_source_tc(self, tc_str):
159
         self.monitor_tc.set_text(tc_str)
160
     
161
-    def set_range_info(self, in_str, out_str, len_str):
162
-        self.marks_tc_display.in_str = in_str
163
-        self.marks_tc_display.out_str = out_str
164
-        self.marks_tc_display.len_str = len_str
165
-        
166
+    def set_range_info(self, mark_in, mark_out):
167
+        self.marks_tc_display.set_marks_range_info(mark_in, mark_out)
168
         self.marks_tc_display.widget.queue_draw()
169
-        #if editorstate.screen_size_small_width() == False:
170
-        #    self.in_value.set_text(in_str)
171
-        #    self.out_value.set_text(out_str)
172
-        #self.marks_length_value.set_text(len_str)
173
-    
174
-    
175
+
176
+
177
 
178
 class MonitorInfoDisplay:
179
 
180
@@ -2168,14 +2140,18 @@
181
         self.widget = cairoarea.CairoDrawableArea2( widget_width,
182
                                                     18,
183
                                                     self._draw)
184
-        self.font_desc = Pango.FontDescription("Bitstream Vera Sans Mono Condensed 8")
185
+        self.font_desc = Pango.FontDescription("sans bold 9")
186
         self.mark_in_img = guiutils.get_cairo_image("mark_in_tc", force=False) 
187
         self.mark_out_img = guiutils.get_cairo_image("mark_out_tc", force=False)
188
         self.marks_length_img = guiutils.get_cairo_image("marks_length_tc", force=False)
189
 
190
-        self.in_str = "--:--:--:--"
191
-        self.out_str = "--:--:--:--"
192
-        self.len_str = "--:--:--:--"
193
+        self.in_str = ""
194
+        self.out_str = ""
195
+        self.len_str = ""
196
+
197
+        self.in_zeros_overlay = ""
198
+        self.out_zeros_overlay = ""
199
+        self.len_zeros_overlay = ""
200
         
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/guipopover.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/guipopover.py Changed
201
 
1
@@ -38,6 +38,9 @@
2
 _markers_menu = None
3
 _tline_properties_popover = None
4
 _tline_properties_menu = None
5
+_sync_popover = None
6
+_sync_menu = None
7
+_autosync_split_submenu = None
8
 _all_tracks_popover = None
9
 _all_tracks_menu = None
10
 _compositing_mode_popover = None
11
@@ -66,6 +69,8 @@
12
 _file_filter_menu = None
13
 _media_file_popover = None
14
 _media_file_menu = None
15
+_media_file_multi_popover = None
16
+_media_file_menu_multi = None
17
 _jobs_popover = None
18
 _jobs_menu = None
19
 _effects_popover = None
20
@@ -108,9 +113,10 @@
21
 _icon_section = None
22
 _mf_render_section = None
23
 _mf_proxy_section = None
24
+_mf_stabilize_section = None
25
 
26
 
27
-# -------------------------------------------------- menuitems builder fuctions
28
+# -------------------------------------------------- menuitems builder functions
29
 def add_menu_action(menu, label, item_id, data, callback, active=True, app=None):
30
     if active == True:
31
         menu.append(label, "app." + item_id) 
32
@@ -238,6 +244,13 @@
33
 
34
     _tline_properties_menu = menu_clear_or_create(_tline_properties_menu)
35
 
36
+    wide_multitrim_is_on = editorpersistance.prefs.wide_multitrim_slip
37
+    disable_drag_when_selected_is_on = editorpersistance.prefs.disable_drag_when_selected
38
+    edit_prefs_section = Gio.Menu.new()
39
+    add_menu_action_check(edit_prefs_section, _("Disable Clip Ends Drag When Selected"), "midbar.tlineproperties.disabledrag", disable_drag_when_selected_is_on, "disabledrag", callback)
40
+    add_menu_action_check(edit_prefs_section, _("Wide Multitrim Slip Target Area"), "midbar.tlineproperties.wideslip", wide_multitrim_is_on, "wideslip", callback)
41
+    _tline_properties_menu.append_section(None, edit_prefs_section)
42
+
43
     display_section = Gio.Menu.new()
44
     add_menu_action_check(display_section, _("Display Clip Media Thumbnails"), "midbar.tlineproperties.thumb", editorstate.display_clip_media_thumbnails, "thumbs", callback)
45
     add_menu_action_check(display_section, _("Display Audio Levels"), "midbar.tlineproperties.all", editorstate.display_all_audio_levels, "all", callback)
46
@@ -258,13 +271,54 @@
47
     _tline_properties_menu.append_section(None, snapping_section)
48
 
49
     scrubbing_section = Gio.Menu.new()
50
-    add_menu_action_check(scrubbing_section, _("Audio scrubbing"), "midbar.tlineproperties.scrubbing", editorpersistance.prefs.audio_scrubbing, "scrubbing", callback)
51
+    add_menu_action_check(scrubbing_section, _("Audio Scrubbing"), "midbar.tlineproperties.scrubbing", editorpersistance.prefs.audio_scrubbing, "scrubbing", callback)
52
     _tline_properties_menu.append_section(None, scrubbing_section)
53
 
54
     _tline_properties_popover = Gtk.Popover.new_from_model(widget, _tline_properties_menu)
55
     launcher.connect_launched_menu(_tline_properties_popover)
56
     _tline_properties_popover.show()
57
 
58
+def sync_menu_show(launcher, widget, properties_set_callback, split_mirror_callback, sync_callback):
59
+    global _sync_popover, _sync_menu, _autosync_split_submenu
60
+
61
+    if _sync_menu == None:
62
+        _sync_menu = menu_clear_or_create(_sync_menu)
63
+            
64
+        properties_section = Gio.Menu.new()
65
+
66
+        
67
+        add_menu_action_check(properties_section, _("Show Synch Relations"), "midbar.sync.showsync", editorpersistance.prefs.show_sync, "showsync", properties_set_callback)
68
+        _sync_menu.append_section(None, properties_section)
69
+
70
+        mirror_section = Gio.Menu.new()
71
+        _autosync_split_submenu = menu_clear_or_create(_autosync_split_submenu)
72
+        items_data =   ( _("Off"), str(appconsts.AUDIO_AUTO_SPLIT_OFF)), 
73
+                        (_("On All Video Tracks"), str(appconsts.AUDIO_AUTO_SPLIT_ALL_TACKS)),
74
+                        ( _("On Tracks V1 and V2"), str(appconsts.AUDIO_AUTO_SPLIT_V1_V2)), 
75
+                        ( _("On Track V1"), str(appconsts.AUDIO_AUTO_SPLIT_V1)) 
76
+        active_index = editorpersistance.prefs.sync_autosplit
77
+        add_menu_action_all_items_radio(_autosync_split_submenu, items_data,  "midbar.sync.autosplit", active_index, sync_callback)
78
+        mirror_section.append_submenu(_("Auto Sync Split Video Clips on Add"), _autosync_split_submenu)
79
+        items_data =(_("Audio Split To Mirrored Track"), "splitmirror"), (_("Audio Split To V1 Always"), "splitv1")
80
+        if  editorpersistance.prefs.sync_mirror == True:
81
+            active_index = 0
82
+        else:
83
+            active_index = 1
84
+        add_menu_action_all_items_radio(mirror_section, items_data, "midbar.sync.mirror", active_index, split_mirror_callback)
85
+        _sync_menu.append_section(None, mirror_section)
86
+    else:
87
+        _autosync_split_submenu = menu_clear_or_create(_autosync_split_submenu)
88
+        items_data =   ( _("Off"), str(appconsts.AUDIO_AUTO_SPLIT_OFF)), 
89
+                        (_("On All Video Tracks"), str(appconsts.AUDIO_AUTO_SPLIT_ALL_TACKS)),
90
+                        ( _("On Tracks V1 and V2"), str(appconsts.AUDIO_AUTO_SPLIT_V1_V2)), 
91
+                        ( _("On Track V1"), str(appconsts.AUDIO_AUTO_SPLIT_V1)) 
92
+        active_index = editorpersistance.prefs.sync_autosplit
93
+        add_menu_action_all_items_radio(_autosync_split_submenu, items_data,  "midbar.sync.autosplit", active_index, sync_callback)
94
+    
95
+    _sync_popover = Gtk.Popover.new_from_model(widget, _sync_menu)
96
+    launcher.connect_launched_menu(_sync_popover)
97
+    _sync_popover.show()
98
+    
99
 def all_tracks_menu_show(launcher, widget, callback):
100
     global _all_tracks_popover, _all_tracks_menu
101
 
102
@@ -357,12 +411,13 @@
103
 
104
     main_section = Gio.Menu.new()
105
     add_menu_action(main_section, _("Add New Sequence"), "sequencepanel.add", "add sequence", callback)
106
-    add_menu_action(main_section, _("Edit Selected Sequence"), "sequencepanel.edit", "edit sequence", callback)
107
-    add_menu_action(main_section, _("Delete Selected Sequence"), "sequencepanel.delete", "delete sequence", callback)
108
+    add_menu_action(main_section, _("Edit"), "sequencepanel.edit", "edit sequence", callback)
109
+    add_menu_action(main_section, _("Delete"), "sequencepanel.delete", "delete sequence", callback)
110
     _sequence_panel_menu.append_section(None, main_section)
111
 
112
     container_section = Gio.Menu.new()
113
-    add_menu_action(container_section, _("Create Container Clip from Selected Sequence"), "sequencepanel.create", "compound clip", callback)
114
+    add_menu_action(container_section, _("Create Container Clip"), "sequencepanel.create", "container clip", callback)
115
+    add_menu_action(container_section, _("Create Sequence Link Container Clip"), "sequencepanel.createseqlink", "sequence link container clip", callback)
116
     _sequence_panel_menu.append_section(None, container_section)
117
 
118
     rect = create_rect(x, y)
119
@@ -480,6 +535,10 @@
120
     global _media_panel_hamburger_popover, _media_panel_hamburger_menu
121
 
122
     _media_panel_hamburger_menu = menu_clear_or_create(_media_panel_hamburger_menu)
123
+
124
+    delete_section = Gio.Menu.new()
125
+    add_menu_action(delete_section, _("Delete"), "mediapanel.delete", "delete", callback)
126
+    _media_panel_hamburger_menu.append_section(None, delete_section)
127
     
128
     proxy_section = Gio.Menu.new()
129
     add_menu_action(proxy_section, _("Render Proxy Files For Selected Media"), "mediapanel.proxyrender", "render proxies", callback)
130
@@ -548,8 +607,8 @@
131
 
132
         items_data =( _("All Files"), "0"), (_("Video Files"), "1"), \
133
                     ( _("Audio Files"), "2"), (_("Graphics Files"), "3"), ( _("Image Sequences"), "4"), \
134
-                    (_("Pattern Producers"), "5"), (_("Unused Files"), "6")
135
-                    
136
+                    (_("Containers"), "5"), (_("Unused Files"), "6")
137
+
138
         active_index = editorstate.media_view_filter
139
         radio_section = Gio.Menu.new()
140
         add_menu_action_all_items_radio(radio_section, items_data, "mediapanel.fileview", active_index, callback)
141
@@ -574,7 +633,7 @@
142
 
143
 def media_file_popover_show(media_file, widget, x, y, callback, callback_rating):
144
     global _media_file_popover, _media_file_menu, _rated_section, _rated_submenu, _monitor_section, \
145
-    _mf_properties_section, _icon_section, _mf_render_section, _mf_proxy_section
146
+    _mf_properties_section, _icon_section, _mf_render_section, _mf_stabilize_section, _mf_proxy_section
147
 
148
     if _media_file_menu == None:
149
         _media_file_menu = menu_clear_or_create(_media_file_menu)
150
@@ -610,6 +669,10 @@
151
         _fill_mf_render_section(_mf_render_section, media_file, callback)
152
         _media_file_menu.append_section(None, _mf_render_section)
153
 
154
+        _mf_stabilize_section  = Gio.Menu.new()
155
+        _fill_mf_stabilize_section(_mf_stabilize_section, media_file, callback)
156
+        _media_file_menu.append_section(None, _mf_stabilize_section)
157
+
158
         _mf_proxy_section = Gio.Menu.new()
159
         _fill_mf_proxy_section(_mf_proxy_section, media_file, callback)
160
         _media_file_menu.append_section(None, _mf_proxy_section)
161
@@ -633,12 +696,38 @@
162
         menu_clear_or_create(_mf_render_section)
163
         _fill_mf_render_section(_mf_render_section, media_file, callback)
164
 
165
+        menu_clear_or_create(_mf_stabilize_section)
166
+        _fill_mf_stabilize_section(_mf_stabilize_section, media_file, callback)
167
+        
168
         menu_clear_or_create(_mf_proxy_section)
169
         _fill_mf_proxy_section(_mf_proxy_section, media_file, callback)
170
         
171
     rect = create_rect(x, y)
172
     _media_file_popover = new_mouse_popover(widget, _media_file_menu, rect)
173
 
174
+def media_file_popover_multi_show(widget, x, y, callback):
175
+    global _media_file_multi_popover, _media_file_menu_multi
176
+
177
+    if _media_file_menu_multi == None:
178
+        _media_file_menu_multi = menu_clear_or_create(_media_file_menu_multi)
179
+
180
+        file_action_section = Gio.Menu.new()
181
+        add_menu_action(file_action_section, _("Delete"), "mediapanel.mediafilemulti.delete", "Delete", callback)
182
+        _media_file_menu_multi.append_section(None, file_action_section)
183
+
184
+        media_item_action_section = Gio.Menu.new()
185
+        add_menu_action(media_item_action_section, _("Move to Clicked Position..."), "mediapanel.mediafilemulti.movetoclicked", "Move to Clicked Position", callback)
186
+        add_menu_action(media_item_action_section, _("Render Proxy File"), "mediapanel.mediafilemulti.proxy", "Render Proxy", callback)
187
+        _media_file_menu_multi.append_section(None, media_item_action_section)
188
+        
189
+        edit_action_section = Gio.Menu.new()
190
+        add_menu_action(edit_action_section, _("Append to Timeline"), "mediapanel.mediafilemulti.append", "Append to Timeline", callback)
191
+        _media_file_menu_multi.append_section(None, edit_action_section)
192
+            
193
+    rect = create_rect(x, y)
194
+    _media_file_multi_popover = new_mouse_popover(widget, _media_file_menu_multi, rect)
195
+
196
+
197
 def _fill_monitor_section(_monitor_section, media_file, callback):
198
     if hasattr(media_file, "container_data"): 
199
         if media_file.container_data == None:
200
@@ -681,6 +770,13 @@
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/guipopoverclip.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/guipopoverclip.py Changed
201
 
1
@@ -47,6 +47,7 @@
2
 _edit_bottom_section = None
3
 _compositor_section = None
4
 _title_section = None
5
+_generator_sub_menu = None
6
 _generator_section = None
7
 
8
 _audio_clip_popover = None
9
@@ -62,6 +63,7 @@
10
 _multi_clip_popover = None
11
 _multi_clip_menu = None
12
 _multi_audio_section = None
13
+_multi_sync_section = None
14
 
15
 _compositor_popover = None
16
 _compositor_menu = None
17
@@ -81,7 +83,7 @@
18
 _kf_select_menu = None
19
  
20
  
21
-# -------------------------------------------------- menuitems builder fuctions
22
+# -------------------------------------------------- menuitems builder functions
23
 def add_menu_action(menu, label, item_id, data, callback, active=True, app=None):
24
     return guipopover.add_menu_action(menu, label, item_id, data, callback, active, app)
25
 
26
@@ -108,7 +110,7 @@
27
 
28
     global _clip_popover, _clip_menu, _audio_submenu, _markers_submenu, \
29
     _markers_submenu_static_items, _reload_section, _edit_actions_menu, \
30
-    _tools_submenu, _title_section, _compositor_section, _generator_section
31
+    _tools_submenu, _title_section, _compositor_section, _generator_section, _generator_sub_menu
32
 
33
     if _clip_menu == None:
34
         _clip_menu = guipopover.menu_clear_or_create(_clip_menu)
35
@@ -124,6 +126,8 @@
36
         _clip_menu.append_section(None, audio_section)
37
 
38
         _generator_section = Gio.Menu.new()
39
+        _generator_sub_menu = Gio.Menu.new()
40
+        _fill_generator_render_section(_generator_sub_menu, clip, callback)
41
         _fill_generator_section(_generator_section, clip, callback)
42
         _clip_menu.append_section(None, _generator_section)
43
         
44
@@ -171,8 +175,8 @@
45
         clone_sub_menu = Gio.Menu.new()
46
         _fill_clone_filters_menu(clone_sub_menu, callback, False, False)
47
         filters_copy_section.append_submenu(_("Clone Filter"), clone_sub_menu)
48
-        add_menu_action(filters_copy_section, _("Copy Filters"), "clipmenu.openinmonitor.copyfilters",  ("copy_filters", None), callback)
49
-        add_menu_action(filters_copy_section, _("Paste Filters"), "clipmenu.openinmonitor.pastefilters",  ("paste_filters", None), callback)
50
+        add_menu_action(filters_copy_section, _("Copy Filters"), "clipmenu.copyfilters",  ("copy_filters", None), callback)
51
+        add_menu_action(filters_copy_section, _("Paste Filters"), "clipmenu.pastefilters",  ("paste_filters", None), callback)
52
         _clip_menu.append_section(None, filters_copy_section)
53
 
54
         _title_section = Gio.Menu.new()
55
@@ -206,9 +210,12 @@
56
         guipopover.menu_clear_or_create(_title_section)
57
         _fill_title_section(_title_section, clip, callback)
58
 
59
+        guipopover.menu_clear_or_create(_generator_sub_menu)
60
+        _fill_generator_render_section(_generator_sub_menu, clip, callback)
61
+
62
         guipopover.menu_clear_or_create(_generator_section)
63
         _fill_generator_section(_generator_section, clip, callback)
64
-
65
+        
66
     rect = guipopover.create_rect(x, y)
67
     _clip_popover = guipopover.new_mouse_popover(widget, _clip_menu, rect, Gtk.PositionType.TOP)
68
 
69
@@ -267,6 +274,7 @@
70
         _fill_clone_filters_menu(clone_sub_menu, callback, False, True)
71
         filters_section.append_submenu(_("Clone Filter"), clone_sub_menu)
72
         add_menu_action(filters_section, _("Clear Filters"), "audioclipmenu.clearfilters",  ("clear_filters", None), callback)
73
+        add_menu_action(filters_section, _("Paste Filters"), "audioclipmenu.pastefilters",  ("paste_filters", None), callback)
74
         _audio_clip_menu.append_section(None, filters_section)
75
 
76
         edit_bottom_section = Gio.Menu.new()
77
@@ -310,7 +318,7 @@
78
         transition_popover_menu_show(widget, clip, track, x, y, callback)
79
         return
80
 
81
-    global _multi_clip_popover, _multi_clip_menu, _multi_audio_section
82
+    global _multi_clip_popover, _multi_clip_menu, _multi_audio_section, _multi_sync_section
83
 
84
     if _multi_clip_menu == None:
85
         _multi_clip_menu = guipopover.menu_clear_or_create(_multi_clip_menu)
86
@@ -319,6 +327,10 @@
87
         _fill_multi_audio_section(_multi_audio_section, clip, track, callback)
88
         _multi_clip_menu.append_section(None, _multi_audio_section)
89
 
90
+        _multi_sync_section = Gio.Menu.new()
91
+        _fill_multi_sync_section(_multi_sync_section, clip, track, callback)
92
+        _multi_clip_menu.append_section(None, _multi_sync_section)
93
+            
94
         container_section = Gio.Menu.new()
95
         add_menu_action(container_section, _("Create Container Clip From Selected Clips"), "multiclipmenu.createmulticompound",  ("create_multi_compound", None), callback)
96
         _multi_clip_menu.append_section(None, container_section)
97
@@ -331,17 +343,25 @@
98
         _fill_clone_filters_menu(clone_sub_menu, callback, True, False)
99
         filters_section.append_submenu(_("Clone Filter"), clone_sub_menu)
100
         add_menu_action(filters_section, _("Clear Filters"), "multiclipmenu.clearfilters",  ("clear_filters", None), callback)
101
+        add_menu_action(filters_section, _("Paste Filters"), "multiclipmenu.pastefilters",  ("paste_filters", None), callback)
102
         _multi_clip_menu.append_section(None, filters_section)
103
 
104
         delete_section = Gio.Menu.new()
105
         add_menu_action(delete_section, _("Delete"), "multiclipmenu.delete",  ("delete", None), callback)
106
         add_menu_action(delete_section, _("Lift"), "multiclipmenu.lift",  ("lift", None), callback)
107
+        add_menu_action(delete_section, _("Ripple Delete Selection Range"), "multiclipmenu.ripplerange",  ("ripplerangeselection", None), callback)
108
         _multi_clip_menu.append_section(None, delete_section)
109
 
110
+        mark_section = Gio.Menu.new()
111
+        add_menu_action(mark_section, _("Mark Selection Range"), "multiclipmenu.markselectionrange",  ("mark_selection_range", None), callback)
112
+        _multi_clip_menu.append_section(None, mark_section)
113
+    
114
     else: # Menu items with possible state changes need to recreated.
115
         guipopover.menu_clear_or_create(_multi_audio_section)
116
         _fill_multi_audio_section(_multi_audio_section, clip, track, callback)
117
-
118
+        guipopover.menu_clear_or_create(_multi_sync_section)
119
+        _fill_multi_sync_section(_multi_sync_section, clip, track, callback)
120
+        
121
     rect = guipopover.create_rect(x, y)
122
     _multi_clip_popover = guipopover.new_mouse_popover(widget, _multi_clip_menu, rect, Gtk.PositionType.TOP)
123
 
124
@@ -391,6 +411,7 @@
125
         _fill_clone_filters_menu(clone_sub_menu, callback, False, False, True)
126
         filters_section.append_submenu(_("Clone Filter"), clone_sub_menu)
127
         add_menu_action(filters_section, _("Clear Filters"), "transitionclipmenu.clearfilters",  ("clear_filters", None), callback)
128
+        add_menu_action(filters_section, _("Paste Filters"), "transitionclipmenu.pastefilters",  ("paste_filters", None), callback)
129
         _transition_menu.append_section(None, filters_section)
130
 
131
     else: # Menu items with possible state changes need to recreated.
132
@@ -405,17 +426,21 @@
133
     if clip.media_type == appconsts.IMAGE_SEQUENCE or clip.media_type == appconsts.IMAGE or clip.media_type == appconsts.PATTERN_PRODUCER:
134
         active = False
135
     add_menu_action(multi_audio_section, _("Split Audio"), "multiclipmenu.multisplitaudio",  ("multi_split_audio", None), callback, active)
136
-    active = (track.id == current_sequence().first_video_index)
137
+    active = True
138
     if clip.media_type == appconsts.IMAGE_SEQUENCE or clip.media_type == appconsts.IMAGE or clip.media_type == appconsts.PATTERN_PRODUCER:
139
         active = False
140
     add_menu_action(multi_audio_section, _("Split Audio Synched"), "multiclipmenu.multisplitaudiosynched",  ("multi_split_audio_synched", None), callback, active)
141
     if clip.media_type == appconsts.IMAGE_SEQUENCE or clip.media_type == appconsts.IMAGE or clip.media_type == appconsts.PATTERN_PRODUCER:
142
         active = False
143
-    else:
144
-        active = True
145
+
146
     add_menu_action(multi_audio_section, _("Mute Audio"), "multiclipmenu.muteaudio",  ("multi_mute_audio", None), callback, active)
147
     add_menu_action(multi_audio_section, _("Unmute Audio"), "multiclipmenu.unmuteaudio",  ("multi_unmute_audio", None), callback, active)
148
-    
149
+
150
+def _fill_multi_sync_section(sync_section, clip, track, callback):
151
+    add_menu_action(sync_section,_("Select Sync Parent Clip..."), "clipmenu.multisetmaster",  ("multi_set_master", None), callback)
152
+    add_menu_action(sync_section,_("Resync"), "clipmenu.multiresync",  ("multi_resync", None), callback)
153
+    add_menu_action(sync_section,_("Clear Sync Relations"), "clipmenu.multiclearsyncrel",  ("multi_clear_sync_rel", None), callback)
154
+
155
 def _fill_audio_menu(audio_submenu, clip, track, callback):
156
     if track.type == appconsts.VIDEO:
157
         active = True
158
@@ -423,7 +448,7 @@
159
             active = False
160
         add_menu_action(audio_submenu, _("Split Audio"), "clipmenu.splitaudio",  ("split_audio", None), callback, active)
161
 
162
-        active = (track.id == current_sequence().first_video_index)
163
+        active = True
164
         if clip.media_type == appconsts.IMAGE_SEQUENCE or clip.media_type == appconsts.IMAGE or clip.media_type == appconsts.PATTERN_PRODUCER:
165
             active = False
166
         add_menu_action(audio_submenu, _("Split Audio Synched"), "clipmenu.splitaudiosynched", ("split_audio_synched", None), callback, active)
167
@@ -504,16 +529,18 @@
168
     del_section = Gio.Menu.new()
169
     add_menu_action(del_section,_("Delete"), "clipmenu.delete",  ("delete", None), callback)
170
     add_menu_action(del_section,_("Lift"), "clipmenu.delete",  ("lift", None), callback)
171
+    add_menu_action(del_section, _("Ripple Delete Clip Range"), "clipmenu.ripplerange",  ("ripplerange", None), callback)
172
     edit_actions_menu.append_section(None, del_section)
173
 
174
-    if track.id != current_sequence().first_video_index:
175
-        sync_section = Gio.Menu.new()
176
-        if clip.sync_data != None:
177
-            add_menu_action(sync_section,_("Resync"), "clipmenu.resync",  ("resync", None), callback)
178
-            add_menu_action(sync_section,_("Clear Sync Relation"), "clipmenu.clearsyncrel",  ("clear_sync_rel", None), callback)
179
-        else:
180
-            add_menu_action(sync_section,_("Select Sync Parent Clip..."), "clipmenu.setmaster",  ("set_master", None), callback)
181
-        edit_actions_menu.append_section(None, sync_section)
182
+    sync_section = Gio.Menu.new()
183
+
184
+    active = (clip.sync_data != None)
185
+    add_menu_action(sync_section,_("Resync"), "clipmenu.resync",  ("resync", None), callback, active)
186
+    add_menu_action(sync_section,_("Clear Sync Relation"), "clipmenu.clearsyncrel",  ("clear_sync_rel", None), callback, active)
187
+
188
+    active = (clip.sync_data == None)
189
+    add_menu_action(sync_section,_("Select Sync Parent Clip..."), "clipmenu.setmaster",  ("set_master", None), callback, active)
190
+    edit_actions_menu.append_section(None, sync_section)
191
 
192
     length_section = Gio.Menu.new()
193
     add_menu_action(length_section, _("Set Clip Length..."), "clipmenu.length",  ("length", None), callback)
194
@@ -544,8 +571,14 @@
195
         pre_id = "audio"
196
     else:
197
         pre_id = ""
198
-    add_menu_action(select_menu, _("All Clips After"), pre_id + "clipmenu.selectallafter",  ("select_all_after", None), callback)
199
-    add_menu_action(select_menu, _("All Clips Before"), pre_id + "clipmenu.selectallbefore",  ("select_all_before", None), callback)
200
+    select_section = Gio.Menu.new()
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/jobs.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/jobs.py Changed
201
 
1
@@ -46,6 +46,7 @@
2
 import renderconsumer
3
 import respaths
4
 import stabilizeheadless
5
+import stabilizedvideoheadless
6
 import trackingheadless
7
 import userfolders
8
 import utils
9
@@ -64,6 +65,7 @@
10
 CONTAINER_CLIP_RENDER_FLUXITY = 6
11
 STABILIZE_DATA_RENDER = 7
12
 MOTION_TRACKING_DATA_RENDER = 8
13
+STABILIZED_MEDIA_ITEM_RENDER = 9
14
 
15
 FFMPEG_ATTR_SOURCEFILE = "%SOURCEFILE"
16
 FFMPEG_ATTR_SCREENSIZE = "%SCREENSIZE"
17
@@ -122,7 +124,15 @@
18
         self.text = text
19
         self.elapsed = elapsed
20
 
21
-                  
22
+class ProcessCommandListRunner(threading.Thread):
23
+    def __init__(self, command_list):
24
+        threading.Thread.__init__(self)
25
+        self.command_list = command_list
26
+        
27
+    def run(self):
28
+        process = subprocess.Popen(self.command_list)
29
+        process.wait()
30
+
31
 #---------------------------------------------------------------- interface
32
 def add_job(job_proxy):
33
     global _jobs, _jobs_list_view 
34
@@ -455,7 +465,6 @@
35
         return file_name
36
         
37
     def start_render(self):
38
-        
39
         job_msg = self.get_job_queue_message()
40
         job_msg.text = _("Render Starting...")
41
         job_msg.status = RENDERING
42
@@ -468,8 +477,10 @@
43
             command_list.append(arg)
44
         parent_folder_arg = "parent_folder:" + str(self.parent_folder)
45
         command_list.append(parent_folder_arg)
46
-            
47
-        subprocess.Popen(command_list)
48
+
49
+        # We need to wait() in thread.
50
+        command_list_runner = ProcessCommandListRunner(command_list)
51
+        command_list_runner.start()
52
         
53
     def update_render_status(self):
54
         GLib.idle_add(self._update_from_gui_thread)
55
@@ -512,7 +523,7 @@
56
             else:
57
                 # Process start/stop on their own and we hit trying to get non-existing status for e.g completed renders.
58
                 
59
-                # This may not necessery to do here.
60
+                # This may not necessary to do here.
61
                 if self.tline_clip_data != None:
62
                     self.target_clip.render_progress = None
63
 
64
@@ -553,7 +564,7 @@
65
         # Set writefile.
66
         data_file_uid = utils.get_uid_str()
67
         self.write_file = userfolders.get_render_dir() + data_file_uid + appconsts.STABILIZE_DATA_EXTENSION
68
-        print(self.write_file)
69
+
70
         # Create command list and launch process.
71
         command_list = sys.executable
72
         command_list.append(respaths.LAUNCH_DIR + "flowbladestabilizeheadless")
73
@@ -612,7 +623,159 @@
74
         stabilizeheadless.abort_render(self.parent_folder, self.get_session_id())
75
 
76
 
77
-class MotionTrackingDataRenderJobQueueObject(AbstractJobQueueObject):
78
+class StablizedMediaItemDataRenderJobQueueObject(AbstractJobQueueObject):
79
+
80
+    def __init__(self, session_id, media_file, render_params, data_render_comple_callback, args):
81
+        
82
+        AbstractJobQueueObject.__init__(self, session_id, STABILIZE_DATA_RENDER)
83
+        
84
+        self.media_file = media_file
85
+        self.render_params = render_params
86
+        self.args = args
87
+        self.parent_folder = userfolders.get_temp_render_dir() # This is used for message passing, output file goes to path given by 'write_file'.
88
+        self.data_render_comple_callback = data_render_comple_callback
89
+        
90
+    def start_render(self):
91
+        
92
+        job_msg = self.get_job_queue_message()
93
+        job_msg.text = _("Render Starting...")
94
+        job_msg.status = RENDERING
95
+        update_job_queue(job_msg)
96
+        
97
+        # Set writefile.
98
+        data_file_uid = utils.get_uid_str()
99
+        self.write_file = userfolders.get_render_dir() + data_file_uid + appconsts.STABILIZE_DATA_EXTENSION
100
+
101
+        # Create command list and launch process.
102
+        command_list = sys.executable
103
+        command_list.append(respaths.LAUNCH_DIR + "flowbladestabilizeheadless")
104
+        for arg in self.args:
105
+            command_list.append(arg)
106
+        parent_folder_arg = "parent_folder:" + str(self.parent_folder)
107
+        command_list.append(parent_folder_arg)
108
+        write_file_arg = "write_file:" + str(self.write_file)
109
+        command_list.append(write_file_arg)
110
+        
111
+        subprocess.Popen(command_list)
112
+        
113
+    def update_render_status(self):
114
+        GLib.idle_add(self._update_from_gui_thread)
115
+            
116
+    def _update_from_gui_thread(self):
117
+
118
+        if stabilizeheadless.session_render_complete(self.parent_folder, self.get_session_id()) == True:
119
+            
120
+            job_msg = self.get_completed_job_message()
121
+            update_job_queue(job_msg)
122
+            
123
+            stabilizeheadless.delete_session_folders(self.parent_folder, self.get_session_id())
124
+            
125
+            GLib.idle_add(self.data_render_done)
126
+
127
+        else:
128
+            status = stabilizeheadless.get_session_status(self.parent_folder, self.get_session_id())
129
+            if status != None:
130
+                fraction, elapsed = status
131
+                
132
+                self.progress = float(fraction)
133
+                if self.progress > 1.0:
134
+                    # A fix for how progress is calculated because producers can render a bit longer then required.
135
+                    self.progress = 1.0
136
+
137
+                self.elapsed = float(elapsed)
138
+                self.text = _("Stabilizing Analysis") + " " + self.media_file.name
139
+                
140
+                job_msg = self.get_job_queue_message()
141
+                
142
+                update_job_queue(job_msg)
143
+            else:
144
+                # Process start/stop on their own and we hit trying to get non-existing status for e.g completed renders.
145
+                pass
146
+
147
+    def data_render_done(self):
148
+        self.data_render_comple_callback(self.media_file, self.render_params, self.write_file)
149
+        
150
+    def abort_render(self):
151
+        #remove_as_status_polling_object(self)
152
+        stabilizeheadless.abort_render(self.parent_folder, self.get_session_id())
153
+
154
+
155
+class StabilizedMediaItemVideoRenderJobQueueObject(AbstractJobQueueObject):
156
+
157
+    def __init__(self, session_id, write_file, args):
158
+        
159
+        AbstractJobQueueObject.__init__(self, session_id, STABILIZED_MEDIA_ITEM_RENDER)
160
+        
161
+        self.write_file = write_file
162
+        self.args = args
163
+        self.parent_folder = userfolders.get_temp_render_dir() # THis is just used for message passing, output file goes where user decided.
164
+                
165
+    def get_job_name(self):
166
+        folder, file_name = os.path.split(self.write_file)
167
+        return file_name
168
+        
169
+    def start_render(self):
170
+        
171
+        job_msg = self.get_job_queue_message()
172
+        job_msg.text = _("Render Starting...")
173
+        job_msg.status = RENDERING
174
+        update_job_queue(job_msg)
175
+        
176
+        # Create command list and launch process.
177
+        command_list = sys.executable
178
+        command_list.append(respaths.LAUNCH_DIR + "flowbladestabilizedvideoheadless")
179
+        for arg in self.args:
180
+            command_list.append(arg)
181
+        parent_folder_arg = "parent_folder:" + str(self.parent_folder)
182
+        command_list.append(parent_folder_arg)
183
+
184
+        # We need to wait() in thread.
185
+        command_list_runner = ProcessCommandListRunner(command_list)
186
+        command_list_runner.start()
187
+        
188
+    def update_render_status(self):
189
+        GLib.idle_add(self._update_from_gui_thread)
190
+            
191
+    def _update_from_gui_thread(self):
192
+
193
+        if stabilizedvideoheadless.session_render_complete(self.parent_folder, self.get_session_id()) == True:
194
+            job_msg = self.get_completed_job_message()
195
+            update_job_queue(job_msg)
196
+            
197
+            stabilizedvideoheadless.delete_session_folders(self.parent_folder, self.get_session_id())
198
+            
199
+            GLib.idle_add(self.create_media_item)
200
+
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/keyevents.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/keyevents.py Changed
10
 
1
@@ -162,7 +162,7 @@
2
         _handle_clip_key_event(event)
3
         return True
4
         
5
-    #  Handle non-timeline delete .
6
+    #  Handle non-timeline delete.
7
     if event.keyval == Gdk.KEY_Delete:
8
         return _handle_delete()
9
 
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/keyframeeditcanvas.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/keyframeeditcanvas.py Changed
57
 
1
@@ -360,6 +360,17 @@
2
         self.keyframes.append((frame, copy.deepcopy(p_shape), copy.deepcopy(p_opacity),  p_type))
3
         
4
         self.keyframes.sort(key=_geom_kf_sort)
5
+
6
+    def add_keyframe_with_shape_opacity_and_type(self, frame, shape, opacity, kf_type):
7
+        if self._frame_has_keyframe(frame) == True:
8
+            kf_index = self._get_frame_keyframe_index(frame)
9
+            self.keyframes.pop(kf_index)
10
+            self._update_shape()
11
+
12
+        # Add with values, for now we always set opacity to max.
13
+        self.keyframes.append((frame, shape, opacity,  kf_type))
14
+        
15
+        self.keyframes.sort(key=_geom_kf_sort)
16
         
17
     def delete_active_keyframe(self, keyframe_index):
18
         if keyframe_index == 0:
19
@@ -377,6 +388,15 @@
20
 
21
         return False
22
 
23
+    def _get_frame_keyframe_index(self, frame):
24
+        for i in range(0, len(self.keyframes)):
25
+            kf = self.keyframesi
26
+            kf_frame, rect, opacity, kf_type = kf
27
+            if frame == kf_frame:
28
+                return i
29
+
30
+        return None
31
+        
32
     def set_keyframes(self, keyframes_str, out_to_in_func):
33
         self.keyframes = self.keyframe_parser(keyframes_str, out_to_in_func)
34
 
35
@@ -566,6 +586,10 @@
36
     def _draw_edit_shape(self, cr, allocation):
37
         print("_draw_edit_shape not impl.")
38
         
39
+    def print_keyframes(self):
40
+        for i in range(0, len(self.keyframes)):
41
+            print(self.keyframesi)
42
+
43
 
44
 class BoxEditCanvas(AbstractEditCanvas):
45
     """
46
@@ -801,9 +825,7 @@
47
         
48
         self.source_edit_rect.h = self.source_edit_rect.h * (self.source_edit_rect.w / old_w)
49
 
50
-    def print_keyframes(self):
51
-        for i in range(0, len(self.keyframes)):
52
-            print(self.keyframesi)
53
+
54
 
55
 
56
 class RotatingEditCanvas(AbstractEditCanvas):
57
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/keyframeeditor.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/keyframeeditor.py Changed
201
 
1
@@ -37,6 +37,7 @@
2
 import cairoarea
3
 import callbackbridge
4
 import compositorfades
5
+import dialogutils
6
 from editorstate import PLAYER
7
 from editorstate import current_sequence
8
 from editorstate import PROJECT
9
@@ -539,6 +540,26 @@
10
         self.keyframes.append((frame, prev_value, prev_type))
11
         self.active_kf_index = len(self.keyframes) - 1
12
 
13
+    def add_keyframe_with_type(self, frame, type):
14
+        # NOTE: This makes added keyframe the active keyframe too.
15
+        kf_index_on_frame = self.frame_has_keyframe(frame)
16
+        if kf_index_on_frame != -1:
17
+            # Trying add on top of existing keyframe makes it active
18
+            self.active_kf_index = kf_index_on_frame
19
+            return
20
+
21
+        for i in range(0, len(self.keyframes)):
22
+            kf_frame, kf_value, kf_type = self.keyframesi
23
+            if kf_frame > frame:
24
+                prev_frame, prev_value, prev_type = self.keyframesi - 1
25
+                self.keyframes.insert(i, (frame, prev_value, type))
26
+                self.active_kf_index = i
27
+                return
28
+
29
+        prev_frame, prev_value, prev_type = self.keyframeslen(self.keyframes) - 1
30
+        self.keyframes.append((frame, prev_value, type))
31
+        self.active_kf_index = len(self.keyframes) - 1
32
+        
33
     def print_keyframes(self, msg="no_msg"):
34
         print(msg, "clip edit keyframes:")
35
         for i in range(0, len(self.keyframes)):
36
@@ -554,6 +575,21 @@
37
             self.active_kf_index = 0
38
         self._set_pos_to_active_kf()
39
 
40
+    def delete_keyframe(self, index):
41
+        if index == 0:
42
+            return
43
+
44
+        try:
45
+            self.keyframes.pop(index)
46
+        except:
47
+            print("ClipKeyFrameEditor.delete_keyframe index out of range")
48
+            return
49
+                
50
+        if self.active_kf_index >= len(self.keyframes):
51
+            self.active_kf_index = len(self.keyframes) - 1
52
+            return
53
+        self._set_pos_to_active_kf()
54
+        
55
     def set_next_active(self):
56
         """
57
         Activates next keyframe or keeps last active to stay in range.
58
@@ -578,7 +614,15 @@
59
             self.active_kf_index = len(self.get_out_of_range_before_kfs())
60
 
61
         self._set_pos_to_active_kf()
62
-    
63
+
64
+    def set_active_keyframe_to_kf_in_frame(self, frame):
65
+        # this is noop if no keyframe in frame exists.
66
+        for i in range(0, len(self.keyframes)):
67
+            kf_frame, kf_value, kf_type = self.keyframesi
68
+            if kf_frame == frame:
69
+                self.active_kf_index = i
70
+                self._set_pos_to_active_kf()
71
+
72
     def _set_pos_to_active_kf(self):
73
         try:
74
             frame, value, type = self.keyframesself.active_kf_index
75
@@ -996,6 +1040,10 @@
76
         guipopover.add_menu_action_all_items_radio(kftype_section, items_data, action_id, active_index, callback)
77
         menu.append_section(None, kftype_section)
78
 
79
+    def print_keyframes(self, msg="no_msg"):
80
+        print(msg, "clip edit keyframes:")
81
+        for i in range(0, len(self.clip_editor.keyframes)):
82
+            print(self.clip_editor.keyframesi)
83
         
84
 class KeyFrameEditor(AbstractKeyFrameEditor):
85
     """
86
@@ -1191,7 +1239,18 @@
87
             self.clip_editor.clone_value_from_next()
88
         elif msg  == "clonekfprev":
89
             self.clip_editor.clone_value_from_prev()
90
-    
91
+        elif msg == "openinkftool":
92
+            track = self.editable_property.track
93
+            clip = self.editable_property.clip
94
+            displayname = self.editable_property.args"displayname".replace("!", " ")
95
+            filter_index = self.editable_property.filter_index
96
+            filter = clip.filtersfilter_index
97
+            prop = filter.propertiesself.editable_property.property_index
98
+            param_name, val, type = prop
99
+            callbackbridge.modesetting_kftool_mode_from_kf_editor(clip, track, param_name, filter, filter_index, displayname)
100
+
101
+            return
102
+            
103
         self.queue_draw()
104
         self.update_property_value()
105
 
106
@@ -1260,6 +1319,10 @@
107
 
108
         _kf_menu.append_section(None, kfs_section)
109
 
110
+        open_in_kf_tool_section = Gio.Menu.new()
111
+        guipopover.add_menu_action(open_in_kf_tool_section, _("Open in Keyframe Tool"), "keyframes.openinkftool",  "openinkftool", self._menu_item_activated)
112
+        _kf_menu.append_section(None, open_in_kf_tool_section)
113
+        
114
         _kf_popover = guipopover.new_popover(widget, _kf_menu, launcher)
115
 
116
 
117
@@ -1850,7 +1913,7 @@
118
         # that contain the property values when opening editor.
119
         # From now on clip editor opacity values are used until editor is discarded.
120
         self.clip_editor.keyframes = self.get_clip_editor_keyframes()
121
-      
122
+
123
         # Build gui
124
         self.pack_start(g_frame, False, False, 0)
125
         self.pack_start(self.pos_entries_row, False, False, 0)
126
@@ -2049,6 +2112,239 @@
127
         self.update_editor_view_with_frame(frame)
128
         self.update_property_value()
129
 
130
+    def _show_add_movement_dialog(self):
131
+        categories_list = 
132
+        in_moves = _("Slide In Form Left"), _("Slide In From Right"), _("Slide In From Top"), _("Slide In From Bottom")
133
+        categories_list.append((_("Slide In"), in_moves))
134
+        out_moves = _("Slide Out To Left"), _("Slide Out To Right"), _("Slide Out To Top"), ("Slide Out To Bottom")
135
+        categories_list.append((_("Slide Out"), out_moves))
136
+        zoom_in_moves = _("Zoom In 5%"), _("Zoom In 10%"), _("Zoom In 20%"), _("Zoom In 30%")
137
+        categories_list.append((_("Zoom In"), zoom_in_moves))
138
+        zoom_out_moves = _("Zoom Out 5%"), _("Zoom Out 10%"), _("Zoom Out 20%"), _("Zoom Out 30%")
139
+        categories_list.append((_("Zoom Out"), zoom_out_moves))
140
+        
141
+        combo = guicomponents.CategoriesModelComboBox(categories_list)
142
+        combo.set_selected(in_moves0)
143
+
144
+        hbox, slider = guiutils.get_non_property_slider_row(2, 200, 1, 10)
145
+        hbox.set_size_request(300, 20)
146
+
147
+        kf_type_combo = Gtk.ComboBoxText()
148
+        kf_type_combo.append_text(_("Linear"))
149
+        kf_type_combo.append_text(_("Smooth"))
150
+        kf_type_combo.set_active(0)
151
+
152
+        left_width = 170
153
+        row1 = guiutils.get_two_column_box(Gtk.Label(label=_("Movement Type:")), combo.widget, left_width)
154
+        row2 = guiutils.get_two_column_box(Gtk.Label(label=_("Movement Length:")), hbox, left_width)
155
+        row3 = guiutils.get_two_column_box(Gtk.Label(label=_("Keyframe Type:")), kf_type_combo, left_width)
156
+        
157
+        pane = Gtk.VBox()
158
+        
159
+        pane = Gtk.VBox()
160
+        pane.pack_start(row1, False, False, 0)
161
+        pane.pack_start(row2, False, False, 0)
162
+        pane.pack_start(row3, False, False, 0)
163
+
164
+        dialogutils.panel_ok_cancel_dialog(_("Add Preset Movement"), pane, _("Add Movement"), self._add_movemement_callback, (combo, slider, kf_type_combo, in_moves, out_moves, zoom_in_moves, zoom_out_moves))
165
+
166
+    def _add_movemement_callback(self, dialog, response_id, data):
167
+        if response_id != Gtk.ResponseType.ACCEPT:
168
+            dialog.destroy()
169
+            return
170
+
171
+        combo, slider, kf_type_combo, in_moves, out_moves, zoom_in_moves, zoom_out_moves = data
172
+
173
+        sel = combo.get_selected()
174
+        length = int(slider.get_value()) 
175
+        in_frame = self.editable_property.clip.clip_in
176
+        out_frame = self.editable_property.clip.clip_out
177
+
178
+        if kf_type_combo.get_active() == 0:
179
+            kf_type = appconsts.KEYFRAME_LINEAR
180
+        else:
181
+            kf_type = appconsts.KEYFRAME_SMOOTH
182
+            
183
+        dialog.destroy()
184
+        
185
+        if ((sel in in_moves) or (sel in out_moves)) == True:
186
+            active_frame = self._write_preset_slide_keyframes(sel, length, kf_type, in_frame, out_frame, in_moves, out_moves)
187
+        else:
188
+            active_frame = self._write_preset_zoom_keyframes(sel, length, kf_type, in_frame, out_frame, zoom_in_moves, zoom_out_moves)
189
+        
190
+        # Update view.
191
+        self.clip_editor.set_active_keyframe_to_kf_in_frame(active_frame)
192
+        
193
+        frame = self.clip_editor.get_active_kf_frame()
194
+        self.pos_entries_row.update_entry_values(self.geom_kf_edit.get_keyframe(self.clip_editor.active_kf_index))
195
+        self.update_editor_view_with_frame(frame)
196
+        self.update_property_value()
197
+        self.buttons_row.set_kf_info(self.clip_editor.get_kf_info())
198
+
199
+        #def _write_preset_slide_keyframes(self, x1, x2, y1, y2, fr1, fr2, kf_type):
200
+    def _write_preset_slide_keyframes(self, sel, length, kf_type, in_frame, out_frame, in_moves, out_moves):
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/kftoolmode.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/kftoolmode.py Changed
32
 
1
@@ -208,6 +208,10 @@
2
     tlinewidgets.set_edit_mode_data(edit_data)
3
     updater.repaint_tline()
4
 
5
+def init_for_clip_filter_and_param(clip, track, param_name, filter, filter_index, dispay_name):
6
+    param_data = (param_name, filter, filter_index, dispay_name)
7
+    init_tool_for_clip(clip, track, PARAM_KF_EDIT, param_data)
8
+
9
 def get_clip_kftool_editable_params_data(clip):
10
     kftool_editable_params = 
11
     for i in range(0, len(clip.filters)):
12
@@ -332,7 +336,7 @@
13
     global enter_mode
14
     if enter_mode != None:
15
         # Exit to enter mode if we had one.
16
-        gui.editor_window.tline_cursor_manager.tline_cursor_manager.kf_tool_exit_to_mode(enter_mode)
17
+        gui.editor_window.tline_cursor_manager.kf_tool_exit_to_mode(enter_mode)
18
         enter_mode = None
19
     else:
20
         # Exit to default mode if no editor was open.
21
@@ -1702,6 +1706,10 @@
22
             global _playhead_follow_kf
23
             _playhead_follow_kf = new_state
24
             action.set_state(GLib.Variant.new_boolean(new_state))
25
+        elif msg == "editpanel":
26
+            ep = edit_data"editable_property"
27
+            clipeffectseditor.set_clip_and_filter(ep.clip, ep.track, ep.clip_index, ep.filter_index)
28
+            exit_tool()
29
         elif msg == "exit":
30
             set_no_clip_edit_data()
31
     
32
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/launch/flowblademltxmlheadless -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/launch/flowblademltxmlheadless Changed
18
 
1
@@ -30,6 +30,7 @@
2
     session_id = _get_arg_value(sys.argv, "session_id")
3
     parent_folder = _get_arg_value(sys.argv, "parent_folder")
4
     xml_file_path = _get_arg_value(sys.argv, "xml_file_path")
5
+    video_file_name = _get_arg_value(sys.argv, "video_file_name")
6
     range_in = _get_arg_value(sys.argv, "range_in")
7
     range_out = _get_arg_value(sys.argv, "range_out")
8
     profile_desc_under_score = _get_arg_value(sys.argv, "profile_desc")
9
@@ -41,7 +42,7 @@
10
     print ("Installation was assumed to be at:", modules_path)
11
     sys.exit(1)
12
 
13
-mltxmlheadless.main(modules_path, session_id, parent_folder, xml_file_path, range_in, range_out, profile_desc)
14
+mltxmlheadless.main(modules_path, session_id, parent_folder, xml_file_path, video_file_name, range_in, range_out, profile_desc)
15
 
16
 
17
 
18
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/launch/flowbladestabilizedvideoheadless Added
51
 
1
@@ -0,0 +1,49 @@
2
+#!/usr/bin/python3
3
+
4
+import sys
5
+import os
6
+
7
+def _get_arg_value(args, key_str):
8
+    for arg in sys.argv:
9
+        parts = arg.split(":")
10
+        if len(parts) > 1:
11
+            if parts0 == key_str:
12
+                return parts1
13
+    
14
+    return None
15
+
16
+modules_path = os.path.dirname(os.path.abspath(sys.argv0)).rstrip("/launch")
17
+
18
+sys.path.insert(0, modules_path)
19
+import processutils
20
+processutils.update_sys_path(modules_path)
21
+
22
+try:
23
+    import stabilizedvideoheadless
24
+    import editorstate # Used to decide which translations from file system are used
25
+    root_dir = modules_path.split("/")1
26
+    
27
+    # And we need this for translations?
28
+    if root_dir != "home":
29
+        editorstate.app_running_from = editorstate.RUNNING_FROM_INSTALLATION
30
+    else:
31
+        editorstate.app_running_from = editorstate.RUNNING_FROM_DEV_VERSION
32
+    
33
+    session_id = _get_arg_value(sys.argv, "session_id")
34
+    parent_folder = _get_arg_value(sys.argv, "parent_folder")
35
+    write_file = _get_arg_value(sys.argv, "write_file")
36
+    results_file = _get_arg_value(sys.argv, "results_file")
37
+    encoding_option_index = _get_arg_value(sys.argv, "encoding_option_index")
38
+    quality_option_index = _get_arg_value(sys.argv, "quality_option_index")
39
+    source_path = _get_arg_value(sys.argv, "source_path")
40
+    profile_desc_under_score = _get_arg_value(sys.argv, "profile_desc")
41
+    profile_desc = profile_desc_under_score.replace("_", " ") # We need to put underscores in profile names to get them here in one piece.
42
+                                                              # Now we take underscores out to get correct MLT profile names.
43
+except Exception as err:
44
+    print ("Failed to import mltxmlheadless")
45
+    print ("ERROR:", err)
46
+    print ("Installation was assumed to be at:", modules_path)
47
+    sys.exit(1)
48
+
49
+stabilizedvideoheadless.main(   modules_path, session_id, parent_folder, write_file, results_file, profile_desc, encoding_option_index, 
50
+                                quality_option_index, source_path)
51
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/launch/flowbladestabilizeheadless -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/launch/flowbladestabilizeheadless Changed
19
 
1
@@ -28,6 +28,8 @@
2
     clip_path = _get_arg_value(sys.argv, "clip_path")
3
     accuracy = _get_arg_value(sys.argv, "accuracy")
4
     shakiness = _get_arg_value(sys.argv, "shakiness")
5
+    smoothing = _get_arg_value(sys.argv, "smoothing")
6
+    zoom = _get_arg_value(sys.argv, "zoom")
7
     profile_desc_under_score = _get_arg_value(sys.argv, "profile_desc")
8
     profile_desc = profile_desc_under_score.replace("_", " ") # We need to put underscores in profile names to get them here in one piece.
9
                                                               # Now we take underscores out to get correct MLT profile names.
10
@@ -37,7 +39,7 @@
11
     print ("Installation was assumed to be at:", modules_path)
12
     sys.exit(1)
13
 
14
-stabilizeheadless.main(modules_path, session_id, parent_folder, profile_desc, write_file, clip_path, accuracy, shakiness)
15
+stabilizeheadless.main(modules_path, session_id, parent_folder, profile_desc, write_file, clip_path, accuracy, shakiness, smoothing, zoom)
16
 
17
 
18
 
19
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/launch/flowbladetrackingheadless -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/launch/flowbladetrackingheadless Changed
10
 
1
@@ -18,6 +18,8 @@
2
 import processutils
3
 processutils.update_sys_path(modules_path)
4
 
5
+print("process trackingheadless PID:", os.getpid())
6
+
7
 try:
8
     import trackingheadless
9
     root_dir = modules_path.split("/")1
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/Flowblade/flowblade.pot -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/Flowblade/flowblade.pot Changed
201
 
1
@@ -8,7 +8,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
 "Language-Team: LANGUAGE <LL@li.org>\n"
10
@@ -33,138 +33,138 @@
11
 msgid "5 min"
12
 msgstr ""
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr ""
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr ""
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr ""
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 msgid "Your MLT version is: "
69
 msgstr ""
70
 
71
-#: app.py:1053
72
+#: app.py:1059
73
 msgid "Install MLT 6.18 or higher to run Flowblade."
74
 msgstr ""
75
 
76
-#: app.py:1127 projectaction.py:555 projectaction.py:757
77
+#: app.py:1133 projectaction.py:559 projectaction.py:761
78
 msgid "Project has not been saved previously"
79
 msgstr ""
80
 
81
-#: app.py:1128 projectaction.py:556 projectaction.py:758
82
+#: app.py:1134 projectaction.py:560 projectaction.py:762
83
 msgid "Save project with File -> Save As before closing."
84
 msgstr ""
85
 
86
-#: projectaction.py:147
87
+#: projectaction.py:151
88
 msgid "Opening"
89
 msgstr ""
90
 
91
-#: projectaction.py:226
92
+#: projectaction.py:230
93
 msgid "Media asset was missing!"
94
 msgstr ""
95
 
96
-#: projectaction.py:227
97
+#: projectaction.py:231
98
 msgid "Path of missing asset:"
99
 msgstr ""
100
 
101
-#: projectaction.py:228
102
+#: projectaction.py:232
103
 msgid ""
104
 "Relative search for replacement file in sub folders of project file failed."
105
 msgstr ""
106
 
107
-#: projectaction.py:229
108
+#: projectaction.py:233
109
 msgid "To load the project you will need to either:"
110
 msgstr ""
111
 
112
-#: projectaction.py:230
113
+#: projectaction.py:234
114
 msgid ""
115
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
116
 msgstr ""
117
 
118
-#: projectaction.py:231
119
+#: projectaction.py:235
120
 msgid "Place a file with the same exact name and path on the hard drive"
121
 msgstr ""
122
 
123
-#: projectaction.py:232
124
+#: projectaction.py:236
125
 msgid "Open project in Media Relinker tool"
126
 msgstr ""
127
 
128
-#: projectaction.py:251
129
+#: projectaction.py:255
130
 msgid "Profile with Description: '"
131
 msgstr ""
132
 
133
-#: projectaction.py:251
134
+#: projectaction.py:255
135
 msgid "' was not found on load!"
136
 msgstr ""
137
 
138
-#: projectaction.py:252
139
+#: projectaction.py:256
140
 msgid ""
141
 "It is possible to load the project by creating a User Profile with exactly "
142
 "the same Description\n"
143
 "as the missing profile. "
144
 msgstr ""
145
 
146
-#: projectaction.py:253
147
+#: projectaction.py:257
148
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
149
 msgstr ""
150
 
151
-#: projectaction.py:360
152
+#: projectaction.py:364
153
 msgid "Opening animated .gif file was refused!"
154
 msgstr ""
155
 
156
-#: projectaction.py:361
157
+#: projectaction.py:365
158
 msgid ""
159
 "Flowblade does not support displaying animated GIF files as media objects.\n"
160
 msgstr ""
161
 
162
-#: projectaction.py:362
163
+#: projectaction.py:366
164
 msgid ""
165
 "A possible workaround is to render GIF into a frame sequence and\n"
166
 "open that as a media item."
167
 msgstr ""
168
 
169
-#: projectaction.py:366
170
+#: projectaction.py:370
171
 msgid "Opening files with unknown  extensions refused!"
172
 msgstr ""
173
 
174
-#: projectaction.py:367
175
+#: projectaction.py:371
176
 msgid ""
177
 "Flowblade does not open files that cannot be identified as media from file "
178
 "extensions.\n"
179
@@ -172,110 +172,110 @@
180
 "\n"
181
 msgstr ""
182
 
183
-#: projectaction.py:369
184
+#: projectaction.py:373
185
 msgid "Too many to list.\n"
186
 msgstr ""
187
 
188
-#: projectaction.py:374
189
+#: projectaction.py:378
190
 msgid ""
191
 "\n"
192
 "Add the correct extension to load a problem file."
193
 msgstr ""
194
 
195
-#: projectaction.py:445
196
+#: projectaction.py:449
197
 msgid "Media files already present in project were opened!"
198
 msgstr ""
199
 
200
-#: projectaction.py:451
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/cs/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -6,7 +6,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2021-02-28 16:18+0100\n"
8
 "Last-Translator: Pavel Fric <pavelfric@seznam.cz>\n"
9
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
10
@@ -35,114 +35,114 @@
11
 msgid "5 min"
12
 msgstr "5 minut"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Příliš malá obrazovka pro tento program."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "Nejmenší rozměry obrazovky pro tento program jsou 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Rozměry vaší obrazovky jsou "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr "Program nelze spustit z důvodu chyby v inicializaci složky XDG."
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 "Flowblade ve verzi 2.6 (nebo novější) vyžaduje ke svému běhu MLT ve verzi "
66
 "6.18"
67
 
68
-#: app.py:1053
69
+#: app.py:1059
70
 msgid "Your MLT version is: "
71
 msgstr "Verze MLT: "
72
 
73
-#: app.py:1053
74
+#: app.py:1059
75
 msgid "Install MLT 6.18 or higher to run Flowblade."
76
 msgstr "Pro běh Flowblade nainstalujte MLT 6.18 nebo novější."
77
 
78
-#: app.py:1127 projectaction.py:555 projectaction.py:757
79
+#: app.py:1133 projectaction.py:559 projectaction.py:761
80
 msgid "Project has not been saved previously"
81
 msgstr "Projekt předtím byl uložen"
82
 
83
-#: app.py:1128 projectaction.py:556 projectaction.py:758
84
+#: app.py:1134 projectaction.py:560 projectaction.py:762
85
 msgid "Save project with File -> Save As before closing."
86
 msgstr "Uložte projekt před zavřením pomocí Soubor → Uložit."
87
 
88
-#: projectaction.py:147
89
+#: projectaction.py:151
90
 msgid "Opening"
91
 msgstr "Otevírá se"
92
 
93
-#: projectaction.py:226
94
+#: projectaction.py:230
95
 msgid "Media asset was missing!"
96
 msgstr "Položka záznamů chybí!"
97
 
98
-#: projectaction.py:227
99
+#: projectaction.py:231
100
 msgid "Path of missing asset:"
101
 msgstr "Cesta k chybějící položce:"
102
 
103
-#: projectaction.py:228
104
+#: projectaction.py:232
105
 msgid ""
106
 "Relative search for replacement file in sub folders of project file failed."
107
 msgstr ""
108
 "Relativní hledání pro nahrazovací soubor v podsložkách souboru s projektem "
109
 "se nezdařilo."
110
 
111
-#: projectaction.py:229
112
+#: projectaction.py:233
113
 msgid "To load the project you will need to either:"
114
 msgstr "Pro nahrání projektu budete potřebovat:"
115
 
116
-#: projectaction.py:230
117
+#: projectaction.py:234
118
 msgid ""
119
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
120
 msgstr ""
121
 "Otevřít projekt v nástroji pro nové odkazování na záznamy pro svázání "
122
 "záznamů s novými soubory, nebo"
123
 
124
-#: projectaction.py:231
125
+#: projectaction.py:235
126
 msgid "Place a file with the same exact name and path on the hard drive"
127
 msgstr "Umístěte falešný soubor s přesně stejným názvem a cestou na pevný disk"
128
 
129
-#: projectaction.py:232
130
+#: projectaction.py:236
131
 msgid "Open project in Media Relinker tool"
132
 msgstr "Otevřít projekt v nástroji pro odkazování záznamů"
133
 
134
-#: projectaction.py:251
135
+#: projectaction.py:255
136
 msgid "Profile with Description: '"
137
 msgstr "Profil s popisem: „"
138
 
139
-#: projectaction.py:251
140
+#: projectaction.py:255
141
 msgid "' was not found on load!"
142
 msgstr "“ nebyl při nahrávání nalezen!"
143
 
144
-#: projectaction.py:252
145
+#: projectaction.py:256
146
 msgid ""
147
 "It is possible to load the project by creating a User Profile with exactly "
148
 "the same Description\n"
149
@@ -152,22 +152,22 @@
150
 "popisem\n"
151
 "jako má chybějící profil. "
152
 
153
-#: projectaction.py:253
154
+#: projectaction.py:257
155
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
156
 msgstr "Uživatelské profily lze vytvářet vybráním Úpravy → Správce profilů."
157
 
158
-#: projectaction.py:360
159
+#: projectaction.py:364
160
 msgid "Opening animated .gif file was refused!"
161
 msgstr "Otevírání animovaného souboru .gif bylo odmítnuto!"
162
 
163
-#: projectaction.py:361
164
+#: projectaction.py:365
165
 msgid ""
166
 "Flowblade does not support displaying animated GIF files as media objects.\n"
167
 msgstr ""
168
 "Flowblade nepodporuje zobrazování animovaných souborů GIF jako předmětů "
169
 "záznamů.\n"
170
 
171
-#: projectaction.py:362
172
+#: projectaction.py:366
173
 msgid ""
174
 "A possible workaround is to render GIF into a frame sequence and\n"
175
 "open that as a media item."
176
@@ -175,11 +175,11 @@
177
 "Možným řešením je vykreslení GIF do sledu snímků a\n"
178
 "otevřít jej jako položku záznamu."
179
 
180
-#: projectaction.py:366
181
+#: projectaction.py:370
182
 msgid "Opening files with unknown  extensions refused!"
183
 msgstr ""
184
 
185
-#: projectaction.py:367
186
+#: projectaction.py:371
187
 msgid ""
188
 "Flowblade does not open files that cannot be identified as media from file "
189
 "extensions.\n"
190
@@ -187,21 +187,21 @@
191
 "\n"
192
 msgstr ""
193
 
194
-#: projectaction.py:369
195
+#: projectaction.py:373
196
 msgid "Too many to list.\n"
197
 msgstr ""
198
 
199
-#: projectaction.py:374
200
+#: projectaction.py:378
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/de/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -10,7 +10,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2014-11-23 14:22+0100\n"
8
 "Last-Translator: Martin Wielebinski <blueray.mw@gmail.com>\n"
9
 "Language-Team: German\n"
10
@@ -36,110 +36,110 @@
11
 msgid "5 min"
12
 msgstr ""
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Zu kleiner Bildschirm für diese Applikation."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "Minimale Auflösung für diese Applikation ist 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Ihre Auflösung beträgt "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr "Kann Applikation wegen XDG-Ordner-Fehler nicht starten."
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr "Flowblade Version 2.6 (und folgende) benötigt MLT ab Version 6.18"
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 msgid "Your MLT version is: "
69
 msgstr "Ihre MLT-Version ist: "
70
 
71
-#: app.py:1053
72
+#: app.py:1059
73
 msgid "Install MLT 6.18 or higher to run Flowblade."
74
 msgstr "Installieren Sie MLT 6.18 oder höher, um Flowblade zu nutzen."
75
 
76
-#: app.py:1127 projectaction.py:555 projectaction.py:757
77
+#: app.py:1133 projectaction.py:559 projectaction.py:761
78
 msgid "Project has not been saved previously"
79
 msgstr "Projekt wurde noch nicht gesichert"
80
 
81
-#: app.py:1128 projectaction.py:556 projectaction.py:758
82
+#: app.py:1134 projectaction.py:560 projectaction.py:762
83
 msgid "Save project with File -> Save As before closing."
84
 msgstr "Projekt vor dem Schließen sichern mit 'Datei -> Sichern als...'."
85
 
86
-#: projectaction.py:147
87
+#: projectaction.py:151
88
 msgid "Opening"
89
 msgstr "Öffnen"
90
 
91
-#: projectaction.py:226
92
+#: projectaction.py:230
93
 msgid "Media asset was missing!"
94
 msgstr "Mediendatei fehlt!"
95
 
96
-#: projectaction.py:227
97
+#: projectaction.py:231
98
 msgid "Path of missing asset:"
99
 msgstr "Pfad der fehlenden Datei:"
100
 
101
-#: projectaction.py:228
102
+#: projectaction.py:232
103
 msgid ""
104
 "Relative search for replacement file in sub folders of project file failed."
105
 msgstr "Suche nach Ersatzdatei in Unterordnern des Projekts fehlgeschlagen."
106
 
107
-#: projectaction.py:229
108
+#: projectaction.py:233
109
 msgid "To load the project you will need to either:"
110
 msgstr "Um das Projekt zu laden müssen Sie entweder:"
111
 
112
-#: projectaction.py:230
113
+#: projectaction.py:234
114
 msgid ""
115
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
116
 msgstr ""
117
 "Das 'Medien-Link'-Werkzeug nutzen, um Medien mit neuen Dateien zu "
118
 "verknüpfen, oder"
119
 
120
-#: projectaction.py:231
121
+#: projectaction.py:235
122
 msgid "Place a file with the same exact name and path on the hard drive"
123
 msgstr "eine Ersatz-Datei mit gleichem Namen und Pfad anlegen"
124
 
125
-#: projectaction.py:232
126
+#: projectaction.py:236
127
 msgid "Open project in Media Relinker tool"
128
 msgstr "Öffne das Projekt im 'Medien-Link' Werkzeug"
129
 
130
-#: projectaction.py:251
131
+#: projectaction.py:255
132
 msgid "Profile with Description: '"
133
 msgstr "Profil mit Beschreibung: '"
134
 
135
-#: projectaction.py:251
136
+#: projectaction.py:255
137
 msgid "' was not found on load!"
138
 msgstr "' wurde beim Laden nicht gefunden!"
139
 
140
-#: projectaction.py:252
141
+#: projectaction.py:256
142
 msgid ""
143
 "It is possible to load the project by creating a User Profile with exactly "
144
 "the same Description\n"
145
@@ -149,21 +149,21 @@
146
 "Parametern\n"
147
 "wie im fehlenden Profil angelegt wird. "
148
 
149
-#: projectaction.py:253
150
+#: projectaction.py:257
151
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
152
 msgstr ""
153
 "Nutzerprofile können unter 'Bearbeiten->Profil-Manager' angelegt werden."
154
 
155
-#: projectaction.py:360
156
+#: projectaction.py:364
157
 msgid "Opening animated .gif file was refused!"
158
 msgstr "Öffnen einer animierten GIF-Datei verweigert!"
159
 
160
-#: projectaction.py:361
161
+#: projectaction.py:365
162
 msgid ""
163
 "Flowblade does not support displaying animated GIF files as media objects.\n"
164
 msgstr "Flowblade unterstützt keine animierten GIF-Dateien als Medien.\n"
165
 
166
-#: projectaction.py:362
167
+#: projectaction.py:366
168
 msgid ""
169
 "A possible workaround is to render GIF into a frame sequence and\n"
170
 "open that as a media item."
171
@@ -171,11 +171,11 @@
172
 "Zur Umgehung kann man ein GIF in eine Filmsequenz verwandeln und\n"
173
 "diese als Medium verwenden."
174
 
175
-#: projectaction.py:366
176
+#: projectaction.py:370
177
 msgid "Opening files with unknown  extensions refused!"
178
 msgstr ""
179
 
180
-#: projectaction.py:367
181
+#: projectaction.py:371
182
 msgid ""
183
 "Flowblade does not open files that cannot be identified as media from file "
184
 "extensions.\n"
185
@@ -183,21 +183,21 @@
186
 "\n"
187
 msgstr ""
188
 
189
-#: projectaction.py:369
190
+#: projectaction.py:373
191
 msgid "Too many to list.\n"
192
 msgstr ""
193
 
194
-#: projectaction.py:374
195
+#: projectaction.py:378
196
 msgid ""
197
 "\n"
198
 "Add the correct extension to load a problem file."
199
 msgstr ""
200
 
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/es/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2024-08-12 13:54+0200\n"
8
 "Last-Translator: David Gámiz Jiménez <david.gamiz@gmail.com>\n"
9
 "Language-Team: David Gamiz Jimenez\n"
10
@@ -34,11 +34,11 @@
11
 msgid "5 min"
12
 msgstr "5 minutos"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr "¡La ubicación de la carpeta de datos XDG ha cambiado!"
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
@@ -51,7 +51,7 @@
25
 "porque el valor de la variable <b>Inicio de datos XDG</b> ha cambiado.\n"
26
 "\n"
27
 
28
-#: app.py:941
29
+#: app.py:947
30
 msgid ""
31
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
32
 "will continue to work,\n"
33
@@ -61,7 +61,7 @@
34
 "Los proyectos existentes con datos de proyecto guardados en el <b>Almacén de "
35
 "datos XDG predeterminado</b> seguirán funcionando.\n"
36
 
37
-#: app.py:942
38
+#: app.py:948
39
 msgid ""
40
 "but new projects will have data saved in the location specified by the new "
41
 "value <b>XDG Data Home</b> variable ."
42
@@ -71,67 +71,67 @@
43
 "proyectos tendrán datos guardados en la ubicación especificada por la nueva "
44
 "variable de valor <b>XDG Data Home</b>."
45
 
46
-#: app.py:1027
47
+#: app.py:1033
48
 msgid "Too small screen for this application."
49
 msgstr "La pantalla es demasiado pequeña para esta aplicación."
50
 
51
-#: app.py:1029
52
+#: app.py:1035
53
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
54
 msgstr ""
55
 "La dimensión de pantalla mínima para esta aplicación es de 1152 x 768.\n"
56
 
57
-#: app.py:1030
58
+#: app.py:1036
59
 msgid "Your screen dimensions are "
60
 msgstr "Las dimensiones de su pantalla son "
61
 
62
-#: app.py:1041
63
+#: app.py:1047
64
 msgid "Cannot launch application because XDG folders init error."
65
 msgstr "Cannot launch application because XDG folders init error."
66
 
67
-#: app.py:1052
68
+#: app.py:1058
69
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
70
 msgstr "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
71
 
72
-#: app.py:1053
73
+#: app.py:1059
74
 msgid "Your MLT version is: "
75
 msgstr "Versión de MLT: "
76
 
77
-#: app.py:1053
78
+#: app.py:1059
79
 msgid "Install MLT 6.18 or higher to run Flowblade."
80
 msgstr "Install MLT 6.18 or higher to run Flowblade."
81
 
82
-#: app.py:1127 projectaction.py:555 projectaction.py:757
83
+#: app.py:1133 projectaction.py:559 projectaction.py:761
84
 msgid "Project has not been saved previously"
85
 msgstr "El proyecto no se ha salvado antes"
86
 
87
-#: app.py:1128 projectaction.py:556 projectaction.py:758
88
+#: app.py:1134 projectaction.py:560 projectaction.py:762
89
 msgid "Save project with File -> Save As before closing."
90
 msgstr "Salvar el proyecto en un Archivo -> Salvar como antes de cerrar."
91
 
92
-#: projectaction.py:147
93
+#: projectaction.py:151
94
 msgid "Opening"
95
 msgstr "Abriendo"
96
 
97
-#: projectaction.py:226
98
+#: projectaction.py:230
99
 msgid "Media asset was missing!"
100
 msgstr "¡Falta un recurso multimedia!"
101
 
102
-#: projectaction.py:227
103
+#: projectaction.py:231
104
 msgid "Path of missing asset:"
105
 msgstr "Ruta del activo faltante:"
106
 
107
-#: projectaction.py:228
108
+#: projectaction.py:232
109
 msgid ""
110
 "Relative search for replacement file in sub folders of project file failed."
111
 msgstr ""
112
 "Error en la búsqueda relativa del archivo de reemplazo en las subcarpetas "
113
 "del archivo del proyecto."
114
 
115
-#: projectaction.py:229
116
+#: projectaction.py:233
117
 msgid "To load the project you will need to either:"
118
 msgstr "Para cargar el proyecto necesitarás:"
119
 
120
-#: projectaction.py:230
121
+#: projectaction.py:234
122
 msgid ""
123
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
124
 msgstr ""
125
@@ -140,24 +140,24 @@
126
 "herramienta 'Media Relinker' para volver a vincular los recursos multimedia "
127
 "a nuevos archivos, o"
128
 
129
-#: projectaction.py:231
130
+#: projectaction.py:235
131
 msgid "Place a file with the same exact name and path on the hard drive"
132
 msgstr ""
133
 "Coloque un archivo con exactamente el mismo nombre y ruta en el disco duro"
134
 
135
-#: projectaction.py:232
136
+#: projectaction.py:236
137
 msgid "Open project in Media Relinker tool"
138
 msgstr "Abrir proyecto en la herramienta Media Relinker"
139
 
140
-#: projectaction.py:251
141
+#: projectaction.py:255
142
 msgid "Profile with Description: '"
143
 msgstr "Perfil con descripción: '"
144
 
145
-#: projectaction.py:251
146
+#: projectaction.py:255
147
 msgid "' was not found on load!"
148
 msgstr "' ¡No se encontró en la carga!"
149
 
150
-#: projectaction.py:252
151
+#: projectaction.py:256
152
 msgid ""
153
 "It is possible to load the project by creating a User Profile with exactly "
154
 "the same Description\n"
155
@@ -167,24 +167,24 @@
156
 "la misma descripción\n"
157
 "que el perfil faltante. "
158
 
159
-#: projectaction.py:253
160
+#: projectaction.py:257
161
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
162
 msgstr ""
163
 "Los perfiles de usuario se pueden crear seleccionando 'Editar->Administrador "
164
 "de perfiles'."
165
 
166
-#: projectaction.py:360
167
+#: projectaction.py:364
168
 msgid "Opening animated .gif file was refused!"
169
 msgstr "¡Se rechazó la apertura del archivo .gif animado!"
170
 
171
-#: projectaction.py:361
172
+#: projectaction.py:365
173
 msgid ""
174
 "Flowblade does not support displaying animated GIF files as media objects.\n"
175
 msgstr ""
176
 "Flowblade no admite la visualización de archivos GIF animados como objetos "
177
 "multimedia.\n"
178
 
179
-#: projectaction.py:362
180
+#: projectaction.py:366
181
 msgid ""
182
 "A possible workaround is to render GIF into a frame sequence and\n"
183
 "open that as a media item."
184
@@ -194,11 +194,11 @@
185
 "convertir el GIF en una secuencia de cuadros y\n"
186
 "abrirlo como un elemento multimedia."
187
 
188
-#: projectaction.py:366
189
+#: projectaction.py:370
190
 msgid "Opening files with unknown  extensions refused!"
191
 msgstr "¡Se rechazó la apertura de archivos con extensiones desconocidas!"
192
 
193
-#: projectaction.py:367
194
+#: projectaction.py:371
195
 msgid ""
196
 "Flowblade does not open files that cannot be identified as media from file "
197
 "extensions.\n"
198
@@ -213,11 +213,11 @@
199
 "multimedia a partir de sus extensiones.\n"
200
 "Archivos problemáticos:\n"
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/fr/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -10,7 +10,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2020-12-14 14:52+0100\n"
8
 "Last-Translator: Jean-Paul Favier <favijep@laposte.net>\n"
9
 "Language-Team: French\n"
10
@@ -38,93 +38,93 @@
11
 msgid "5 min"
12
 msgstr ""
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Votre écran est trop petit pour cette application."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "La résolution minimum pour cet application est de 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Votre résolution actuelle est "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 "Ne peut pas lancer l'application à cause d'une erreur d'initialisation des "
61
 "dossiers XDG."
62
 
63
-#: app.py:1052
64
+#: app.py:1058
65
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
66
 msgstr "Flowblade version 2.6 ou supérieure demande MLT version 6.18"
67
 
68
-#: app.py:1053
69
+#: app.py:1059
70
 msgid "Your MLT version is: "
71
 msgstr "Version MLT : "
72
 
73
-#: app.py:1053
74
+#: app.py:1059
75
 msgid "Install MLT 6.18 or higher to run Flowblade."
76
 msgstr "Installez MLT 6.18 ou supérieure pour lancer Flowblade."
77
 
78
-#: app.py:1127 projectaction.py:555 projectaction.py:757
79
+#: app.py:1133 projectaction.py:559 projectaction.py:761
80
 msgid "Project has not been saved previously"
81
 msgstr "Le projet n'a jamais été sauvegardé"
82
 
83
-#: app.py:1128 projectaction.py:556 projectaction.py:758
84
+#: app.py:1134 projectaction.py:560 projectaction.py:762
85
 msgid "Save project with File -> Save As before closing."
86
 msgstr ""
87
 "Avant de fermer, sauvegardez le projet avec <u>Menu Fichier</u> -> "
88
 "Enregistrer sous."
89
 
90
-#: projectaction.py:147
91
+#: projectaction.py:151
92
 msgid "Opening"
93
 msgstr "Ouverture"
94
 
95
-#: projectaction.py:226
96
+#: projectaction.py:230
97
 msgid "Media asset was missing!"
98
 msgstr "Le média est absent !"
99
 
100
-#: projectaction.py:227
101
+#: projectaction.py:231
102
 msgid "Path of missing asset:"
103
 msgstr "Chemin du média manquant :"
104
 
105
-#: projectaction.py:228
106
+#: projectaction.py:232
107
 msgid ""
108
 "Relative search for replacement file in sub folders of project file failed."
109
 msgstr ""
110
 "Échec de la recherche du chemin relatif pour le fichier de remplacement dans "
111
 "les sous-dossiers du fichier projet."
112
 
113
-#: projectaction.py:229
114
+#: projectaction.py:233
115
 msgid "To load the project you will need to either:"
116
 msgstr "Pour charger le projet vous avez besoin soit :"
117
 
118
-#: projectaction.py:230
119
+#: projectaction.py:234
120
 msgid ""
121
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
122
 msgstr ""
123
@@ -132,54 +132,54 @@
124
 "médias manquants\n"
125
 "ou"
126
 
127
-#: projectaction.py:231
128
+#: projectaction.py:235
129
 msgid "Place a file with the same exact name and path on the hard drive"
130
 msgstr ""
131
 "De placer un fichier au nom et chemin identiques sur votre unité de stockage"
132
 
133
-#: projectaction.py:232
134
+#: projectaction.py:236
135
 msgid "Open project in Media Relinker tool"
136
 msgstr "Ouvrir le projet dans l'outil Remplacement de médias"
137
 
138
-#: projectaction.py:251
139
+#: projectaction.py:255
140
 msgid "Profile with Description: '"
141
 msgstr "Description : '"
142
 
143
-#: projectaction.py:251
144
+#: projectaction.py:255
145
 msgid "' was not found on load!"
146
 msgstr "'n'a pas été trouvé au chargement !"
147
 
148
-#: projectaction.py:252
149
+#: projectaction.py:256
150
 msgid ""
151
 "It is possible to load the project by creating a User Profile with exactly "
152
 "the same Description\n"
153
 "as the missing profile. "
154
 msgstr ""
155
 
156
-#: projectaction.py:253
157
+#: projectaction.py:257
158
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
159
 msgstr ""
160
 
161
-#: projectaction.py:360
162
+#: projectaction.py:364
163
 msgid "Opening animated .gif file was refused!"
164
 msgstr ""
165
 
166
-#: projectaction.py:361
167
+#: projectaction.py:365
168
 msgid ""
169
 "Flowblade does not support displaying animated GIF files as media objects.\n"
170
 msgstr ""
171
 
172
-#: projectaction.py:362
173
+#: projectaction.py:366
174
 msgid ""
175
 "A possible workaround is to render GIF into a frame sequence and\n"
176
 "open that as a media item."
177
 msgstr ""
178
 
179
-#: projectaction.py:366
180
+#: projectaction.py:370
181
 msgid "Opening files with unknown  extensions refused!"
182
 msgstr ""
183
 
184
-#: projectaction.py:367
185
+#: projectaction.py:371
186
 msgid ""
187
 "Flowblade does not open files that cannot be identified as media from file "
188
 "extensions.\n"
189
@@ -187,21 +187,21 @@
190
 "\n"
191
 msgstr ""
192
 
193
-#: projectaction.py:369
194
+#: projectaction.py:373
195
 msgid "Too many to list.\n"
196
 msgstr ""
197
 
198
-#: projectaction.py:374
199
+#: projectaction.py:378
200
 msgid ""
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/hu/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2017-03-24 08:40+0100\n"
8
 "Last-Translator: Péter Gábor <ptrg@freemail.hu>\n"
9
 "Language-Team: \n"
10
@@ -33,115 +33,115 @@
11
 msgid "5 min"
12
 msgstr "5 perc"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Túl kicsi a képernyő az alkalmazás számára."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "A minimális képernyőfelbontás ezen alkalmazás számára 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Az ön képernyőjének felbontása "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 #, fuzzy
69
 msgid "Your MLT version is: "
70
 msgstr "MLT változat: "
71
 
72
-#: app.py:1053
73
+#: app.py:1059
74
 msgid "Install MLT 6.18 or higher to run Flowblade."
75
 msgstr ""
76
 
77
-#: app.py:1127 projectaction.py:555 projectaction.py:757
78
+#: app.py:1133 projectaction.py:559 projectaction.py:761
79
 msgid "Project has not been saved previously"
80
 msgstr "A projekt korábban még nem volt mentve"
81
 
82
-#: app.py:1128 projectaction.py:556 projectaction.py:758
83
+#: app.py:1134 projectaction.py:560 projectaction.py:762
84
 msgid "Save project with File -> Save As before closing."
85
 msgstr ""
86
 "Mentse a projektet a Fájl -> Mentés másként menüpont használatával mielőtt "
87
 "bezárná."
88
 
89
-#: projectaction.py:147
90
+#: projectaction.py:151
91
 msgid "Opening"
92
 msgstr "Megnyitás"
93
 
94
-#: projectaction.py:226
95
+#: projectaction.py:230
96
 msgid "Media asset was missing!"
97
 msgstr "Hiányzó média összetevő!"
98
 
99
-#: projectaction.py:227
100
+#: projectaction.py:231
101
 msgid "Path of missing asset:"
102
 msgstr "A hiányzó média összetevő útvonala:"
103
 
104
-#: projectaction.py:228
105
+#: projectaction.py:232
106
 msgid ""
107
 "Relative search for replacement file in sub folders of project file failed."
108
 msgstr ""
109
 "A keresés a relatív útvonalakon a projekt almappáiban nem járt sikerrel."
110
 
111
-#: projectaction.py:229
112
+#: projectaction.py:233
113
 msgid "To load the project you will need to either:"
114
 msgstr "A projekt betöltéséhez szükség van a következők valamelyikére:"
115
 
116
-#: projectaction.py:230
117
+#: projectaction.py:234
118
 msgid ""
119
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
120
 msgstr ""
121
 "Projekt megnyitása a 'Média újracsatoló' eszközben a média összetevők "
122
 "újracsatolásához, vagy"
123
 
124
-#: projectaction.py:231
125
+#: projectaction.py:235
126
 msgid "Place a file with the same exact name and path on the hard drive"
127
 msgstr ""
128
 "Helyezzen el egy fájlt teljesen megegyező névvel és útvonallal a meghajtón"
129
 
130
-#: projectaction.py:232
131
+#: projectaction.py:236
132
 msgid "Open project in Media Relinker tool"
133
 msgstr "Projekt megnyitása a 'Média újracsatoló' eszközben"
134
 
135
-#: projectaction.py:251
136
+#: projectaction.py:255
137
 msgid "Profile with Description: '"
138
 msgstr "A profil ezzel a leírással: '"
139
 
140
-#: projectaction.py:251
141
+#: projectaction.py:255
142
 msgid "' was not found on load!"
143
 msgstr "' nem volt a megtalálható betöltés során!"
144
 
145
-#: projectaction.py:252
146
+#: projectaction.py:256
147
 msgid ""
148
 "It is possible to load the project by creating a User Profile with exactly "
149
 "the same Description\n"
150
@@ -151,32 +151,32 @@
151
 "tartalmazó\n"
152
 "felhasználói profil létrehozása után."
153
 
154
-#: projectaction.py:253
155
+#: projectaction.py:257
156
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
157
 msgstr ""
158
 "Felhasználói profilok létrehozhatók a 'Szerkesztés -> Profilkezelő' "
159
 "használatával."
160
 
161
-#: projectaction.py:360
162
+#: projectaction.py:364
163
 msgid "Opening animated .gif file was refused!"
164
 msgstr ""
165
 
166
-#: projectaction.py:361
167
+#: projectaction.py:365
168
 msgid ""
169
 "Flowblade does not support displaying animated GIF files as media objects.\n"
170
 msgstr ""
171
 
172
-#: projectaction.py:362
173
+#: projectaction.py:366
174
 msgid ""
175
 "A possible workaround is to render GIF into a frame sequence and\n"
176
 "open that as a media item."
177
 msgstr ""
178
 
179
-#: projectaction.py:366
180
+#: projectaction.py:370
181
 msgid "Opening files with unknown  extensions refused!"
182
 msgstr ""
183
 
184
-#: projectaction.py:367
185
+#: projectaction.py:371
186
 msgid ""
187
 "Flowblade does not open files that cannot be identified as media from file "
188
 "extensions.\n"
189
@@ -184,21 +184,21 @@
190
 "\n"
191
 msgstr ""
192
 
193
-#: projectaction.py:369
194
+#: projectaction.py:373
195
 msgid "Too many to list.\n"
196
 msgstr ""
197
 
198
-#: projectaction.py:374
199
+#: projectaction.py:378
200
 msgid ""
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/it/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -9,7 +9,7 @@
2
 msgstr ""
3
 "Project-Id-Version: Floblade Italian Translation 0.14\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2020-29-02 21:24+0200\n"
8
 "Last-Translator: Albano Battistella <albano_battistella@hotmail.com>\n"
9
 "Language-Team: Italiano\n"
10
@@ -36,112 +36,112 @@
11
 msgid "5 min"
12
 msgstr "5 min"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Lo schermo è troppo piccolo per questa applicazione."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "La risoluzione minima per questa applicazione è 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "La risoluzione corrente è "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 #, fuzzy
69
 msgid "Your MLT version is: "
70
 msgstr "Versione MLT: "
71
 
72
-#: app.py:1053
73
+#: app.py:1059
74
 msgid "Install MLT 6.18 or higher to run Flowblade."
75
 msgstr ""
76
 
77
-#: app.py:1127 projectaction.py:555 projectaction.py:757
78
+#: app.py:1133 projectaction.py:559 projectaction.py:761
79
 msgid "Project has not been saved previously"
80
 msgstr "Il progetto non è mai stato salvato"
81
 
82
-#: app.py:1128 projectaction.py:556 projectaction.py:758
83
+#: app.py:1134 projectaction.py:560 projectaction.py:762
84
 msgid "Save project with File -> Save As before closing."
85
 msgstr "Salva il progetto da File -> Salva con nome prima di chiudere."
86
 
87
-#: projectaction.py:147
88
+#: projectaction.py:151
89
 msgid "Opening"
90
 msgstr "Apertura"
91
 
92
-#: projectaction.py:226
93
+#: projectaction.py:230
94
 msgid "Media asset was missing!"
95
 msgstr "File multimediale mancante!"
96
 
97
-#: projectaction.py:227
98
+#: projectaction.py:231
99
 msgid "Path of missing asset:"
100
 msgstr "Percorso del file mancante:"
101
 
102
-#: projectaction.py:228
103
+#: projectaction.py:232
104
 msgid ""
105
 "Relative search for replacement file in sub folders of project file failed."
106
 msgstr ""
107
 "Non ho trovato nessun file sostitutivo nelle sottocartelle del progetto."
108
 
109
-#: projectaction.py:229
110
+#: projectaction.py:233
111
 msgid "To load the project you will need to either:"
112
 msgstr "Per caricare il progetto è necessario:"
113
 
114
-#: projectaction.py:230
115
+#: projectaction.py:234
116
 msgid ""
117
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
118
 msgstr ""
119
 "Aprire il progetto in 'Media Relinker' per ricreare i collegamenti ai file "
120
 "multimediali, oppure"
121
 
122
-#: projectaction.py:231
123
+#: projectaction.py:235
124
 msgid "Place a file with the same exact name and path on the hard drive"
125
 msgstr "Creare un file con lo stesso nome e percorso nel disco fisso"
126
 
127
-#: projectaction.py:232
128
+#: projectaction.py:236
129
 msgid "Open project in Media Relinker tool"
130
 msgstr "Apri il progetto con Media Relinker"
131
 
132
-#: projectaction.py:251
133
+#: projectaction.py:255
134
 msgid "Profile with Description: '"
135
 msgstr "Descrizione: '"
136
 
137
-#: projectaction.py:251
138
+#: projectaction.py:255
139
 msgid "' was not found on load!"
140
 msgstr "' non è stato trovato!"
141
 
142
-#: projectaction.py:252
143
+#: projectaction.py:256
144
 msgid ""
145
 "It is possible to load the project by creating a User Profile with exactly "
146
 "the same Description\n"
147
@@ -151,31 +151,31 @@
148
 "la stessa descrizione\n"
149
 "del profilo mancante. "
150
 
151
-#: projectaction.py:253
152
+#: projectaction.py:257
153
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
154
 msgstr ""
155
 "I profili utente possono essere creati da 'Modifica->Gestione Profili'."
156
 
157
-#: projectaction.py:360
158
+#: projectaction.py:364
159
 msgid "Opening animated .gif file was refused!"
160
 msgstr ""
161
 
162
-#: projectaction.py:361
163
+#: projectaction.py:365
164
 msgid ""
165
 "Flowblade does not support displaying animated GIF files as media objects.\n"
166
 msgstr ""
167
 
168
-#: projectaction.py:362
169
+#: projectaction.py:366
170
 msgid ""
171
 "A possible workaround is to render GIF into a frame sequence and\n"
172
 "open that as a media item."
173
 msgstr ""
174
 
175
-#: projectaction.py:366
176
+#: projectaction.py:370
177
 msgid "Opening files with unknown  extensions refused!"
178
 msgstr ""
179
 
180
-#: projectaction.py:367
181
+#: projectaction.py:371
182
 msgid ""
183
 "Flowblade does not open files that cannot be identified as media from file "
184
 "extensions.\n"
185
@@ -183,21 +183,21 @@
186
 "\n"
187
 msgstr ""
188
 
189
-#: projectaction.py:369
190
+#: projectaction.py:373
191
 msgid "Too many to list.\n"
192
 msgstr ""
193
 
194
-#: projectaction.py:374
195
+#: projectaction.py:378
196
 msgid ""
197
 "\n"
198
 "Add the correct extension to load a problem file."
199
 msgstr ""
200
 
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/pl/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -6,7 +6,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2024-08-27 10:29+0200\n"
8
 "Last-Translator: Stanislaw Polak <polak@agh.edu.pl>\n"
9
 "Language-Team: Polish\n"
10
@@ -34,11 +34,11 @@
11
 msgid "5 min"
12
 msgstr ""
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr "Zmieniła się lokalizacja folderu danych XDG!"
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
@@ -47,7 +47,7 @@
25
 "Lokalizacja <b>Domyślnego magazynu danych XDG</b> uległa zmianie, ponieważ "
26
 "zmieniła się wartość zmiennej <b>XDG Data Home</b>.\n"
27
 
28
-#: app.py:941
29
+#: app.py:947
30
 msgid ""
31
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
32
 "will continue to work,\n"
33
@@ -55,7 +55,7 @@
34
 "Istniejące projekty z danymi projektu zapisanymi w <b>Domyślnym magazynie "
35
 "danych XDG</b> będą nadal działać,\n"
36
 
37
-#: app.py:942
38
+#: app.py:948
39
 msgid ""
40
 "but new projects will have data saved in the location specified by the new "
41
 "value <b>XDG Data Home</b> variable ."
42
@@ -63,92 +63,92 @@
43
 "ale nowe projekty będą miały dane zapisane w lokalizacji określonej przez "
44
 "nową wartość zmiennej <b>XDG Data Home</b>."
45
 
46
-#: app.py:1027
47
+#: app.py:1033
48
 msgid "Too small screen for this application."
49
 msgstr "Zbyt mały ekran dla tej aplikacji."
50
 
51
-#: app.py:1029
52
+#: app.py:1035
53
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
54
 msgstr "Minimalne wymiary ekranu dla tej aplikacji to 1152 x 768.\n"
55
 
56
-#: app.py:1030
57
+#: app.py:1036
58
 msgid "Your screen dimensions are "
59
 msgstr "Wymiary twojego ekranu to "
60
 
61
-#: app.py:1041
62
+#: app.py:1047
63
 msgid "Cannot launch application because XDG folders init error."
64
 msgstr ""
65
 "Nie można uruchomić aplikacji, ponieważ wystąpił błąd inicjalizacji folderów "
66
 "XDG."
67
 
68
-#: app.py:1052
69
+#: app.py:1058
70
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
71
 msgstr ""
72
 "Flowblade w wersji 2.6 (lub nowszej) wymaga do działania MLT w wersji 6.18"
73
 
74
-#: app.py:1053
75
+#: app.py:1059
76
 msgid "Your MLT version is: "
77
 msgstr "Twoja wersja MLT to: "
78
 
79
-#: app.py:1053
80
+#: app.py:1059
81
 msgid "Install MLT 6.18 or higher to run Flowblade."
82
 msgstr "Zainstaluj MLT 6.18 lub nowszy, aby uruchomić Flowblade."
83
 
84
-#: app.py:1127 projectaction.py:555 projectaction.py:757
85
+#: app.py:1133 projectaction.py:559 projectaction.py:761
86
 msgid "Project has not been saved previously"
87
 msgstr "Projekt nie został wcześniej zapisany"
88
 
89
-#: app.py:1128 projectaction.py:556 projectaction.py:758
90
+#: app.py:1134 projectaction.py:560 projectaction.py:762
91
 msgid "Save project with File -> Save As before closing."
92
 msgstr "Przed zamknięciem, zapisz projekt za pomocą Plik -> Zapisz jako."
93
 
94
-#: projectaction.py:147
95
+#: projectaction.py:151
96
 msgid "Opening"
97
 msgstr "Otwieranie"
98
 
99
-#: projectaction.py:226
100
+#: projectaction.py:230
101
 msgid "Media asset was missing!"
102
 msgstr "Brak zasobów multimedialnych!"
103
 
104
-#: projectaction.py:227
105
+#: projectaction.py:231
106
 msgid "Path of missing asset:"
107
 msgstr "Ścieżka brakującego zasobu:"
108
 
109
-#: projectaction.py:228
110
+#: projectaction.py:232
111
 msgid ""
112
 "Relative search for replacement file in sub folders of project file failed."
113
 msgstr ""
114
 "Względne wyszukiwanie plików zastępczych w podfolderach pliku projektu nie "
115
 "powiodło się."
116
 
117
-#: projectaction.py:229
118
+#: projectaction.py:233
119
 msgid "To load the project you will need to either:"
120
 msgstr "Aby załadować projekt, musisz również:"
121
 
122
-#: projectaction.py:230
123
+#: projectaction.py:234
124
 msgid ""
125
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
126
 msgstr ""
127
 "Otwórz projekt w narzędziu 'Relinker Multimediów', aby powiązać zasoby "
128
 "multimedialne z nowymi plikami, lub"
129
 
130
-#: projectaction.py:231
131
+#: projectaction.py:235
132
 msgid "Place a file with the same exact name and path on the hard drive"
133
 msgstr "Umieść plik o tej samej nazwie i ścieżce na dysku twardym"
134
 
135
-#: projectaction.py:232
136
+#: projectaction.py:236
137
 msgid "Open project in Media Relinker tool"
138
 msgstr "Otwórz projekt w narzędziu Relinker Multimediów"
139
 
140
-#: projectaction.py:251
141
+#: projectaction.py:255
142
 msgid "Profile with Description: '"
143
 msgstr "Profil z Opisem: '"
144
 
145
-#: projectaction.py:251
146
+#: projectaction.py:255
147
 msgid "' was not found on load!"
148
 msgstr "' nie został znaleziony podczas ładowania!"
149
 
150
-#: projectaction.py:252
151
+#: projectaction.py:256
152
 msgid ""
153
 "It is possible to load the project by creating a User Profile with exactly "
154
 "the same Description\n"
155
@@ -158,23 +158,23 @@
156
 "dokładnie tym samym opisem \n"
157
 "jak w przypadku brakującego profilu. "
158
 
159
-#: projectaction.py:253
160
+#: projectaction.py:257
161
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
162
 msgstr ""
163
 "Profile Użytkowników można tworzyć, wybierając 'Edytuj -> Manager Profili'."
164
 
165
-#: projectaction.py:360
166
+#: projectaction.py:364
167
 msgid "Opening animated .gif file was refused!"
168
 msgstr "Odmówiono otwarcia animowanego pliku .gif!"
169
 
170
-#: projectaction.py:361
171
+#: projectaction.py:365
172
 msgid ""
173
 "Flowblade does not support displaying animated GIF files as media objects.\n"
174
 msgstr ""
175
 "Flowblade nie obsługuje wyświetlania animowanych plików GIF jako obiektów "
176
 "multimedialnych.\n"
177
 
178
-#: projectaction.py:362
179
+#: projectaction.py:366
180
 msgid ""
181
 "A possible workaround is to render GIF into a frame sequence and\n"
182
 "open that as a media item."
183
@@ -182,11 +182,11 @@
184
 "Możliwym obejściem jest wyrenderowanie GIF jako sekwencji klatek i\n"
185
 "otwarcie jej jako elementu multimedialnego."
186
 
187
-#: projectaction.py:366
188
+#: projectaction.py:370
189
 msgid "Opening files with unknown  extensions refused!"
190
 msgstr "Odmowa otwarcia plików o nieznanych rozszerzeniach!"
191
 
192
-#: projectaction.py:367
193
+#: projectaction.py:371
194
 msgid ""
195
 "Flowblade does not open files that cannot be identified as media from file "
196
 "extensions.\n"
197
@@ -198,11 +198,11 @@
198
 "Problematyczne pliki:\n"
199
 "\n"
200
 
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/ru/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: Flowblade\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2023-06-20 15:06+0300\n"
8
 "Last-Translator: Смольянинов Николай <smolianinow.colya2016@yandex.ru>\n"
9
 "Language-Team: ru\n"
10
@@ -35,112 +35,112 @@
11
 msgid "5 min"
12
 msgstr "каждые 5 минут"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Недостаточное разрешение экрана."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "Минимальное разрешение экрана должно быть не ниже 1152 х 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Разрешение вашего экрана "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr "Не удалось запустить приложение из-за ошибки инициализации папок XDG."
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr "Для запуска Flowblade 2.6 (или выше) требуется версия MLT не ниже 6.18"
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 msgid "Your MLT version is: "
69
 msgstr "Ваша версия MLT: "
70
 
71
-#: app.py:1053
72
+#: app.py:1059
73
 msgid "Install MLT 6.18 or higher to run Flowblade."
74
 msgstr "Установите MLT 6.18 или выше для запуска Flowblade."
75
 
76
-#: app.py:1127 projectaction.py:555 projectaction.py:757
77
+#: app.py:1133 projectaction.py:559 projectaction.py:761
78
 msgid "Project has not been saved previously"
79
 msgstr "Проект не был сохранён"
80
 
81
-#: app.py:1128 projectaction.py:556 projectaction.py:758
82
+#: app.py:1134 projectaction.py:560 projectaction.py:762
83
 msgid "Save project with File -> Save As before closing."
84
 msgstr "Сохраните проект перед закрытием (Файл ⇨ Сохранить как...)."
85
 
86
-#: projectaction.py:147
87
+#: projectaction.py:151
88
 msgid "Opening"
89
 msgstr "Открытие"
90
 
91
-#: projectaction.py:226
92
+#: projectaction.py:230
93
 msgid "Media asset was missing!"
94
 msgstr "Медиафайлы потеряны!"
95
 
96
-#: projectaction.py:227
97
+#: projectaction.py:231
98
 msgid "Path of missing asset:"
99
 msgstr "Путь к потерянному файлу:"
100
 
101
-#: projectaction.py:228
102
+#: projectaction.py:232
103
 msgid ""
104
 "Relative search for replacement file in sub folders of project file failed."
105
 msgstr ""
106
 "Не удалось найти медиафайл по относительному пути во вложенных папках "
107
 "проекта для его замены."
108
 
109
-#: projectaction.py:229
110
+#: projectaction.py:233
111
 msgid "To load the project you will need to either:"
112
 msgstr "Для загрузки проекта выполните одно из действий:"
113
 
114
-#: projectaction.py:230
115
+#: projectaction.py:234
116
 msgid ""
117
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
118
 msgstr ""
119
 "Откройте проект в «Перелинковщике медиа», чтобы повторно связать пути с "
120
 "новыми файлами"
121
 
122
-#: projectaction.py:231
123
+#: projectaction.py:235
124
 msgid "Place a file with the same exact name and path on the hard drive"
125
 msgstr "Расположите файл по тому же пути и с тем же именем"
126
 
127
-#: projectaction.py:232
128
+#: projectaction.py:236
129
 msgid "Open project in Media Relinker tool"
130
 msgstr "Открыть проект в Перелинковщике медиа"
131
 
132
-#: projectaction.py:251
133
+#: projectaction.py:255
134
 msgid "Profile with Description: '"
135
 msgstr "Профиль с описанием: '"
136
 
137
-#: projectaction.py:251
138
+#: projectaction.py:255
139
 msgid "' was not found on load!"
140
 msgstr "' не найден при загрузке!"
141
 
142
-#: projectaction.py:252
143
+#: projectaction.py:256
144
 msgid ""
145
 "It is possible to load the project by creating a User Profile with exactly "
146
 "the same Description\n"
147
@@ -150,23 +150,23 @@
148
 "были\n"
149
 "в потерянном профиле. "
150
 
151
-#: projectaction.py:253
152
+#: projectaction.py:257
153
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
154
 msgstr ""
155
 "Пользовательские профили создаются через меню «Правка ⇨ Менеджер профилей»."
156
 
157
-#: projectaction.py:360
158
+#: projectaction.py:364
159
 msgid "Opening animated .gif file was refused!"
160
 msgstr "Открытие анимированного файла .gif невозможно!"
161
 
162
-#: projectaction.py:361
163
+#: projectaction.py:365
164
 msgid ""
165
 "Flowblade does not support displaying animated GIF files as media objects.\n"
166
 msgstr ""
167
 "Flowblade не поддерживает отображение анимированных файлов GIF\n"
168
 "в качестве медиаобъектов.\n"
169
 
170
-#: projectaction.py:362
171
+#: projectaction.py:366
172
 msgid ""
173
 "A possible workaround is to render GIF into a frame sequence and\n"
174
 "open that as a media item."
175
@@ -174,11 +174,11 @@
176
 "Возможный обходной путь — это преобразование GIF в видеоряд\n"
177
 "и его открытие в качестве мультимедийного элемента."
178
 
179
-#: projectaction.py:366
180
+#: projectaction.py:370
181
 msgid "Opening files with unknown  extensions refused!"
182
 msgstr "Отказано в открытии файлов с неизвестными расширениями!"
183
 
184
-#: projectaction.py:367
185
+#: projectaction.py:371
186
 msgid ""
187
 "Flowblade does not open files that cannot be identified as media from file "
188
 "extensions.\n"
189
@@ -190,11 +190,11 @@
190
 "Проблемные файлы:\n"
191
 "\n"
192
 
193
-#: projectaction.py:369
194
+#: projectaction.py:373
195
 msgid "Too many to list.\n"
196
 msgstr "Слишком большое количество для перечисления.\n"
197
 
198
-#: projectaction.py:374
199
+#: projectaction.py:378
200
 msgid ""
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/tr/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/tr/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/tr/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/tr/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2021-04-04 15:07+0300\n"
8
 "Last-Translator: \n"
9
 "Language-Team: Türkçe\n"
10
@@ -34,113 +34,113 @@
11
 msgid "5 min"
12
 msgstr "5 dakika"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Bu uygulama için çok küçük bir ekran."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "Bu uygulama için Minimum ekran boyutları şunlardır 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Ekran boyutlarınız aşağıdaki gibidir "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr "XDG klasörleri başlangıç hatası nedeniyle uygulama başlatılamıyor."
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 "Flowblade sürüm 2.6 (veya üstü) çalıştırmak için MLT sürüm 6.18 gerektirir"
66
 
67
-#: app.py:1053
68
+#: app.py:1059
69
 msgid "Your MLT version is: "
70
 msgstr "MLT sürümünüz şu şekildedir: "
71
 
72
-#: app.py:1053
73
+#: app.py:1059
74
 msgid "Install MLT 6.18 or higher to run Flowblade."
75
 msgstr "Flowblade çalıştırmak için MLT 6.18 veya daha yükseğini yükleyin."
76
 
77
-#: app.py:1127 projectaction.py:555 projectaction.py:757
78
+#: app.py:1133 projectaction.py:559 projectaction.py:761
79
 msgid "Project has not been saved previously"
80
 msgstr "Proje daha önce kaydedilmedi"
81
 
82
-#: app.py:1128 projectaction.py:556 projectaction.py:758
83
+#: app.py:1134 projectaction.py:560 projectaction.py:762
84
 msgid "Save project with File -> Save As before closing."
85
 msgstr "Projeyi dosyaya kaydedin -> kapatmadan önce Farklı Kaydet."
86
 
87
-#: projectaction.py:147
88
+#: projectaction.py:151
89
 msgid "Opening"
90
 msgstr "Açılan"
91
 
92
-#: projectaction.py:226
93
+#: projectaction.py:230
94
 msgid "Media asset was missing!"
95
 msgstr "Ortam varlığı kayıptı!"
96
 
97
-#: projectaction.py:227
98
+#: projectaction.py:231
99
 msgid "Path of missing asset:"
100
 msgstr "Eksik varlığın yolu:"
101
 
102
-#: projectaction.py:228
103
+#: projectaction.py:232
104
 msgid ""
105
 "Relative search for replacement file in sub folders of project file failed."
106
 msgstr ""
107
 "Proje dosyasının alt klasörlerinde yedek dosya için ilgili arama başarısız "
108
 "oldu."
109
 
110
-#: projectaction.py:229
111
+#: projectaction.py:233
112
 msgid "To load the project you will need to either:"
113
 msgstr "Projeyi yüklemek için şunlardan birine ihtiyacınız olacak:"
114
 
115
-#: projectaction.py:230
116
+#: projectaction.py:234
117
 msgid ""
118
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
119
 msgstr ""
120
 "Medya varlıklarını yeni dosyalara yeniden bağlamak için 'Ortam Bağlama' "
121
 "aracında projeyi açın veya"
122
 
123
-#: projectaction.py:231
124
+#: projectaction.py:235
125
 msgid "Place a file with the same exact name and path on the hard drive"
126
 msgstr "Sabit sürücüye aynı ad ve yola sahip bir dosya yerleştirin"
127
 
128
-#: projectaction.py:232
129
+#: projectaction.py:236
130
 msgid "Open project in Media Relinker tool"
131
 msgstr "Projeyi Ortam Bağlama aracında aç"
132
 
133
-#: projectaction.py:251
134
+#: projectaction.py:255
135
 msgid "Profile with Description: '"
136
 msgstr "Profil ile birlikte Tanımı: '"
137
 
138
-#: projectaction.py:251
139
+#: projectaction.py:255
140
 msgid "' was not found on load!"
141
 msgstr "' yük bulunamadı!"
142
 
143
-#: projectaction.py:252
144
+#: projectaction.py:256
145
 msgid ""
146
 "It is possible to load the project by creating a User Profile with exactly "
147
 "the same Description\n"
148
@@ -150,23 +150,23 @@
149
 " sahip bir kullanıcı profili oluşturarak projeyi yüklemek mümkün\n"
150
 "kayıp profil olarak. "
151
 
152
-#: projectaction.py:253
153
+#: projectaction.py:257
154
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
155
 msgstr ""
156
 "Kullanıcı Profilleri 'Düzenle->Profil Yöneticisi' seçerek oluşturulabilir."
157
 
158
-#: projectaction.py:360
159
+#: projectaction.py:364
160
 msgid "Opening animated .gif file was refused!"
161
 msgstr "Açılış animasyonlu .gif dosyası reddedildi!"
162
 
163
-#: projectaction.py:361
164
+#: projectaction.py:365
165
 msgid ""
166
 "Flowblade does not support displaying animated GIF files as media objects.\n"
167
 msgstr ""
168
 "Flowblade animasyonlu GIF dosyalarını ortam nesneleri olarak görüntülemeyi "
169
 "desteklemiyor.\n"
170
 
171
-#: projectaction.py:362
172
+#: projectaction.py:366
173
 msgid ""
174
 "A possible workaround is to render GIF into a frame sequence and\n"
175
 "open that as a media item."
176
@@ -174,11 +174,11 @@
177
 "Olası bir geçici çözüm, GIF ortamını bir çerçeve dizisine dönüştürün ve\n"
178
 "bunu bir ortam öğesi olarak açın."
179
 
180
-#: projectaction.py:366
181
+#: projectaction.py:370
182
 msgid "Opening files with unknown  extensions refused!"
183
 msgstr ""
184
 
185
-#: projectaction.py:367
186
+#: projectaction.py:371
187
 msgid ""
188
 "Flowblade does not open files that cannot be identified as media from file "
189
 "extensions.\n"
190
@@ -186,21 +186,21 @@
191
 "\n"
192
 msgstr ""
193
 
194
-#: projectaction.py:369
195
+#: projectaction.py:373
196
 msgid "Too many to list.\n"
197
 msgstr ""
198
 
199
-#: projectaction.py:374
200
+#: projectaction.py:378
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/uk/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/uk/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/uk/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/uk/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -8,7 +8,7 @@
2
 msgstr ""
3
 "Project-Id-Version: \n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2021-01-15 21:19+0300\n"
8
 "Last-Translator: Микита Бесчастний <micitabesh1992@rambler.ua>\n"
9
 "Language-Team: \n"
10
@@ -35,111 +35,111 @@
11
 msgid "5 min"
12
 msgstr "5 мін"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "Занадто маленький екран для цього додатка."
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "Мінімальні розміри екрана для цієї програми - 1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "Ваші розміри екрана "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 "Програму не можна запустити, оскільки сталася помилка ініціалізації папки "
61
 "XDG."
62
 
63
-#: app.py:1052
64
+#: app.py:1058
65
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
66
 msgstr "Flowblade версії 2.6 (або пізнішої) вимагає запуску MLT версії 6.18"
67
 
68
-#: app.py:1053
69
+#: app.py:1059
70
 msgid "Your MLT version is: "
71
 msgstr "Ваша версія MLT: "
72
 
73
-#: app.py:1053
74
+#: app.py:1059
75
 msgid "Install MLT 6.18 or higher to run Flowblade."
76
 msgstr "Встановіть MLT 6.18 або вище для запуску Flowblade."
77
 
78
-#: app.py:1127 projectaction.py:555 projectaction.py:757
79
+#: app.py:1133 projectaction.py:559 projectaction.py:761
80
 msgid "Project has not been saved previously"
81
 msgstr "Проект раніше не зберігався"
82
 
83
-#: app.py:1128 projectaction.py:556 projectaction.py:758
84
+#: app.py:1134 projectaction.py:560 projectaction.py:762
85
 msgid "Save project with File -> Save As before closing."
86
 msgstr "Перед закриттям збережіть проект через Файл -> Зберегти як."
87
 
88
-#: projectaction.py:147
89
+#: projectaction.py:151
90
 msgid "Opening"
91
 msgstr "Відкривається"
92
 
93
-#: projectaction.py:226
94
+#: projectaction.py:230
95
 msgid "Media asset was missing!"
96
 msgstr "Медіа-ресурс відсутній!"
97
 
98
-#: projectaction.py:227
99
+#: projectaction.py:231
100
 msgid "Path of missing asset:"
101
 msgstr "Шлях відсутнього ресурсу:"
102
 
103
-#: projectaction.py:228
104
+#: projectaction.py:232
105
 msgid ""
106
 "Relative search for replacement file in sub folders of project file failed."
107
 msgstr "Помилка відносного пошуку файлів заміни у підпапках файлу проекту."
108
 
109
-#: projectaction.py:229
110
+#: projectaction.py:233
111
 msgid "To load the project you will need to either:"
112
 msgstr "Для завантаження проекту вам потрібно:"
113
 
114
-#: projectaction.py:230
115
+#: projectaction.py:234
116
 msgid ""
117
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
118
 msgstr ""
119
 "Відкрийте проект у Media Relinker, щоб пов’язати медіа з новими файлами, або"
120
 
121
-#: projectaction.py:231
122
+#: projectaction.py:235
123
 msgid "Place a file with the same exact name and path on the hard drive"
124
 msgstr "Помістіть файл з тим самим іменем та шляхом на жорсткий диск"
125
 
126
-#: projectaction.py:232
127
+#: projectaction.py:236
128
 msgid "Open project in Media Relinker tool"
129
 msgstr "Відкрийте проект у Media Relinker"
130
 
131
-#: projectaction.py:251
132
+#: projectaction.py:255
133
 msgid "Profile with Description: '"
134
 msgstr "Профіль із описом: '"
135
 
136
-#: projectaction.py:251
137
+#: projectaction.py:255
138
 msgid "' was not found on load!"
139
 msgstr "'не знайдено під час завантаження!"
140
 
141
-#: projectaction.py:252
142
+#: projectaction.py:256
143
 msgid ""
144
 "It is possible to load the project by creating a User Profile with exactly "
145
 "the same Description\n"
146
@@ -149,32 +149,32 @@
147
 "описом\n"
148
 "що стосується відсутнього профілю. "
149
 
150
-#: projectaction.py:253
151
+#: projectaction.py:257
152
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
153
 msgstr ""
154
 "Профілі користувачів можна створити, вибравши \"Редагувати -> Менеджер "
155
 "профілів\"."
156
 
157
-#: projectaction.py:360
158
+#: projectaction.py:364
159
 msgid "Opening animated .gif file was refused!"
160
 msgstr ""
161
 
162
-#: projectaction.py:361
163
+#: projectaction.py:365
164
 msgid ""
165
 "Flowblade does not support displaying animated GIF files as media objects.\n"
166
 msgstr ""
167
 
168
-#: projectaction.py:362
169
+#: projectaction.py:366
170
 msgid ""
171
 "A possible workaround is to render GIF into a frame sequence and\n"
172
 "open that as a media item."
173
 msgstr ""
174
 
175
-#: projectaction.py:366
176
+#: projectaction.py:370
177
 msgid "Opening files with unknown  extensions refused!"
178
 msgstr ""
179
 
180
-#: projectaction.py:367
181
+#: projectaction.py:371
182
 msgid ""
183
 "Flowblade does not open files that cannot be identified as media from file "
184
 "extensions.\n"
185
@@ -182,21 +182,21 @@
186
 "\n"
187
 msgstr ""
188
 
189
-#: projectaction.py:369
190
+#: projectaction.py:373
191
 msgid "Too many to list.\n"
192
 msgstr ""
193
 
194
-#: projectaction.py:374
195
+#: projectaction.py:378
196
 msgid ""
197
 "\n"
198
 "Add the correct extension to load a problem file."
199
 msgstr ""
200
 
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/zh_CN/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2017-04-15 18:47+0800\n"
8
 "Last-Translator: wu <laowudebox@126.com>\n"
9
 "Language-Team: Language LANGUAGE\n"
10
@@ -32,109 +32,109 @@
11
 msgid "5 min"
12
 msgstr "5 min"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "对于这个应用,画面太小。"
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "对于这个应用,最小画面尺寸是1152 x 768.\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "你的画面尺寸是 "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 #, fuzzy
69
 msgid "Your MLT version is: "
70
 msgstr "MLT 版本 "
71
 
72
-#: app.py:1053
73
+#: app.py:1059
74
 msgid "Install MLT 6.18 or higher to run Flowblade."
75
 msgstr ""
76
 
77
-#: app.py:1127 projectaction.py:555 projectaction.py:757
78
+#: app.py:1133 projectaction.py:559 projectaction.py:761
79
 msgid "Project has not been saved previously"
80
 msgstr "项目还未被保存过"
81
 
82
-#: app.py:1128 projectaction.py:556 projectaction.py:758
83
+#: app.py:1134 projectaction.py:560 projectaction.py:762
84
 msgid "Save project with File -> Save As before closing."
85
 msgstr "在关闭之前通过菜单 文件 -> 另存为 保存项目"
86
 
87
-#: projectaction.py:147
88
+#: projectaction.py:151
89
 msgid "Opening"
90
 msgstr "正在打开"
91
 
92
-#: projectaction.py:226
93
+#: projectaction.py:230
94
 msgid "Media asset was missing!"
95
 msgstr "有用的媒体已丢失"
96
 
97
-#: projectaction.py:227
98
+#: projectaction.py:231
99
 msgid "Path of missing asset:"
100
 msgstr "已丢失的有用东西的路径"
101
 
102
-#: projectaction.py:228
103
+#: projectaction.py:232
104
 msgid ""
105
 "Relative search for replacement file in sub folders of project file failed."
106
 msgstr "在失败项目文件的子文件夹中搜索相关代替文件"
107
 
108
-#: projectaction.py:229
109
+#: projectaction.py:233
110
 msgid "To load the project you will need to either:"
111
 msgstr "加载你将会需要的另一个项目"
112
 
113
-#: projectaction.py:230
114
+#: projectaction.py:234
115
 msgid ""
116
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
117
 msgstr "在媒体重新链接器工具中打开项目以便重新连接相关媒体到新文件,或者"
118
 
119
-#: projectaction.py:231
120
+#: projectaction.py:235
121
 msgid "Place a file with the same exact name and path on the hard drive"
122
 msgstr "放置一个名字和路径完全相同的的文件到硬盘上"
123
 
124
-#: projectaction.py:232
125
+#: projectaction.py:236
126
 msgid "Open project in Media Relinker tool"
127
 msgstr "在媒体重新链接器工具中打开项目"
128
 
129
-#: projectaction.py:251
130
+#: projectaction.py:255
131
 msgid "Profile with Description: '"
132
 msgstr "带有描述的配置文件"
133
 
134
-#: projectaction.py:251
135
+#: projectaction.py:255
136
 msgid "' was not found on load!"
137
 msgstr "未找到加载内容"
138
 
139
-#: projectaction.py:252
140
+#: projectaction.py:256
141
 msgid ""
142
 "It is possible to load the project by creating a User Profile with exactly "
143
 "the same Description\n"
144
@@ -143,30 +143,30 @@
145
 "通过准确地创建一个用户配置文件来加载项目相同的描述\n"
146
 "作为已丢失的配置文件。 "
147
 
148
-#: projectaction.py:253
149
+#: projectaction.py:257
150
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
151
 msgstr "用户配置文件可以通过选择“配置文件管理器”来创建"
152
 
153
-#: projectaction.py:360
154
+#: projectaction.py:364
155
 msgid "Opening animated .gif file was refused!"
156
 msgstr ""
157
 
158
-#: projectaction.py:361
159
+#: projectaction.py:365
160
 msgid ""
161
 "Flowblade does not support displaying animated GIF files as media objects.\n"
162
 msgstr ""
163
 
164
-#: projectaction.py:362
165
+#: projectaction.py:366
166
 msgid ""
167
 "A possible workaround is to render GIF into a frame sequence and\n"
168
 "open that as a media item."
169
 msgstr ""
170
 
171
-#: projectaction.py:366
172
+#: projectaction.py:370
173
 msgid "Opening files with unknown  extensions refused!"
174
 msgstr ""
175
 
176
-#: projectaction.py:367
177
+#: projectaction.py:371
178
 msgid ""
179
 "Flowblade does not open files that cannot be identified as media from file "
180
 "extensions.\n"
181
@@ -174,21 +174,21 @@
182
 "\n"
183
 msgstr ""
184
 
185
-#: projectaction.py:369
186
+#: projectaction.py:373
187
 msgid "Too many to list.\n"
188
 msgstr ""
189
 
190
-#: projectaction.py:374
191
+#: projectaction.py:378
192
 msgid ""
193
 "\n"
194
 "Add the correct extension to load a problem file."
195
 msgstr ""
196
 
197
-#: projectaction.py:445
198
+#: projectaction.py:449
199
 msgid "Media files already present in project were opened!"
200
 msgstr "媒体文件已经发送到被打开的项目"
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/zh_TW/LC_MESSAGES/flowblade.mo -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/zh_TW/LC_MESSAGES/flowblade.mo Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/locale/zh_TW/LC_MESSAGES/flowblade.po -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/locale/zh_TW/LC_MESSAGES/flowblade.po Changed
201
 
1
@@ -7,7 +7,7 @@
2
 msgstr ""
3
 "Project-Id-Version: PACKAGE VERSION\n"
4
 "Report-Msgid-Bugs-To: \n"
5
-"POT-Creation-Date: 2024-12-18 10:56+0200\n"
6
+"POT-Creation-Date: 2025-03-24 15:26+0200\n"
7
 "PO-Revision-Date: 2018-12-31 10:20+0800\n"
8
 "Last-Translator: Steve Nian <sdnian@gmail.com>\n"
9
 "Language-Team: Chinese (traditional)\n"
10
@@ -32,109 +32,109 @@
11
 msgid "5 min"
12
 msgstr "5 分鐘"
13
 
14
-#: app.py:939
15
+#: app.py:945
16
 msgid "XDG Data folder location has changed!"
17
 msgstr ""
18
 
19
-#: app.py:940
20
+#: app.py:946
21
 msgid ""
22
 "Location of <b>Default XDG Data Store</b> has changed because value of "
23
 "<b>XDG Data Home</b> variable has changed.\n"
24
 "\n"
25
 msgstr ""
26
 
27
-#: app.py:941
28
+#: app.py:947
29
 msgid ""
30
 "Existing Projects with project data saved in <b>Default XDG Data Store</b> "
31
 "will continue to work,\n"
32
 msgstr ""
33
 
34
-#: app.py:942
35
+#: app.py:948
36
 msgid ""
37
 "but new projects will have data saved in the location specified by the new "
38
 "value <b>XDG Data Home</b> variable ."
39
 msgstr ""
40
 
41
-#: app.py:1027
42
+#: app.py:1033
43
 msgid "Too small screen for this application."
44
 msgstr "畫面太小無法執行此應用程式"
45
 
46
-#: app.py:1029
47
+#: app.py:1035
48
 msgid "Minimum screen dimensions for this application are 1152 x 768.\n"
49
 msgstr "此應用程式的最小螢幕解析度為 1152 x 768。\n"
50
 
51
-#: app.py:1030
52
+#: app.py:1036
53
 msgid "Your screen dimensions are "
54
 msgstr "你的螢幕解析度是 "
55
 
56
-#: app.py:1041
57
+#: app.py:1047
58
 msgid "Cannot launch application because XDG folders init error."
59
 msgstr ""
60
 
61
-#: app.py:1052
62
+#: app.py:1058
63
 msgid "Flowblade version 2.6 (or later) requires MLT version 6.18 to run"
64
 msgstr ""
65
 
66
-#: app.py:1053
67
+#: app.py:1059
68
 #, fuzzy
69
 msgid "Your MLT version is: "
70
 msgstr "MLT 版本: "
71
 
72
-#: app.py:1053
73
+#: app.py:1059
74
 msgid "Install MLT 6.18 or higher to run Flowblade."
75
 msgstr ""
76
 
77
-#: app.py:1127 projectaction.py:555 projectaction.py:757
78
+#: app.py:1133 projectaction.py:559 projectaction.py:761
79
 msgid "Project has not been saved previously"
80
 msgstr "先前的專案尚未儲存"
81
 
82
-#: app.py:1128 projectaction.py:556 projectaction.py:758
83
+#: app.py:1134 projectaction.py:560 projectaction.py:762
84
 msgid "Save project with File -> Save As before closing."
85
 msgstr "在結束之前,從 檔案 -> 另存新檔 來儲存專案。"
86
 
87
-#: projectaction.py:147
88
+#: projectaction.py:151
89
 msgid "Opening"
90
 msgstr "開啟中"
91
 
92
-#: projectaction.py:226
93
+#: projectaction.py:230
94
 msgid "Media asset was missing!"
95
 msgstr "媒體資產遺失!"
96
 
97
-#: projectaction.py:227
98
+#: projectaction.py:231
99
 msgid "Path of missing asset:"
100
 msgstr "遺失資產的路徑:"
101
 
102
-#: projectaction.py:228
103
+#: projectaction.py:232
104
 msgid ""
105
 "Relative search for replacement file in sub folders of project file failed."
106
 msgstr "在專案檔案的子資料夾中相對尋找替代檔案失敗。"
107
 
108
-#: projectaction.py:229
109
+#: projectaction.py:233
110
 msgid "To load the project you will need to either:"
111
 msgstr "載入專案,您將需要:"
112
 
113
-#: projectaction.py:230
114
+#: projectaction.py:234
115
 msgid ""
116
 "Open project in 'Media Relinker' tool to relink media assets to new files, or"
117
 msgstr "在 '媒體重新連接器' 工具中開啟專案來重新連結媒體資產到新的檔案,或"
118
 
119
-#: projectaction.py:231
120
+#: projectaction.py:235
121
 msgid "Place a file with the same exact name and path on the hard drive"
122
 msgstr "在硬碟中的相同路徑放一個相同名稱的檔案"
123
 
124
-#: projectaction.py:232
125
+#: projectaction.py:236
126
 msgid "Open project in Media Relinker tool"
127
 msgstr "在媒體重新連接器工具開啟專案"
128
 
129
-#: projectaction.py:251
130
+#: projectaction.py:255
131
 msgid "Profile with Description: '"
132
 msgstr "載入專案描述: ''"
133
 
134
-#: projectaction.py:251
135
+#: projectaction.py:255
136
 msgid "' was not found on load!"
137
 msgstr "' 時未發現!"
138
 
139
-#: projectaction.py:252
140
+#: projectaction.py:256
141
 msgid ""
142
 "It is possible to load the project by creating a User Profile with exactly "
143
 "the same Description\n"
144
@@ -143,30 +143,30 @@
145
 "可以通過建立與遺失的專案完全相同描述的使用者檔案\n"
146
 "來載入專案。"
147
 
148
-#: projectaction.py:253
149
+#: projectaction.py:257
150
 msgid "User Profiles can be created by selecting 'Edit->Profiles Manager'."
151
 msgstr "使用者設定檔可以藉由 '編輯 -> 設定檔管理員' 來創建。"
152
 
153
-#: projectaction.py:360
154
+#: projectaction.py:364
155
 msgid "Opening animated .gif file was refused!"
156
 msgstr ""
157
 
158
-#: projectaction.py:361
159
+#: projectaction.py:365
160
 msgid ""
161
 "Flowblade does not support displaying animated GIF files as media objects.\n"
162
 msgstr ""
163
 
164
-#: projectaction.py:362
165
+#: projectaction.py:366
166
 msgid ""
167
 "A possible workaround is to render GIF into a frame sequence and\n"
168
 "open that as a media item."
169
 msgstr ""
170
 
171
-#: projectaction.py:366
172
+#: projectaction.py:370
173
 msgid "Opening files with unknown  extensions refused!"
174
 msgstr ""
175
 
176
-#: projectaction.py:367
177
+#: projectaction.py:371
178
 msgid ""
179
 "Flowblade does not open files that cannot be identified as media from file "
180
 "extensions.\n"
181
@@ -174,21 +174,21 @@
182
 "\n"
183
 msgstr ""
184
 
185
-#: projectaction.py:369
186
+#: projectaction.py:373
187
 msgid "Too many to list.\n"
188
 msgstr ""
189
 
190
-#: projectaction.py:374
191
+#: projectaction.py:378
192
 msgid ""
193
 "\n"
194
 "Add the correct extension to load a problem file."
195
 msgstr ""
196
 
197
-#: projectaction.py:445
198
+#: projectaction.py:449
199
 msgid "Media files already present in project were opened!"
200
 msgstr "媒體檔案已存在開啟的專案!"
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/mediaplugin.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/mediaplugin.py Changed
150
 
1
@@ -19,7 +19,7 @@
2
 """
3
 
4
 """
5
-Thís module handels creating, editing and cloning of
6
+Thís module handles creating, editing and cloning of
7
 Generators.
8
 
9
 Generators are container clips that use Fluxity Scripts to render 
10
@@ -105,6 +105,16 @@
11
         script_file = respaths.MEDIA_PLUGINS_PATH + self.folder + "/" + self.script_file
12
         return script_file
13
 
14
+    def get_data(self):
15
+        return (self.folder, self.script_file, self.name, self.category, self.default_render)
16
+
17
+
18
+class GeneratorTemplate:
19
+    
20
+    def __init__(self, plugin_data, edited_script_data):
21
+        self.plugin_data = plugin_data
22
+        self.edited_script_data = edited_script_data
23
+
24
 
25
 # --------------------------------------------------------------- interface
26
 def init():
27
@@ -167,7 +177,7 @@
28
     
29
     return categories_list  
30
 
31
-# This method is used by scriptool.py create sub menu to load generator code into 
32
+# This method is used by scriptool.py to create a sub menu to load generator code into 
33
 # editor window as an example.
34
 def fill_media_plugin_sub_menu_gio(app, menu, callback):
35
     for group_data in _plugins_groups:
36
@@ -272,14 +282,57 @@
37
 def get_plugin_script_path(plugin_folder_and_script):
38
     return respaths.MEDIA_PLUGINS_PATH + plugin_folder_and_script
39
 
40
+def _save_current_state_as_generator_template():
41
+    global _current_plugin_data_object
42
+    plugin_data = _selected_plugin.get_data()
43
+    
44
+    edited_script_data = copy.deepcopy(_current_plugin_data_object)
45
+    edited_script_data"editors_list" = simpleeditors.get_editors_data_as_editors_list(_add_plugin_window.plugin_editors.editor_widgets)
46
+    edited_script_data"length" = int(_add_plugin_window.length_spin.get_value())
47
+
48
+    gen_data = GeneratorTemplate(plugin_data, edited_script_data)
49
+    default_name = edited_script_data"name" + ".generatortemplate"
50
+    
51
+    dialogs.save_generator_template(_save_template_callback, default_name, gen_data)
52
+
53
+def _save_template_callback(dialog, response_id, save_data):
54
+    if response_id == Gtk.ResponseType.ACCEPT:
55
+        save_path = dialog.get_filenames()0
56
+        with atomicfile.AtomicFileWriter(save_path, "wb") as afw:
57
+            write_file = afw.get_file()
58
+            pickle.dump(save_data, write_file)
59
+
60
+    dialog.destroy()
61
+
62
+def _load_generator_template():
63
+    dialogs.load_generator_template(_load_template_callback)
64
+    
65
+def _load_template_callback(dialog, response_id):
66
+    global _add_plugin_window
67
+    if response_id == Gtk.ResponseType.ACCEPT:
68
+        load_path = dialog.get_filenames()0
69
+        try:
70
+            generator_template = utils.unpickle(load_path)
71
+            _add_plugin_window._plugin_selection_changed(None, generator_template)
72
+        except Exception as e:
73
+            primary_txt = _("Generator Template load failed!")
74
+            secondary_txt = _("Error message: ") + str(e)
75
+            dialogutils.warning_message(primary_txt, secondary_txt, gui.editor_window.window)
76
+            gui.editor_window.edit_multi.set_visible_child_name(appconsts.EDIT_MULTI_EMPTY)
77
+
78
+    _add_plugin_window.position_listener(0.5, _add_plugin_window.producer.get_length())
79
+    _add_plugin_window.pos_bar.set_normalized_pos(0.5)
80
+    _add_plugin_window._show_preview()
81
+ 
82
+    dialog.destroy()
83
+    
84
 # --------------------------------------------------------- Window
85
 class AddMediaPluginWindow(Gtk.Window):
86
     def __init__(self):
87
         GObject.GObject.__init__(self)
88
         
89
         self.producer = PosBarProducer()
90
-        
91
-        self.set_modal(True)
92
+
93
         self.set_transient_for(gui.editor_window.window)
94
         self.set_title(_("Add Generator"))
95
         self.connect("delete-event", lambda w, e:_close_window())
96
@@ -332,8 +385,7 @@
97
         pos_bar_frame.set_margin_bottom(9)
98
         pos_bar_frame.set_margin_start(6)
99
         pos_bar_frame.set_margin_end(2)
100
-                                                 
101
-                                                 
102
+
103
         control_panel = Gtk.HBox(False, 2)
104
         control_panel.pack_start(self.tc_display.widget, False, False, 0)
105
         control_panel.pack_start(pos_bar_frame, True, True, 0)
106
@@ -374,13 +426,20 @@
107
         values_row = Gtk.HBox(False, 8)
108
         values_row.pack_start(self.editors_box, False, False, 0)
109
         values_row.pack_start(right_column_panel, True, True, 0)
110
-        
111
+
112
         close_button = guiutils.get_sized_button(_("Close"), 150, 32)
113
         close_button.connect("clicked", lambda w: _close_clicked())
114
         self.add_button = guiutils.get_sized_button(_("Add Generator"), 150, 32)
115
         self.add_button.connect("clicked", lambda w: _add_media_plugin())
116
+
117
+        save_button = guiutils.get_sized_button(_("Save Generator Template"), 170, 32)
118
+        save_button.connect("clicked", lambda w: _save_current_state_as_generator_template())
119
+        load_button = guiutils.get_sized_button(_("Load Generator Template"), 170, 32)
120
+        load_button.connect("clicked", lambda w: _load_generator_template())
121
         
122
         buttons_row = Gtk.HBox(False, 0)
123
+        buttons_row.pack_start(save_button, False, False, 0)
124
+        buttons_row.pack_start(load_button, False, False, 0)
125
         buttons_row.pack_start(Gtk.Label(), True, True, 0)
126
         buttons_row.pack_start(close_button, False, False, 0)
127
         buttons_row.pack_start(self.add_button, False, False, 0)
128
@@ -456,11 +515,17 @@
129
         cr.line_to(mx + 0.5, my + 0.5)
130
         cr.stroke()
131
         
132
-    def _plugin_selection_changed(self, combo):
133
-        name, new_selected_plugin = self.plugin_select.get_selected()
134
+    def _plugin_selection_changed(self, combo, plugin_template=None):
135
+
136
+        if plugin_template == None:
137
+            name, new_selected_plugin = self.plugin_select.get_selected()
138
+            success, fctx = self.get_plugin_data(new_selected_plugin.get_plugin_script_file())
139
+            script_data_object = json.loads(fctx.get_script_data())
140
+        else:
141
+            
142
+            new_selected_plugin = MediaPlugin(*plugin_template.plugin_data)
143
+            script_data_object = plugin_template.edited_script_data
144
         
145
-        success, fctx = self.get_plugin_data(new_selected_plugin.get_plugin_script_file())
146
-        script_data_object = json.loads(fctx.get_script_data())
147
         self._show_plugin_editors_panel(script_data_object)
148
 
149
         global _selected_plugin, _current_screenshot_surface, _current_plugin_data_object
150
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/middlebar.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/middlebar.py Changed
23
 
1
@@ -245,17 +245,18 @@
2
     tooltip_runner = glassbuttons.TooltipRunner(editor_window.edit_buttons_3, tooltips)
3
     editor_window.edit_buttons_3.no_decorations = no_decorations
4
     editor_window.edit_buttons_3.show_prelight_icons()
5
-    
6
+
7
     # Resync and split audio
8
     editor_window.edit_buttons_2 = glassbuttons.GlassButtonsGroup(44*size_adj, 23*size_adj, 2*size_adj, 3*size_adj, 5*size_adj)
9
     editor_window.edit_buttons_2.add_button(guiutils.get_cairo_image("split_audio"), tlineaction.split_audio_synched_button_pressed)
10
+    editor_window.edit_buttons_2.add_button(guiutils.get_cairo_image("set_track_sync"), tlineaction.set_track_sync_button_pressed)
11
     editor_window.edit_buttons_2.add_button(guiutils.get_cairo_image("resync_track"), tlineaction.resync_track_button_pressed)
12
     editor_window.edit_buttons_2.add_button(guiutils.get_cairo_image("resync"), tlineaction.resync_button_pressed)
13
-    tooltips = _("Split Audio Synched"),  _("Resync Track Containing Selected Clip/s"), _("Resync Selected Clip")
14
+    tooltips = _("Split Audio Synched"), _("Set Sync for All Clips on Track Containing Selected Clip/s"), _("Resync Track Containing Selected Clip/s"), _("Resync Selected Clips")
15
     tooltip_runner = glassbuttons.TooltipRunner(editor_window.edit_buttons_2, tooltips)
16
     editor_window.edit_buttons_2.no_decorations = no_decorations
17
     editor_window.edit_buttons_2.show_prelight_icons()
18
-    
19
+
20
     editor_window.monitor_insert_buttons = glassbuttons.GlassButtonsGroup(44*size_adj, 23*size_adj, 2*size_adj, 3*size_adj, 5*size_adj)
21
     editor_window.monitor_insert_buttons.add_button(guiutils.get_cairo_image("overwrite_range"), tlineaction.range_overwrite_pressed)
22
     editor_window.monitor_insert_buttons.add_button(guiutils.get_cairo_image("overwrite_clip"), tlineaction.three_point_overwrite_pressed)
23
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/mltfilters.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/mltfilters.py Changed
10
 
1
@@ -221,7 +221,7 @@
2
              self.mlt_filter.set("disable", str(1))
3
 
4
     def replace_values(self, clip):
5
-        # We need to initialize some calues based clip length and need wait until clip for
6
+        # We need to initialize some values based clip length and need wait until clip for
7
         # filter is known, replace at object creation is done before clip is available
8
         replacement_happened = propertyparse.replace_values_using_clip_data(self.properties, self.info, clip)
9
         if replacement_happened == True:
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/mltplayer.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/mltplayer.py Changed
9
 
1
@@ -425,6 +425,7 @@
2
         self.ticker.start_ticker()
3
     
4
     def stop_ticker(self):
5
+        gui.editor_window.player_buttons.show_playing_state(False)
6
         self.ticker.destroy_ticker()
7
 
8
 
9
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/mlttransitions.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/mlttransitions.py Changed
18
 
1
@@ -22,6 +22,7 @@
2
 Module contains objects that wrap mlt.Transition objects used to mix video between
3
 two tracks.
4
 """
5
+
6
 import copy
7
 try:
8
     import mlt7 as mlt
9
@@ -335,7 +336,7 @@
10
     
11
         self.destroy_id = os.urandom(16) # HACK, HACK, HACK - find a way to remove this stuff  
12
                                          # Compositors are recreated often in Sequence.restack_compositors()
13
-                                         # and cannot be destroyed in undo/redo with object identidy.
14
+                                         # and cannot be destroyed in undo/redo with object identity.
15
                                          # This is cloned in clone_properties
16
 
17
     def get_length(self):
18
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/modesetting.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/modesetting.py Changed
26
 
1
@@ -339,3 +339,23 @@
2
     gui.editor_window.tline_cursor_manager.set_cursor_to_mode()
3
 
4
     clipeffectseditor.keyframe_editor_widgets = 
5
+
6
+def kftool_mode_from_kf_editor(clip, track, param_name, filter, filter_index, displayname):
7
+    stop_looping()
8
+    current_sequence().clear_hidden_track()
9
+
10
+    kftoolmode.enter_mode = editorstate.edit_mode 
11
+    editorstate.edit_mode = editorstate.KF_TOOL
12
+        
13
+    tlinewidgets.set_edit_mode(None, tlinewidgets.draw_kftool_overlay)
14
+    movemodes.clear_selected_clips() # Entering this edit mode clears selection 
15
+
16
+    kftoolmode.set_no_clip_edit_data()
17
+
18
+    #kftoolmode.init_tool_for_clip(clip, track, edit_type)
19
+    kftoolmode.init_for_clip_filter_and_param(clip, track, param_name, filter, filter_index, displayname)
20
+    kftoolmode.edit_data"initializing" = False
21
+    gui.editor_window.tline_cursor_manager.set_cursor_to_mode()
22
+
23
+    clipeffectseditor.keyframe_editor_widgets = 
24
+    
25
\ No newline at end of file
26
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/monitorevent.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/monitorevent.py Changed
64
 
1
@@ -57,51 +57,21 @@
2
     if editorstate.current_is_active_trim_mode() and trimmodes.submode != trimmodes.NOTHING_ON:
3
         return
4
 
5
-    if current_is_move_mode():
6
-        movemodes.play_pressed()
7
-    elif EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
8
-        trimmodes.oneroll_play_pressed()
9
-    elif EDIT_MODE() == editorstate.ONE_ROLL_TRIM_NO_EDIT:
10
-        movemodes.play_pressed()
11
-    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
12
-        trimmodes.tworoll_play_pressed()
13
-    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM_NO_EDIT:
14
-        movemodes.play_pressed()
15
-    elif EDIT_MODE() == editorstate.SLIDE_TRIM:
16
-        trimmodes.slide_play_pressed()
17
-    elif EDIT_MODE() == editorstate.SLIDE_TRIM_NO_EDIT:
18
-        movemodes.play_pressed()
19
-    elif EDIT_MODE() == editorstate.KF_TOOL:
20
-        movemodes.play_pressed()
21
-    elif EDIT_MODE() == editorstate.MULTI_TRIM:
22
-        movemodes.play_pressed()
23
-    elif EDIT_MODE() == editorstate.CUT:
24
-        movemodes.play_pressed()
25
+    PLAYER().start_playback()
26
+    gui.editor_window.player_buttons.show_playing_state(True)
27
 
28
 def stop_pressed():
29
-    if current_is_move_mode():
30
-        movemodes.stop_pressed()
31
-    elif EDIT_MODE() == editorstate.ONE_ROLL_TRIM_NO_EDIT:
32
-        movemodes.stop_pressed()
33
-    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM_NO_EDIT:
34
-        movemodes.stop_pressed()
35
-    elif EDIT_MODE() == editorstate.ONE_ROLL_TRIM:
36
-        trimmodes.oneroll_stop_pressed()
37
-    elif EDIT_MODE() == editorstate.TWO_ROLL_TRIM:
38
-        trimmodes.tworoll_stop_pressed()
39
-    elif EDIT_MODE() == editorstate.SLIDE_TRIM:
40
-        trimmodes.slide_stop_pressed()
41
-    elif EDIT_MODE() == editorstate.SLIDE_TRIM_NO_EDIT:
42
-        movemodes.stop_pressed()
43
-    elif EDIT_MODE() == editorstate.KF_TOOL:
44
-        movemodes.stop_pressed()
45
-    elif EDIT_MODE() == editorstate.MULTI_TRIM:
46
-        movemodes.stop_pressed()
47
-    elif EDIT_MODE() == editorstate.CUT:
48
-        movemodes.stop_pressed()
49
-
50
+    PLAYER().stop_playback()
51
+    gui.editor_window.player_buttons.show_playing_state(False)
52
+    
53
     updater.maybe_autocenter()
54
 
55
+def play_stop_pressed():
56
+    if PLAYER().is_playing():
57
+        stop_pressed()
58
+    else:
59
+        play_pressed()
60
+            
61
 #------------------------------------------  go to start, end
62
 def start_pressed():
63
     if current_is_move_mode():
64
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/motiontracking.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/motiontracking.py Changed
24
 
1
@@ -56,6 +56,22 @@
2
         tdata_select_combo.set_active(current_selection_index)
3
     return (tdata_keys, tdata_select_combo)
4
 
5
+def get_used_motion_tracking_data():
6
+    used_tracking_data = 
7
+    for seq in PROJECT().sequences:
8
+        for track in seq.tracks:
9
+            for clip in track.clips:
10
+                try:
11
+                    for filt in clip.filters:
12
+                        if filt.info.mlt_service_id == "affine":
13
+                            for non_mlt_property in filt.non_mlt_properties:
14
+                                p_name, p_value, p_type = non_mlt_property
15
+                                if p_name == "selected_tracking_data":
16
+                                    used_tracking_data.append(p_value)
17
+                except:
18
+                    pass # Blank clip hit
19
+    return used_tracking_data
20
+
21
 def apply_tracking( tracking_data_id, filter, editable_properties, 
22
                     xoff, yoff, interpretation, size, clip_in,
23
                     source_width, source_height):
24
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/movemodes.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/movemodes.py Changed
42
 
1
@@ -45,7 +45,7 @@
2
 # Mouse delta in pix needed before selection is interpreted as move.
3
 MOVE_START_LIMIT = 5
4
 
5
-# Width of area in pixels that is iterpreted as an attempt to place overwrite
6
+# Width of area in pixels that is interpreted as an attempt to place overwrite
7
 # clips, starting from edit
8
 MAGNETIC_AREA_IN_PIX = 5
9
 
10
@@ -69,23 +69,6 @@
11
 # Data/state for ongoing edit.
12
 edit_data = None
13
 
14
-#------------------------------ playback control
15
-# These four buttons act differently in trimmodes and move modes
16
-def play_pressed():
17
-    # This handles only move modes, see trimmodes.py module for others.
18
-    # Jul-2016 - SvdB - Added code to handle play/pause button
19
-    if editorpersistance.prefs.play_pause == True:
20
-        if PLAYER().is_playing():
21
-            PLAYER().stop_playback()
22
-        else:
23
-            PLAYER().start_playback()
24
-    else:
25
-        # Original code
26
-        PLAYER().start_playback()
27
-
28
-def stop_pressed():
29
-    # This handles only move modes, see trimmodes.py module for others.
30
-    PLAYER().stop_playback()
31
 
32
 #------------------------------------------ go to start end
33
 def start_pressed():
34
@@ -95,6 +78,7 @@
35
 def end_pressed():
36
     # This handles only move modes, see trimmodes.py module for others.
37
     PLAYER().seek_frame(PLAYER().get_active_length() - 1)
38
+    
39
 #------------------------------------------ End of  go to start end
40
 def prev_pressed():
41
     # This handles only move modes, see trimmodes.py module for others.
42
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/panels.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/panels.py Changed
32
 
1
@@ -194,7 +194,9 @@
2
     return align
3
 
4
 def get_file_properties_panel(data):
5
-    media_file, img, size, length, vcodec, acodec, channels, frequency, fps, match_profile_name, matches_current_profile = data
6
+    media_file, img, size, length, vcodec, acodec, channels, frequency, \
7
+    fps, match_profile_name, matches_current_profile, pixel_format, colorspace = data
8
+
9
     name_label = Gtk.Label(label=media_file.name)
10
     name_label.set_max_width_chars(100)
11
     name_label.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
12
@@ -212,7 +214,9 @@
13
     row5 = get_two_column_box_fixed(get_bold_label(_("Audio Sample Rate:")), Gtk.Label(label=frequency))
14
     row6 = get_two_column_box_fixed(get_bold_label(_("Best Profile:")), Gtk.Label(label=match_profile_name))
15
     row7 = get_two_column_box_fixed(get_bold_label(_("Matches Project Profile:")), Gtk.Label(label=matches_current_profile))
16
-    
17
+    row8 = get_two_column_box_fixed(get_bold_label(_("Colorspace:")), Gtk.Label(label=colorspace))
18
+    row9 = get_two_column_box_fixed(get_bold_label(_("Pixel Format:")), Gtk.Label(label=pixel_format))
19
+
20
     vbox = Gtk.VBox(False, 2)
21
     vbox.pack_start(img, False, False, 0)
22
     vbox.pack_start(guiutils.get_pad_label(12, 16), False, False, 0)
23
@@ -222,6 +226,8 @@
24
     vbox.pack_start(row111, False, False, 0)
25
     vbox.pack_start(row11, False, False, 0)
26
     vbox.pack_start(row2, False, False, 0)
27
+    vbox.pack_start(row9, False, False, 0)
28
+    vbox.pack_start(row8, False, False, 0)
29
     vbox.pack_start(row3, False, False, 0)
30
     vbox.pack_start(row4, False, False, 0)
31
     vbox.pack_start(row5, False, False, 0)
32
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/patternproducer.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/patternproducer.py Changed
10
 
1
@@ -163,7 +163,7 @@
2
 # --------------------------------------------------- bin media objects
3
 class AbstractBinClip: # not extends projectdata.MediaFile? too late, too late. Also better name would be AbstractBinPatternProducer
4
     """
5
-    A pattern producer object presnt in Media Bin.
6
+    A pattern producer object present in Media Bin.
7
     """
8
     def __init__(self, id, name):
9
         self.id = id
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/persistance.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/persistance.py Changed
90
 
1
@@ -65,7 +65,7 @@
2
 # Used to send messages when loading project, set at callsite.
3
 load_dialog = None
4
 
5
-# These are used to recrete parenting relationships
6
+# These are used to recreate parenting relationships
7
 all_clips = {}
8
 sync_clips = 
9
 
10
@@ -239,6 +239,10 @@
11
 
12
     s_playlist.clips = add_clips
13
     
14
+    # Replace parent track with its id.
15
+    if s_playlist.parent_track != None:
16
+        s_playlist.parent_track = s_playlist.parent_track.id
17
+    
18
     # Remove unpicleable attributes
19
     remove_attrs(s_playlist, PLAY_LIST_REMOVE)
20
    
21
@@ -341,10 +345,12 @@
22
 
23
 def get_p_sync_data(sync_data):
24
     s_sync_data = copy.copy(sync_data)
25
-    if isinstance( sync_data.master_clip, int ): # When saving relinked projects sync_data.master_clip 
26
-                                                   # is already int and does not need to be replaced
27
+    if isinstance( sync_data.master_clip, int ):   # When saving relinked projects sync_data.master_clip 
28
+                                                   # and s_sync_data.master_clip_track are already ints
29
+                                                   # because they haven't been replacved with live objects.
30
         return s_sync_data
31
     s_sync_data.master_clip = sync_data.master_clip.id
32
+    s_sync_data.master_clip_track = sync_data.master_clip_track.id
33
     return s_sync_data
34
 
35
 def remove_attrs(obj, remove_attrs):
36
@@ -511,7 +517,7 @@
37
     # Compositing mode COMPOSITING_MODE_TOP_DOWN_AUTO_FOLLOW was removed 2.6->
38
     persistancecompat.FIX_DEPRECATED_SEQUENCE_COMPOSITING_MODE(seq)
39
     
40
-    # Grap and replace py tracks. Do this way to use same create
41
+    # Grab and replace py tracks. Do this way to use same create
42
     # method as when originally created.
43
     py_tracks = seq.tracks
44
     seq.tracks = 
45
@@ -522,6 +528,7 @@
46
     # Create and fill MLT tracks.
47
     for py_track in py_tracks:
48
         mlt_track = seq.add_track(py_track.type)
49
+        persistancecompat.FIX_MISSING_TRACK_ATTRS(mlt_track)
50
         if py_track.id == len(py_tracks) - 1:
51
             continue # Do not try to fill hidden track even if somehow a clip was saved there.
52
         fill_track_mlt(mlt_track, py_track)
53
@@ -529,7 +536,7 @@
54
         if hasattr(mlt_track, "gain_filter"): # Hidden track and black track do not have these
55
             mlt_track.gain_filter.set("gain", str(mlt_track.audio_gain))
56
         if mlt_track.audio_pan != appconsts.NO_PAN:
57
-            seq.add_track_pan_filter(mlt_track, mlt_track.audio_pan) # only rtack with non-center pan values have pan filters
58
+            seq.add_track_pan_filter(mlt_track, mlt_track.audio_pan) # only track with non-center pan values have pan filters
59
     
60
     # Create and connect compositors.
61
     mlt_compositors = 
62
@@ -576,12 +583,25 @@
63
         clip, track = clip_n_track
64
         try:
65
             master_clip = all_clipsclip.sync_data.master_clip # master clip has been replaced with its id on save
66
-            clip.sync_data.master_clip = master_clip # put back reference to master clip
67
-            resync.clip_added_to_timeline(clip, track) # save data to enagble sync states monitoring after eddits
68
+            if hasattr(clip.sync_data, "master_clip_track"):
69
+                master_clip_track = seq.tracksclip.sync_data.master_clip_track
70
+            else:
71
+                # All sync parents were previously on track V1.
72
+                master_clip_track = seq.tracksseq.first_video_index
73
+            # put back references to objects
74
+            clip.sync_data.master_clip = master_clip
75
+            clip.sync_data.master_clip_track = master_clip_track
76
+            resync.clip_added_to_timeline(clip, track) # save data to enagble sync states monitoring after edits
77
         except KeyError:
78
             clip.sync_data = None # masterclip no longer on track V1
79
             resync.clip_removed_from_timeline(clip)
80
 
81
+    # Replace track ids with track objects on parented tracks.
82
+    for i in range(1, len(seq.tracks) - 1):
83
+        track = seq.tracksi
84
+        if track.parent_track != None:
85
+            track.parent_track = seq.trackstrack.parent_track
86
+
87
     # This sets MLT properties that actually do mute
88
     seq.set_tracks_mute_state()
89
 
90
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/persistancecompat.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/persistancecompat.py Changed
62
 
1
@@ -21,7 +21,10 @@
2
 """
3
 This module holds functions that maintain compatibility between project savefiles
4
 created by different versions of application.
5
+
6
+When new attributes are added to persistent classes they are added here to classes in save files created by older versions.  
7
 """
8
+
9
 import hashlib
10
 import os
11
 
12
@@ -53,6 +56,9 @@
13
     if not hasattr(media_file, "rating"):
14
         media_file.rating = appconsts.MEDIA_FILE_UNRATED
15
 
16
+    if not hasattr(media_file, "link_seq_data"):
17
+        media_file.link_seq_data = None
18
+
19
 def FIX_MISSING_CLIP_ATTRS(clip):
20
     # Add color attribute if not found
21
     if not hasattr(clip, "color"):
22
@@ -77,7 +83,10 @@
23
     # Add container data if not found.
24
     if not hasattr(clip, "slowmo_data"):
25
         clip.slowmo_data = None
26
-        
27
+
28
+    if not hasattr(clip, "link_seq_data"):
29
+        clip.link_seq_data = None 
30
+
31
 def FIX_MISSING_FILTER_ATTRS(filter):
32
     if not hasattr(filter.info, "filter_mask_filter"):
33
         filter.info.filter_mask_filter = None
34
@@ -93,6 +102,9 @@
35
     if not hasattr(seq, "compositing_mode"):
36
         seq.compositing_mode = appconsts.COMPOSITING_MODE_TOP_DOWN_FREE_MOVE
37
 
38
+    if(not hasattr(seq, "uid")):
39
+        seq.uid = hashlib.md5(str(os.urandom(32)).encode('utf-8')).hexdigest()
40
+        
41
 def FIX_DEPRECATED_SEQUENCE_COMPOSITING_MODE(seq):
42
     # Compositing mode COMPOSITING_MODE_TOP_DOWN_AUTO_FOLLOW was removed 2.6->, we just convert it 
43
     # to COMPOSITING_MODE_TOP_DOWN_FREE_MOVE.
44
@@ -123,8 +135,14 @@
45
 
46
     if(not hasattr(project, "tracking_data")):
47
         project.tracking_data = {}
48
-        
49
+
50
+    if(not hasattr(project, "container_default_encoding")):
51
+        project.container_default_encoding = None
52
+
53
 def FIX_MISSING_BIN_ATTRS(bin):
54
     if(not hasattr(bin, "uid")):
55
         bin.uid = hashlib.md5(str(os.urandom(32)).encode('utf-8')).hexdigest()
56
-    
57
\ No newline at end of file
58
+
59
+def FIX_MISSING_TRACK_ATTRS(track):
60
+    if(not hasattr(track, "parent_track")):
61
+        track.parent_track = None
62
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/positionbar.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/positionbar.py Changed
10
 
1
@@ -129,7 +129,7 @@
2
         length = producer.get_length() # Get from MLT
3
         self.length = length 
4
         try:
5
-            self.mark_in_norm = float(mark_in) / length # Diasables range if mark_in == -1 because self.mark_in_norm < 0
6
+            self.mark_in_norm = float(mark_in) / length # Disables range if mark_in == -1 because self.mark_in_norm < 0
7
             self.mark_out_norm = float(mark_out) / length
8
             frame_pos = producer.frame()
9
             norm_pos = float(frame_pos) / length
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/preferenceswindow.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/preferenceswindow.py Changed
38
 
1
@@ -367,11 +367,6 @@
2
     tracks_combo.append_text(_("2 x - 100px, 50px"))
3
     tracks_combo.set_active(prefs.tracks_scale)
4
 
5
-    icons_combo = Gtk.ComboBoxText()
6
-    icons_combo.append_text(_("Default"))
7
-    icons_combo.append_text(_("Double"))
8
-    icons_combo.set_active(prefs.icons_scale)
9
-
10
     monitors_data = utilsgtk.get_display_monitors_size_data()
11
     layout_monitor = Gtk.ComboBoxText()
12
 
13
@@ -409,7 +404,6 @@
14
     row1 = _row(guiutils.get_checkbox_row_box(display_splash_check, Gtk.Label(label=_("Display splash screen"))))
15
     row6 = _row(guiutils.get_checkbox_row_box(show_full_file_names, Gtk.Label(label=_("Show Full File names"))))
16
     row7 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Tracks Heights:")), tracks_combo, PREFERENCES_LEFT))
17
-    row8 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Icons Size:")), icons_combo, PREFERENCES_LEFT))
18
 
19
     row10 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Do GUI layout based on:")), layout_monitor, PREFERENCES_LEFT))
20
     row13 = _row(guiutils.get_two_column_box(Gtk.Label(label=_("Edit panel width:")), edit_panel_width_spin, PREFERENCES_LEFT))
21
@@ -424,7 +418,6 @@
22
     vbox.pack_start(row1, False, False, 0)
23
     vbox.pack_start(row6, False, False, 0)
24
     vbox.pack_start(row7, False, False, 0)
25
-    vbox.pack_start(row8, False, False, 0)
26
     vbox.pack_start(row14, False, False, 0)
27
     vbox.pack_start(row13, False, False, 0)
28
     vbox.pack_start(row12, False, False, 0)
29
@@ -434,7 +427,7 @@
30
     guiutils.set_margins(vbox, 12, 0, 12, 12)
31
 
32
     return vbox, (force_language_combo, display_splash_check, window_mode_combo, show_full_file_names,
33
-                  tracks_combo, icons_combo, project_panel_width_spin, edit_panel_width_spin, media_panel_width_spin,
34
+                  tracks_combo, project_panel_width_spin, edit_panel_width_spin, media_panel_width_spin,
35
                   layout_monitor, filter_select_width_spin)
36
 
37
 
38
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/projectaction.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/projectaction.py Changed
201
 
1
@@ -29,6 +29,8 @@
2
     import mlt7 as mlt
3
 except:
4
     import mlt
5
+
6
+import copy
7
 import os
8
 from os import listdir
9
 from os.path import isfile, join, expanduser
10
@@ -58,6 +60,7 @@
11
 import guicomponents
12
 import guipopover
13
 import guiutils
14
+import gtkbuilder
15
 import edit
16
 import editorstate
17
 from editorstate import current_sequence
18
@@ -67,6 +70,7 @@
19
 from editorstate import MONITOR_MEDIA_FILE
20
 from editorstate import EDIT_MODE
21
 import editorpersistance
22
+import jobs
23
 import kftoolmode
24
 import medialinker
25
 import medialog
26
@@ -1016,6 +1020,7 @@
27
         proxyediting.create_proxy_files_pressed(True)
28
     elif msg == "select all":
29
         gui.media_list_view.select_all()
30
+        gui.media_list_view.selected_objects0.widget.grab_focus()
31
     elif msg == "select none":
32
         gui.media_list_view.clear_selection()
33
     elif msg == "append all":
34
@@ -1031,6 +1036,8 @@
35
         dialogs.set_bin_grfx_default_length_dialog( current_bin(),
36
                                                     current_default_length,
37
                                                     _set_bin_grfx_default_length_callback)
38
+    elif msg == "delete":
39
+        delete_media_files()
40
     else:
41
         target_bin_index = int(msg)
42
         
43
@@ -1395,9 +1402,13 @@
44
     if media_file.type == appconsts.VIDEO:
45
         match_profile_index = mltprofiles.get_closest_matching_profile_index(info)
46
         match_profile_name =  mltprofiles.get_profile_name_for_index(match_profile_index)
47
+        pixel_format = info"pixel_format"
48
+        colorspace = info"colorspace"
49
     else:
50
         match_profile_name = _("N/A")
51
-    
52
+        pixel_format = _("N/A")
53
+        colorspace = _("N/A")
54
+
55
     if media_file.type == appconsts.VIDEO:
56
         if media_file.matches_project_profile():
57
             matches_project_profile = _("Yes")
58
@@ -1412,8 +1423,10 @@
59
         fps = utils.get_fps_str_with_two_decimals(str(float(num/den)))
60
     except:
61
         fps = _("N/A")
62
-    
63
-    dialogs.file_properties_dialog((media_file, img, size, length, vcodec, acodec, channels, frequency, fps, match_profile_name, matches_project_profile))
64
+
65
+    dialogs.file_properties_dialog((media_file, img, size, length, vcodec, acodec, 
66
+                                    channels, frequency, fps, match_profile_name, 
67
+                                    matches_project_profile, pixel_format, colorspace))
68
 
69
 def remove_unused_media():
70
     unused = PROJECT().get_unused_media()
71
@@ -1426,7 +1439,7 @@
72
 
73
 def _media_filtering_selector_item_activated(action, new_value_variant):
74
     try:
75
-        index = int( new_value_variant.get_string())
76
+        index = int(new_value_variant.get_string())
77
     except:
78
         # This is ratings selection
79
         _ratings_filtering_item_activated(action, new_value_variant)
80
@@ -1479,33 +1492,17 @@
81
 def _media_import_data_ready():
82
     files_list = projectmediaimport.get_imported_media()
83
     generators_list = projectmediaimport.get_imported_generators()
84
-    
85
-    if len(generators_list) > 0:
86
-        global media_import_data
87
-        media_import_data = (files_list, generators_list, 0)
88
-        _media_import_with_generators()
89
-    else:
90
-        # No need to do complex callbacks to get generators imported.
91
-        open_file_names(files_list)
92
 
93
-def _media_import_with_generators():
94
-    # import generators from list recursively using existing code in containerclip.py
95
-    global media_import_data
96
-    files_list, generators_list, index = media_import_data
97
-    if index == len(generators_list):
98
+    if len(files_list) > 0:
99
         open_file_names(files_list)
100
-    else:
101
-        container_data = generators_listindex
102
-        index += 1
103
-        media_import_data = (files_list, generators_list, index)
104
-    
105
-        script_file, screenshot_file, plugin_data = mediaplugin.create_plugin_assests_for_media_import(container_data)
106
-    
107
-        containerclip.create_fluxity_media_item_from_plugin(    script_file, 
108
-                                                                screenshot_file, 
109
-                                                                plugin_data, 
110
-                                                                _media_import_with_generators)
111
         
112
+    if len(generators_list) > 0:
113
+        primary_txt = _("Generators are not imported from another Projects!")
114
+        secondary_text = _("You attempted to import %s Generator/s.\n\nPlease use <b>Project/Add Generator.../Save/Load Generator Template</b> -feature\nto create reusable Generators.") 
115
+        secondary_text = secondary_text  % (str(len(generators_list)))
116
+
117
+        dialogutils.info_message(primary_txt, secondary_text, gui.editor_window.window)
118
+
119
 def create_selection_compound_clip():
120
     if movemodes.selected_track == -1:
121
         # info window no clips selected?
122
@@ -1573,8 +1570,6 @@
123
     default_name = _("sequence_") + _get_compound_clip_default_name_date_str()
124
     dialogs.compound_clip_name_dialog(_do_create_sequence_compound_clip, default_name, _("Save Sequence Container Clip"))
125
 
126
-
127
-
128
 def _do_create_sequence_compound_clip(dialog, response_id, name_entry):
129
     if response_id != Gtk.ResponseType.ACCEPT:
130
         dialog.destroy()
131
@@ -1617,7 +1612,27 @@
132
                                                     (write_file, media_name), selected_sequence, 
133
                                                     PROJECT(), PLAYER())
134
     render_player.start()
135
+
136
+
137
+def create_sequence_link_container_clip_from_selected():
138
+    selection = gui.sequence_list_view.treeview.get_selection()
139
+    model, iter = selection.get_selected()
140
+    (model, rows) = selection.get_selected_rows()
141
+    row = max(rows0)
142
+    selected_sequence = PROJECT().sequencesrow
143
+
144
+    media_name = selected_sequence.name + _(" LINK")
145
+
146
+    # Create unique file path in hidden render folder.
147
+    folder = userfolders.get_render_dir()
148
+    uuid_str = hashlib.md5(str(os.urandom(32)).encode('utf-8')).hexdigest()
149
+    write_file = folder + uuid_str + ".xml"
150
     
151
+    render_player = renderconsumer.XMLRenderPlayer( write_file, _sequence_link_xml_render_done_callback, 
152
+                                                    (selected_sequence, write_file, media_name), selected_sequence, 
153
+                                                    PROJECT(), PLAYER())
154
+    render_player.start()
155
+
156
 def create_sequence_freeze_frame_compound_clip():
157
     # lets's just set something unique-ish 
158
     default_name = _("frame_") + utils.get_tc_string_with_fps_for_filename(PLAYER().current_frame(), utils.fps()) + ".xml"
159
@@ -1651,6 +1666,39 @@
160
 def _get_compound_clip_default_name_date_str():
161
     return str(datetime.date.today()) + "_" + time.strftime("%H%M%S")
162
 
163
+def create_sequence_link_container():
164
+    dialogs.select_link_sequence_for_container(_do_create_sequence_link_container)
165
+
166
+def _do_create_sequence_link_container(dialog, response_id, data):
167
+    if response_id != Gtk.ResponseType.ACCEPT:
168
+        dialog.destroy()
169
+        return
170
+    
171
+    sequences_combo, selection_data = data
172
+    selected_sequence = selection_datasequences_combo.get_active()
173
+    media_name = selected_sequence.name + _(" LINK")
174
+
175
+    dialog.destroy()
176
+
177
+    # Create unique file path in hidden render folder
178
+    folder = userfolders.get_render_dir()
179
+    uuid_str = hashlib.md5(str(os.urandom(32)).encode('utf-8')).hexdigest()
180
+    write_file = folder + uuid_str + ".xml"
181
+    
182
+    render_player = renderconsumer.XMLRenderPlayer( write_file, _sequence_link_xml_render_done_callback, 
183
+                                                    (selected_sequence, write_file, media_name), selected_sequence, 
184
+                                                    PROJECT(), PLAYER())
185
+    render_player.start()
186
+
187
+def _sequence_link_xml_render_done_callback(data):
188
+    # We do GUI updates on add, so we need GLib thread.
189
+    selected_sequence, write_file, media_name = data
190
+    GLib.idle_add(_do_sequence_link_item_add, data)
191
+
192
+def _do_sequence_link_item_add(data):
193
+    selected_sequence, xml_file_path, media_name = data
194
+    containerclip.create_sequence_link_media_item(xml_file_path, media_name, selected_sequence.uid)
195
+    
196
 def append_all_media_clips_into_timeline():
197
     media_files = 
198
     for file_id in PROJECT().c_bin.file_ids:
199
@@ -1876,9 +1924,11 @@
200
         delete_selected_sequence()
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/projectdata.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/projectdata.py Changed
64
 
1
@@ -100,6 +100,7 @@
2
                                                   # 1.10 needed that data for the first time and required recreating it correctly for older projects
3
         self.project_properties = {} # Key value pair for misc persistent properties, dict is used that we can add these without worrying loading
4
         self.tracking_data = {}
5
+        self.container_default_encoding = None # Set in coantaineractions.py by user.
6
 
7
         self.vault_folder = None
8
         self.project_data_id = None
9
@@ -204,6 +205,10 @@
10
         
11
     def add_container_clip_media_object(self, media_object):
12
         self._add_media_object(media_object)
13
+
14
+    def add_sequence_link_media_object(self, media_object, link_seq_uid):
15
+        media_object.link_seq_data = link_seq_uid
16
+        self._add_media_object(media_object)
17
         
18
     def _add_media_object(self, media_object, target_bin=None):
19
         """
20
@@ -272,7 +277,6 @@
21
 
22
         self.c_bin.file_ids.pop(media_file.id)
23
 
24
-
25
     def get_unused_media(self):
26
         # Create path -> media item dict
27
         path_to_media_object = {}
28
@@ -323,6 +327,12 @@
29
         name = _("sequence_") + str(self.next_seq_number)
30
         self.add_named_sequence(name)
31
 
32
+    def get_sequence_for_uid(self, seq_uid):
33
+        for seq in self.sequences:
34
+            if seq.uid == seq_uid:
35
+                return seq
36
+        return None
37
+
38
     def get_current_bin_graphics_default_length(self):
39
         try:
40
             return self.bins_graphics_default_lengthsself.c_bin.uid
41
@@ -434,6 +444,14 @@
42
         self.tracking_datadata_uid = (final_label, data_file_path)
43
         return final_label
44
 
45
+    def delete_tracking_data(self, tracking_data_id):
46
+        final_label, data_file_path = self.tracking_datatracking_data_id
47
+        try:
48
+            os.remove(data_file_path)
49
+        except:
50
+            print("ProjectData.delete_tracking_data(): trying to delete non-existing data") 
51
+        del self.tracking_datatracking_data_id
52
+
53
     def _tracking_data_label_exists(self, data_label):
54
         for item in self.tracking_data.items():
55
             label, data_path = item
56
@@ -466,6 +484,7 @@
57
 
58
         self.container_data = None
59
         self.titler_data = None
60
+        self.link_seq_data = None
61
         
62
         self.info = info
63
         self.rating = appconsts.MEDIA_FILE_UNRATED
64
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/projectdatavault.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/projectdatavault.py Changed
28
 
1
@@ -40,7 +40,7 @@
2
 from editorstate import PROJECT
3
 
4
 # Project data folder path is accessed with PROJECT() in main application, but 
5
-# render processses receive it as parameter and set it here in init. 
6
+# render processes receive it as parameter and set it here in init. 
7
 _project_data_folder = None
8
 
9
 # User folder locations
10
@@ -85,7 +85,7 @@
11
 
12
 # ------------------------------------------------------------------------ init
13
 def init(_current_project_data_folder=None):
14
-    # This data is duplicated with userfolders.py but thats really not an issue.
15
+    # This data is duplicated with userfolders.py but that's really not an issue.
16
     global _xdg_config_dir, _xdg_data_dir, _xdg_cache_dir, _project_data_folder
17
 
18
     # XDG folders
19
@@ -152,7 +152,7 @@
20
 def get_project_data_folder():
21
     # Render processes don't have access to project data folder path via 'PROJECT()',
22
     # so they sometimes use '_project_data_folder' which set is in main() to be available
23
-    # when neeeded.
24
+    # when needed.
25
 
26
     try:
27
         path = PROJECT().vault_folder + "/" + PROJECT().project_data_id + "/"
28
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/projectdatavaultgui.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/projectdatavaultgui.py Changed
28
 
1
@@ -547,7 +547,7 @@
2
         name = vaults_obj.get_user_vaults_data()self.view_vault_index - 1"name" # -1 because first vault is the default vault
3
         name_label = Gtk.Label(label=name)
4
 
5
-        data_label = Gtk.Label(label=_("Data inside folder will NOT be destroyd."))
6
+        data_label = Gtk.Label(label=_("Data inside folder will NOT be destroyed."))
7
         data_label.set_margin_top(24)
8
 
9
                 
10
@@ -568,7 +568,7 @@
11
         drop_index = self.view_vault_index - 1 # -1 because 0 the default vault, 1 - n user vaults
12
                                                # and we are always dropping _user_ vault.
13
         
14
-        # We need to get activa vault path before deleting anythin because active 
15
+        # We need to get activa vault path before deleting anything because active 
16
         # vault is saved as index and deleting anything can mess that up
17
         # and we need to restore correct active vault after droip.
18
 
19
@@ -876,7 +876,7 @@
20
             self.info_label.set_use_markup(True)
21
 
22
     def cloning_completed(self):
23
-        self.info_label.set_text("<small>Project cloned succesfully.</small>")
24
+        self.info_label.set_text("<small>Project cloned successfully.</small>")
25
         self.info_label.set_use_markup(True)
26
         self.create_button.set_sensitive(False)
27
             
28
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/projectmediaimport.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/projectmediaimport.py Changed
11
 
1
@@ -73,7 +73,8 @@
2
         
3
         target_project.c_seq = target_project.sequencestarget_project.c_seq_index
4
 
5
-        # Media file media assets and generator assets are handled a differently.
6
+        # Media file media assets are imported and generator assetsfile is used to info user
7
+        # generator clips are not imported.
8
         media_assets = ""
9
         generator_assets = 
10
 
11
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/propertyeditorbuilder.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/propertyeditorbuilder.py Changed
31
 
1
@@ -82,8 +82,8 @@
2
 REGION_EDITOR_BUILDER = "region_properties"                 # Creates a single row editor for multiple properties of region transition
3
 ROTATION_GEOMETRY_EDITOR_BUILDER = "rotation_geometry_editor" # Creates a single editor for multiple geometry values
4
 INFOANDTIPS = "infotips"                                    # Displays link to docs Info & Tips page 
5
-ANALYZE_STABILIZE = "analyzestabilize"                      # Launches stabilizing analyzis for clip
6
-ANALYZE_MOTION = "analyzemotion"                            # Launches motion tracking analyzis for clip
7
+ANALYZE_STABILIZE = "analyzestabilize"                      # Launches stabilizing analysis for clip
8
+ANALYZE_MOTION = "analyzemotion"                            # Launches motion tracking analysis for clip
9
 APPLY_MOTION = "applymotion"                                # Applies motion tracking as source image movement.
10
 APPLY_FILTER_MASK_MOTION = "applyfiltermaskmotion"          # Applies motion tracking as filter mask.
11
 SCALE_DIGITS = "scale_digits"                               # Number of decimal digits displayed in a widget
12
@@ -684,9 +684,6 @@
13
 def _get_fade_length_editor(editable_property):
14
     return FadeLengthEditor(editable_property)
15
 
16
-
17
-
18
-
19
 def _get_file_select_editor(editable_property):
20
     """
21
     Returns GUI component for selecting file of determined type
22
@@ -716,7 +713,7 @@
23
     file_select_button.set_size_request(210, 28)
24
     # TODO: check this out
25
     if hasattr(editable_property, "value") and editable_property.value != '' and editable_property.value != '""':
26
-        file_select_button.set_uri(GLib.filename_to_uri(editable_property.value))
27
+        file_select_button.set_filename(editable_property.value)
28
 
29
     file_select_label = Gtk.Label(label=editable_property.get_display_name())
30
 
31
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/propertyparse.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/propertyparse.py Changed
28
 
1
@@ -39,7 +39,7 @@
2
 ARGS = appconsts.ARGS
3
 SCREENSIZE = "SCREENSIZE"                                   # replace with "WIDTHxHEIGHT" of profile screensize in pix
4
 SCREENSIZE2 = "Screensize2"                                 # replace with "WIDTH HEIGHT" of profile screensize in pix
5
-WIPE_PATH = "WIPE_PATH"                                     # path to folder contining wipe resource images
6
+WIPE_PATH = "WIPE_PATH"                                     # path to folder containing wipe resource images
7
 SCREENSIZE_WIDTH = "SCREENSIZE_WIDTH"                       # replace with width of profile screensize in pix
8
 SCREENSIZE_HEIGHT = "SCREENSIZE_HEIGHT"                     # replace with height of profile screensize in pix
9
 VALUE_REPLACEMENT = "value_replacement"                     # attr name for replacing value after clip is known
10
@@ -362,7 +362,7 @@
11
     
12
 def rotating_geom_keyframes_value_string_to_geom_kf_array(keyframes_str, out_to_in_func):
13
     # THIS WAS CREATED FOR frei0r cairoaffineblend FILTER. That filter has to use a very particular parameter values
14
-    # scheme to satisty the frei0r requirement of all float values being in range 0.0 - 1.0.
15
+    # scheme to satisfy the frei0r requirement of all float values being in range 0.0 - 1.0.
16
     #
17
     # Parse extraeditor value properties value string into (frame, x, y, x_scale, y_scale, rotation, opacity)
18
     # keyframe tuples used by keyframeeditorcanvas.RotatingEditCanvas editor.
19
@@ -423,7 +423,7 @@
20
         # and rotate image automatically around its tramslated center point.
21
         #
22
         # So the we need to add half of width and height to mlt values AND 
23
-        # addional linear correction based on applied scaling when creating
24
+        # additional linear correction based on applied scaling when creating
25
         # keyframes for keyframecanvas.RotatingEditCanvas editor.
26
         x = float(values0) + float(screen_width) / 2.0 + \
27
             ((x_scale * screen_width) - screen_width) / 2.0
28
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/render.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/render.py Changed
37
 
1
@@ -52,7 +52,7 @@
2
 import userfolders
3
 import utils
4
 
5
-# User defined render agrs file extension
6
+# User defined render args file extension
7
 FFMPEG_OPTS_SAVE_FILE_EXTENSION = ".rargs"
8
 
9
 # These consts only applicable here, used in timeline clip slowmotion and reverse code.
10
@@ -414,7 +414,7 @@
11
     dialog.destroy()
12
 
13
     # Get render range for new media and information needed for clip.slowmo_data 
14
-    # used to eanble further slowmo renders to produce timeline clips with the 
15
+    # used to enable further slowmo renders to produce timeline clips with the 
16
     # same content area.
17
     if clip.slowmo_data == None:
18
         orig_file_path = clip.path
19
@@ -428,7 +428,7 @@
20
                                           orig_media_out, speed,
21
                                           range_selection)
22
     else:
23
-        # clip.slowmo_data is set after succesful slowmo render when new rendered clip
24
+        # clip.slowmo_data is set after successful slowmo render when new rendered clip
25
         # is placed on timeline.
26
         slowmo_type, orig_file_path, slowmo_clip_media_area, current_speed, orig_media_in, orig_media_out = clip.slowmo_data
27
 
28
@@ -549,7 +549,7 @@
29
             _compute_reverse_render_range(media_file_length, producer_length, orig_media_in, \
30
                                           orig_media_out, speed, range_selection)
31
     else:
32
-        # clip.slowmo_data is set after succesful slowmo render when new rendered clip
33
+        # clip.slowmo_data is set after successful slowmo render when new rendered clip
34
         # is placed on timeline.
35
         slowmo_type, orig_file_path, slowmo_clip_media_area, current_speed, orig_media_in, orig_media_out = clip.slowmo_data
36
 
37
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/rendergui.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/rendergui.py Changed
10
 
1
@@ -1290,7 +1290,7 @@
2
         self.display_selection_callback = display_selection_callback
3
         
4
         self.args_edit_window = None
5
-        self.text_buffer = None # only used here for small screen heights with dialog for setting agrs, but this value is always tested to determine where to get agrs if set
6
+        self.text_buffer = None # only used here for small screen heights with dialog for setting args, but this value is always tested to determine where to get args if set
7
         self.ext = ""
8
                 
9
         self.use_args_label = Gtk.Label(label=_("Render using args"))
10
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/css3/bold-text-class.css Added
5
 
1
@@ -0,0 +1,3 @@
2
+.bold-text {
3
+  font-weight: bold;
4
+}
5
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/css3/middlebar-id.css Added
5
 
1
@@ -0,0 +1,3 @@
2
+#middlebar {
3
+  background-color: #363636;
4
+}
5
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/css3/player-bar-id.css Added
6
 
1
@@ -0,0 +1,4 @@
2
+#player-bar {
3
+  background-color: #363636;
4
+  border-radius: 10px;
5
+}
6
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/css3/sass/_common.scss -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/css3/sass/_common.scss Changed
10
 
1
@@ -340,7 +340,7 @@
2
 
3
   &.flat {
4
     @include button(undecorated);
5
-    // to avoid adiacent buttons borders clashing when transitioning, the transition on the normal state is set
6
+    // to avoid adjacent buttons borders clashing when transitioning, the transition on the normal state is set
7
     // to none, while it's added back in the hover state, so the button decoration will fade in on hover, but
8
     // it won't fade out when the pointer leave the button allocation area. To make the transition more evident
9
     // in this case the duration is increased.
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/clip_button.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/clip_button.png Changed
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/container_sequence_link_icon.png Added
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/filters_down_arrow.png Added
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/filters_up_arrow.png Added
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_clear_xs.png Added
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_in_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_in_s.png Changed
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_in_xs.png Added
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_out_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_out_s.png Changed
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/mark_out_xs.png Added
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/marks_clear_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/marks_clear_s.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/next_frame_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/next_frame_s.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/play_2_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/play_2_s.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/prev_frame_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/prev_frame_s.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/program_view_2.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/program_view_2.png Changed
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/set_track_sync.png Added
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/slowmo.png Added
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/stop_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/stop_s.png Changed
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/sync_menu_launch.png Added
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/timeline_button.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/timeline_button.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/to_mark_in_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/to_mark_in_s.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/to_mark_out_s.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/to_mark_out_s.png Changed
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/track_sync_icon.png Added
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/darktheme/trim_view.png -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/darktheme/trim_view.png Changed
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/filters/filters.xml -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/filters/filters.xml Changed
10
 
1
@@ -547,7 +547,7 @@
2
         <extraeditor name="infotips" args="header=Compressor"></extraeditor> 
3
         <property name="0" args="range_in=0,100 range_out=0,1 editor=ladspa_slider displayname=RMP-peak">0</property>
4
         <property name="1" args="range_in=1.5,400 range_out=1.5,400 editor=ladspa_slider displayname=Attack(ms)">100</property>
5
-        <property name="2" args="range_in=2,800 range_out=2,800 editor=ladspa_slider displayname=Relese(ms)">400</property>
6
+        <property name="2" args="range_in=2,800 range_out=2,800 editor=ladspa_slider displayname=Release(ms)">400</property>
7
         <property name="3" args="range_in=-30,0 range_out=-30,0 editor=ladspa_slider displayname=Threshold(dB)">0</property>
8
         <property name="4" args="range_in=1,20 range_out=1,20 editor=ladspa_slider displayname=Ratio">1</property>
9
         <property name="5" args="range_in=1,10 range_out=1,10 editor=ladspa_slider displayname=Knee!Radius(dB)">3.25</property>
10
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/advanced.html Added
201
 
1
@@ -0,0 +1,1165 @@
2
+<!DOCTYPE html>
3
+<html>
4
+<head>
5
+  <title>Advanced Editing</title>
6
+  <link rel="stylesheet" href="style.css">
7
+<script src="toc.js" type="text/javascript"></script>
8
+</head>
9
+
10
+<body>
11
+
12
+<div id="content">
13
+<img src="header_text_5.png">
14
+
15
+<script src="tocgen.js"></script>
16
+
17
+<div id="toccontent">
18
+
19
+<div id="advtoc">
20
+<div class="subject-header">Advanced Editing Features</div>
21
+</div>
22
+
23
+<div id="toc"></div>
24
+
25
+
26
+
27
+<h2>1. Sync Editing</h2>
28
+<p>
29
+In Flowblade Movie Editor sync editing workflow is to <b>set clip's positions to follow another clip's positions</b> on request.
30
+</p>
31
+<ul>
32
+<li> Sync relation between two clips is set by either setting relation individually, doing audio splits or setting sync relation for all clips on a track or a box selection in single action </li>
33
+<li> Clips that have lost sync with their parent clips can be resynced one or more at a time or by resyncing a whole track in single action.</li>
34
+</ul>
35
+
36
+<p>
37
+Below we give suggested workflows for three typical use cases for utilizing Flowblade's sync editing features.
38
+</p>
39
+<ul>
40
+<li> Generic work preserving sync editing. </li>
41
+<li> Editing to audio, such as when creating music videos or voice over driven programs. </li>
42
+<li> Dialogue editing. </li>
43
+</ul>
44
+
45
+
46
+
47
+<h3>Setting up Sync Relations</h3>
48
+
49
+<p>
50
+There are three ways to set up a sync relation between clips: 
51
+</p>
52
+
53
+<h4>Clip Parenting</h4>
54
+
55
+<p>
56
+Explicitly set Sync relation between two clips set up by selecting a <b>Sync Parent Clip</b> for a <b>Sync Child Clip</b>.
57
+</p>
58
+
59
+<ul>
60
+<li> Click <b>Right Mouse</b> on clip and select <b>Edit->Select Sync Parent Clip...</b>.</li>
61
+<li> Or Click <b>Right Mouse</b> on clip that is part of a multiclip selection and and select <b>Select Sync Parent Clip...</b>.</li>
62
+<li> Cursor turns into a Target Cross. Click on a clip to select it as <b>Sync Parent Clip</b>.</li>
63
+</ul>
64
+
65
+<h4>Audio Splitting</h4>
66
+
67
+<p>
68
+Split a video clip into two clips: a muted video clip as <b>Sync Parent Clip</b> and an audio clip as <b>Sync Child Clip</b>.
69
+</p>
70
+
71
+<ul>
72
+<li> Click <b>Right Mouse</b> on clip and select <b>Audio Edit->Split Audio Synched</b>.
73
+<li> When multple Clips are selected click <b>Right Mouse</b> on clip and select <b>Split Audio Synched</b>.
74
+<li>A new synched Audio Clip/s is placed on audio Track, either on V1 or mirrored track based on current preference.</li>
75
+<li> If you select from <b>Sync Properties</b> menu property <b>Auto Sync Split Video Clips on Add</b> video clips will be split automatically when added to certain tracks. 
76
+</li>
77
+</ul>
78
+
79
+<h4>Track Auto Parenting</h4>
80
+<p>
81
+Set all clips on track as <b>Sync Child Clips</b> to closest clips on the selected Track as <b>Sync Parent Clips</b>. 
82
+</p>
83
+<ul>
84
+<li> Click <b>Right Mouse</b> on a Track in the left side Tracks Column area and select <b>Sync All Clips To Track... </b>.</li>
85
+<ul>
86
+<li>Select sync parenting target Track using the dialog window.</li>
87
+<li>A sync relation is created for all Clips on Track.</li>
88
+<li>An icon appers on Track Head in in the Tracks Column to indicate that updating sync is now posibble.</li>
89
+</ul>
90
+<li>Once a Track has been auto parented it remembers the target Track and parenting can be updated by clicking <b>Right Mouse</b> on a Track Head and selecting <b>Update Sync to Clips' Current Positions</b>.</li>
91
+<li> Click <b>Right Mouse</b> on a Track Head and select <b>Clear Sync</b> to clear all sync relations on a Track and info on parenting target Track.</li>
92
+</ul>
93
+
94
+
95
+<h3>Resyncing</h3>
96
+
97
+<h4>Single Clip</h4>
98
+<ul>
99
+<li> Click <b>Right Mouse</b> on Sync Child Clip and select <b>Edit->Resync</b> from popup menu to resync single clip.</li>
100
+<li> Press <b>Resync Selected Clips</b> Button to resync single clip.</li>
101
+</li>
102
+</ul>
103
+
104
+<h4>Multiple Clips</h4>
105
+<ul>
106
+<li> Press <b>Resync Selected Clips</b> Button to resync selected clips clip.</li>
107
+<li> Click <b>Right Mouse</b> on <b>Sync Child Clip</b> that is part of a multiclip selection and and select <b>Resync</b> from popup menu to resync single clip.</li>
108
+</li>
109
+</ul>
110
+
111
+<h4>All Clips on a Track</h4>
112
+<ul>
113
+<li> Select from application menu <b>Edit->Resync Track</b> to resync all clips in the track containing currently selected clip.</li>
114
+<li> Press <b>Resync Track Containing Selected Clip</b> Button to resync all clips in the track containing currently selected clip.</li>
115
+</ul>
116
+
117
+<h3>Clearing Sync Parent Relations </h3>
118
+<ul>
119
+<li> Click <b>Right Mouse</b> on Sync Child Clip and select <b>Edit->Clear Sync Relation</b>.</li>
120
+<li> Or Click <b>Right Mouse</b> on clip that is part of a multiclip selection and and select <b>>Clear Sync Relations</b>.</li>
121
+</ul>
122
+
123
+<h3>Workflows</h3>
124
+
125
+<h4> Generic work preserving sync editing</h4>
126
+<p>
127
+Most edits require clips on different tracks to maintain positions relative to each other, such as a title placed on top of a video clip.
128
+</p>
129
+<p>
130
+Many edit actions necessarily change the positions of clips differently on different tracks. Sync editing tools provide quick workflow to regain sync between clips.
131
+</p>
132
+<ul>
133
+<li> It is often useful to treat track <b>V1</b> as a master track, and have all other tracks relate positions to track <b>V1</b>.</li>
134
+<li> Set sync relations for individual or multiple selected clips.</li>
135
+<li> If there exists many clips of similar type that require synching, dedicate a track to that type of clips and use track syncing features to keep that track in sync.</li>
136
+<li> If program features multiple clearly defined complex scenes one approach is to:
137
+    <ul>
138
+    <li> Parent first clip of the scene on each track to the first clip of scene on track <b>V1</b>.</li>
139
+    <li> Use <b>Spacer</b> tool with <b>Control</b> modifier to sync tracks manually at scene start when needed.</li>
140
+    <li> Or use track syncing.</li>
141
+    </ul>
142
+</li>
143
+</ul>
144
+
145
+
146
+<h4>Editing to audio</h4>
147
+<p>
148
+When creating music videos or voice over driven programs it is useful to use a single audio track as sync target track for most ar all other element in the sequence.</li>
149
+</p>
150
+
151
+<ul>
152
+<li> Place the program defining audio of track <b>A1</b> and treat that as a master track.</li>
153
+<li> Have all other tracks and clips relate their positions to track <b>A1</b>.</li>
154
+<li> With music videos it is useful to use a large number of track dedicated to invidual types of visual elements, and use excusively track syncing featues instead of setting sync to individual clips.</li>
155
+</ul>
156
+
157
+<h4> Dialogue editing</h4>
158
+<p>
159
+Editing dialogue scenes frequently require actor's voice to start before or end after the image of the character speaking. These types of edit are knowns as J- and L-cuts.
160
+</p>
161
+<ul>
162
+<li> Dedicate tracks <b>V1</b>, <b>V2</b>, <b>A1</b> and <b>A2</b> to dialoque video and audio.</li>
163
+<li> Select from <b>Sync Properties</b> menu on the left behaviour that suits your preferences.
164
+    <ul>
165
+    <li> <b>Auto Sync Split Video Clips on Add</b> has multiple options to select which tracks do this.</li>
166
+    <li> <b>Audio Split To Mirrored Track</b> behaviour can be turned on and off.</li>
167
+    </ul>
168
+</li>
169
+<li> When creating J- or L-cuts use methods that maintain sync to minimize the need to resync:
170
+    <ul>
171
+    <li> When using <b>Trim</b> tool, use <i>Two Roll Trim</i> instead of <i>One Roll Trim</i>.</li>
172
+    <li> When dragging clip ends use <b>Alt</b> modifier to do <b>Clip End Overwrite Drag</b> actions.</li>
173
+    </ul>
174
+</li>
175
+<li> Use exclusively track resyncing actions to keep audio on tracks <b>A1</b> and <b>A2</b> synced.</li>
176
+</ul>
177
+
178
+
179
+<h3>Sync UX</h3>
180
+<h4>Buttons</h4>
181
+
182
+<p>
183
+There are 4 buttons in the <b>Middlebar</b>, from left to right:
184
+</p>
185
+    <ul>
186
+     <li><b>Split Audio Synched</b></li>
187
+     <li><b>Set Sync for All Clips on Track Containing Selected Clip/s</b></li>
188
+     <li><b>Resync Track Containing Selected Clip/s</b></li>
189
+     <li><b>Resync Selected Clips</b></li>
190
+     </ul>
191
+<h4>Menus</h4>
192
+<p>
193
+There are 4 menus available at various places to provide sync editing functionality:
194
+</p>
195
+<ul>
196
+ <li><b>Sync Properties Menu</b> above <b>Tracks Column</b> allows for setting sync editing properties.</li>
197
+ <li><b>Track Menu</b> available in <b>Tracks Column</b> provides Track sync actions.</li>
198
+ <li><b>Clip Menu</b> provides sync actions applied to single clips.</li>
199
+ <li><b>Multi Clip Selection Menu</b> provides sync actions applied to multiple clips.</li>
200
+ </ul>
201
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/all_comp.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/ru/all_comp.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/basic_editing.html Added
201
 
1
@@ -0,0 +1,329 @@
2
+ <!DOCTYPE html>
3
+<html>
4
+<head>
5
+  <title>Basic Editing</title>
6
+  <link rel="stylesheet" href="style.css">
7
+</head>
8
+
9
+<body>
10
+
11
+<div id="content">
12
+<img src="header_text_5.png" >
13
+
14
+<script src="tocgen.js"></script>
15
+
16
+<div class="subject-header">Basic Editing</div>
17
+
18
+<p>
19
+This section describes the minimal workflow for making a movie using only a single track.
20
+</p>
21
+<div id="toc"></div>
22
+
23
+<div id="toccontent">
24
+
25
+<h3>Creating a New Project</h3>
26
+<p>
27
+Flowblade Movie Editor saves work in project files.
28
+</p>
29
+<p>
30
+To create a new Project:
31
+</p>
32
+<ul>
33
+<li> <b>Menu:</b> Select <b>File -> New</b> from menu.</li>
34
+<li> <b>Keyboard Shortcut:</b> Press <b>Control+N</b>.</li>
35
+</ul>
36
+<p>
37
+A project contains:
38
+</p>
39
+ <ul>
40
+<li> one or more Sequences of edited media</li>
41
+<li> a collection of Media Files stored in Bins.</li>
42
+</ul>
43
+<p>
44
+There are two parameters that can be selected for a new project:
45
+</p>
46
+<ul style="list-style-type:none">
47
+<li> <b>Project Profile</b> Project Profile determines frame rate per second, image size in pixels and pixel aspect ratio.</li>
48
+<li> <b>Tracks count</b> Select the number of video and audio tracks that are used in the project. This can be changed later, but the operation destroys the Undo / Redo stack and all the Timeline Clips that do not fit in the newly created version of the Sequence.</li>
49
+<li> <b>Data Store</b> Thumbnails, Generator and Rendered Transitions, stabilizing and motion tracking data, proxy files etc. are stored here in a <b>Data Store</b>, see chapter: <a href="datastores.html">Data Stores</a>.
50
+
51
+
52
+</ul>
53
+
54
+<div class="note">
55
+Flowblade Movie Editor handles image data internally as YUV420 frames, so the encoding associated with a given profile has no affect on quality before rendering.
56
+</div>
57
+<div class="note">
58
+For <b>best possible quality</b> the <b>input material, Project Profile and Rendering Profile</b> should <b>all have the same pixel dimensions</b> and pixel aspect ratio.
59
+</div>
60
+
61
+<h3>Adding and removing new Sequences</h3>
62
+<p>
63
+A Project contains one or more Sequences. The term Sequence refers to the full contents of the timeline forming a program, a movie.
64
+</p>
65
+
66
+<p>
67
+For complex projects it is sometimes best to use multiple sequences for creating and managing different parts of the finished product.
68
+</p>
69
+
70
+<p>
71
+<b>Adding Sequences:</b>
72
+</p>
73
+<ul>
74
+<li> <b>Default layout:</b> Press <b>Right Mouse</b> popup menu on Sequences area and select menu item <b>Add New Sequence</b>..</li>
75
+<li> <b>Small screen layout:</b> Press <b>Right Mouse</b> popup menu in the <b>Project</b> tab <b>Sequences</b> area and select menu item <b>Add New Sequence</b>.</li>
76
+<li> Or select  <b>Project -> Sequence -> Add New Sequence</b> from application menu.</li>
77
+</ul>
78
+
79
+
80
+<p>
81
+<b>Deleting Sequences</b> can be done with menu actions accessed in the same places.
82
+</p>
83
+
84
+<div class="note">
85
+<p>
86
+When creating a new Sequence, you can choose the number of Tracks in the Sequence. This can be changed later, but the operation destroys the Undo / Redo stack and all the Timeline Clips that do not fit in the newly created version of the Sequence.
87
+</p>
88
+</div>
89
+
90
+<h3>Working with Media Files</h3>
91
+
92
+<p>
93
+Flowblade Movie Editor holds files in <b>Media</b> tab. Files are listed in unnamed table that displays contents of the currently selected Bin. Bins are listed in the <b>Bins</b> table.
94
+</p>
95
+
96
+<p>
97
+<b>Opening Media Files:</b>
98
+</p>
99
+
100
+<ol>
101
+<li> Press <b>Right Mouse</b> on <b>Media</b> tab empty area and select menu item <b>Add Video, Audio or Image...</b>.
102
+<li> Or select  <b>Project -> Add Video, Audio or Image...</b> from application menu.
103
+<li> Use dialog to find and select files.</li>
104
+<li> Files are displayed as thumbnails.</li>
105
+<li> Note that creating thumbnails for opened files will take some time.</li>
106
+</ol>
107
+
108
+<div class="note">
109
+<h3 style="margin-top:10px">Project Media: Absolute and relative paths</h3>
110
+<ul>
111
+<li> Flowblade <b>saves references</b> to media files used in a project as <b>absolute paths</b>.</li>
112
+<li> If a media is <b>not found on load</b>, Flowblade attempts to find a media file with the same name in subfolders relative to the project file.</li>
113
+<li> If all media used by a project is saved in subfolders relative to project file, <b>project file and media can moved as a unit</b> and the project will load successfully after data is copied to a different place</li>
114
+<li> <b>Rendered files</b> like transitions are saved by default in a <b>Data Store</b>, see chapter: <a href="datastores.html">Data Stores</a>.</li>
115
+<li> <b>Load order</b> between absolute and relative paths can be set in preferences window</li>
116
+<li> <b>Media Relinker</b> tool can be used to fix problems that may occur </li>
117
+</ul>
118
+</div>
119
+
120
+<h3>Working with Bins</h3>
121
+
122
+<p>
123
+In video editing a bin is a named location for storing media. The term is used in Avid and was earlier used by film editors.
124
+</p>
125
+
126
+<p>
127
+    <b>Adding a Bin:</b>
128
+<p>
129
+<ul>
130
+<li> <b>Default layout:</b> Press <b>Right Mouse</b> on Bin area to launch a popup menu and select menu item <b>Add Bin</b>.</li>
131
+<li> <b>Small screen layout:</b> Press <b>Right Mouse</b> in the <b>Media</b> tab <b>Bins</b> panel to launch a popup menu and select menu item <b>Add Bin</b>.</li>
132
+<li> Or select  <b>Project -> Bin -> Add Bin</b> from application menu.</li>
133
+</ul>
134
+
135
+<p><b>Deleting a Bin</b>: Delete actions can be accessed from the same places as above.</p>
136
+<p><b>Renaming a Bin</b>: Click on the Bin name, type new name and press <b>Enter</b>.</p>
137
+<p><b>Moving files to another Bin:</b></p>
138
+<ul>
139
+<li> Select and drag files on top of the Bin you wish to move the files into.</li>
140
+<li> Select files and open <b>Hamburger menu</b> in <b>Media</b> panel and select menu item <b>Move Selected media to Bin</b> and then the menu item with the Bins name.</li>
141
+</ul>
142
+<div class="tabbed">
143
+
144
+</div>
145
+
146
+<h4>Filtering Bin View</h4>
147
+<p>
148
+    Bins can be made to display only subset of media items they contain. Press on filtering button in <b>Media Panel</b> bottom row next <b>Hamburger</b> and <b>columns</b> buttons.
149
+<p>
150
+    <ul>
151
+    <li> <b>Filtering by media type.</b> Select one of options <i>All Files, Video Files Audio Files, Graphics Files, Image Sequences, Pattern Producers, Unused Files</i>.</li>
152
+    <li> <b>Filtering by ratings.</b> Select one of options in submenu <i>Ratings</i>, either <i>Show All Ratings, Show Favorites, Hide bad</i>. Each media item can be given a rating in context popover submenu <i>Rating</i>.</li>
153
+    </ul>
154
+    
155
+<h3>Using Timeline</h3>
156
+
157
+<h4>Scrolling Timeline</h4>
158
+<ul>
159
+<li> Press and Drag <b>Scrollbar</b> below Timeline</li>
160
+<li> Scroll <b>Mouse Middle</b> button + <b>CTRL</b> key while on top of Timeline</li>
161
+</ul>
162
+
163
+<h4>Zooming Timeline</h4>
164
+<ul>
165
+<li> Click <b>Zoom In</b>, <b>Zoom Out</b> or <b>Zoom Length</b> buttons.</li>
166
+<li> Scroll <b>Mouse Middle</b> button on top of Timeline </li>
167
+</ul>
168
+
169
+<h4>Changing Current Frame</h4>
170
+<ul>
171
+<li> Drag with <b>Right Mouse</b> button starting from  an empty space in the Timeline.</li>
172
+<li> Drag with <b>Left Mouse</b> button on the Frame Scale.</li>
173
+<li> Drag with <b>Left Mouse</b> on the Monitor Position Bar.</li>
174
+<li> Click <b>Left Arrow</b> key or <b>Right Arrow</b> key to move to next or previous frame.</li>
175
+<li> Click <b>Up Arrow</b> key or <b>Down Arrow</b> key to move to next or previous cut on topmost active track.</li>
176
+<li> Click <b>Next</b> or <b>Prev</b> button in Monitor Buttons area to move to next or previous frame.</li>
177
+</ul>
178
+
179
+<h4>Changing Current Frame when Clip is displayed on Monitor</h4>
180
+<ul>
181
+<li> Drag with <b>Left Mouse</b> on the Monitor Position Bar.</li>
182
+<li> Click <b>Left Arrow</b> key or <b>Right Arrow</b> key to move to next or previous frame.</li>
183
+<li> Click <b>Up Arrow</b> key or <b>Down Arrow</b> key to move to next or previous of the following: Mark In/Mark Out/Start/End</li>
184
+<li> Click <b>Next</b> or <b>Prev</b> button in Monitor Buttons area to move to next or previous frame.</li>
185
+</ul>
186
+
187
+<h4>Switching between Timeline and Clip Display</h4>
188
+<ul>
189
+<li> Click buttons with icons representing sequence or single clip in Monitor Buttons area.</li>
190
+<li> Drag Media File on top of <b>Monitor</b> to display Clip.</li>
191
+</ul>
192
+
193
+<h4>Setting Active Tracks</h4>
194
+<ul>
195
+<li> Click <b>Track Active Switch</b> on the right side of Tracks Column area. Topmost  <b>Track Active Switch</b> displays arrow pointing downwards indicating that <b>Insert From Monitor</b> and other buttons place clips on that track.</li>
196
+</ul>
197
+
198
+<div class="note">
199
+<h4>Effects of Track Active State</h4>
200
+<ul>
201
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/blender_clip_editor.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/blender_clip_editor.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/blender_color_editor.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/blender_color_editor.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/blender_script.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/blender_script.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/blender_string_editor.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/blender_string_editor.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/comp_clips.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/comp_clips.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/compositor.html Added
201
 
1
@@ -0,0 +1,221 @@
2
+ <!DOCTYPE html>
3
+<html>
4
+<head>
5
+  <title>Creating Composited Images</title>
6
+  <link rel="stylesheet" href="style.css">
7
+</head>
8
+
9
+<body>
10
+
11
+<div id="content">
12
+<img src="header_text_5.png" >
13
+
14
+<script src="tocgen.js"></script>
15
+
16
+<div id="toccontent">
17
+
18
+<div class="subject-header">Creating Composited Images</div>
19
+
20
+<p>
21
+Flowblade Movie Editor uses Compositors to mix images from two different tracks.
22
+</p>
23
+
24
+<div id="toc"></div>
25
+
26
+<h3>Compositing Modes</h3>
27
+<p>
28
+The way that Compositors work is defined by a Compositing Mode. Users can select Compositing Mode to suit their preference or editing needs of a particular Sequence.
29
+</p>
30
+<p>
31
+<b>To set Compositing Mode</b> for a Sequence select it from <b><i>Sequence -> Compositing Mode</i></b> sub menu.
32
+</p>
33
+
34
+<h4>Standard Full Track</h4>
35
+<p>
36
+This is the most simple and easiest to use Compositing Mode. No Compositors are needed. Fade In/Outs, Wipes and transforms are created with Filters. Some compositing functionality is not available. It is not possible to create node tree compositions
37
+</p>
38
+<h4>Compositor Free Move</h4>
39
+<p>
40
+This is the most powerful and complex Compositing Mode. Users can set destination tracks and positions of Compositors freely and create node tree compositions if needed.
41
+</p>
42
+
43
+<h2>Standard Full Track Compositing Mode</h2>
44
+<p>
45
+Compositing in Standard Full Track mode is similar to using layers in applications like Gimp and Photoshop.
46
+
47
+
48
+<h3>Workflow</h3>
49
+<h4>Creating layered compositions</h4>
50
+
51
+<ul>
52
+<li> Add Clips on Timeline on different tracks.</li>
53
+<li> Images are composited in bottom to top order.</li>
54
+<li> Images with alpha channel are composited with transparency as defined by alpha channel.</li>
55
+<li> Use Filters to create Dissolves, Wipes, Blends and affine transforms.</li>
56
+</ul>
57
+
58
+<h4>Dissolves</h4>
59
+<ul>
60
+<li> Add Clips on Timeline on different tracks.</li>
61
+<li> Add <b>Fade In</b> or <b>Fade Out</b> Filters to Clip on the upper track to create Dissolves with Clip on the lower track.</li>
62
+<li> <b>Fade In</b> and <b>Fade Out</b> Filters are in <b>Fade</b> Filter category.</li>
63
+</ul>
64
+
65
+<h4>Dissolves - Rendered Transition</h4>
66
+
67
+<ul>
68
+<li> Select two Clips on the same track.</li>
69
+<li> Press <b>Add Rendered Transition</b> button in middlebar.</li>
70
+<li> Give length of rendered transition and press <b>Render</b> button.</li>
71
+</ul>
72
+
73
+<h4>Blends</h4>
74
+<ul>
75
+<li> Add Clips on Timeline on different tracks.</li>
76
+<li> Add <b>Blend</b> Filter to Clip on the upper track to control blend mode used when compositing image on top of the Clip on the lower track.</li>
77
+<li> <b>Blend</b> Filters can be combined with other Filters to create compositions as wished.</li>
78
+<li> <b>Blend</b> Filters are in <b>Blend</b> Filter category.</li>
79
+</ul>
80
+
81
+<h4>Wipes</h4>
82
+<ul>
83
+<li> Add Clips on Timeline on different tracks.</li>
84
+<li> Add <b>Wipe</b> Filters to the top Clip to create wipe transitions.</li>
85
+<li> <b>Wipe</b> Filters are in <b>Blend</b> Filter category.</li>
86
+</ul>
87
+
88
+<h4>Alpha channel manipulation: Keys, Rotomasks etc.</h4>
89
+<ul>
90
+<li> Add Clips on Timeline on different tracks.</li>
91
+<li> Use appropriate Filters in <b>Alpha</b> Filter category to create more complex compositing operations such as color keys, shaped masks or animated masks.</li>
92
+</ul>
93
+
94
+<h4>Transforms</h4>
95
+<ul>
96
+<li> Add Clips on Timeline on different tracks.</li>
97
+<li> Add <b>Position Scale</b> or <b>Position Scale Rotation</b> Filters to the top Clip to move, rotate and scale image before it is composited on lower track.</li>
98
+<li> These Filters are in <b>Transform</b> Filter category.</li>
99
+</ul>
100
+
101
+<h2>Compositor Free Move Compositing mode</h2>
102
+<p>
103
+In this modes Compositors have a Source track and a Destination track.</p>
104
+</p>
105
+<p>
106
+On the Timeline a Compositor is displayed as a rectangular object on top of two tracks. Source track is always the one above Compositor, but Destination track may be any of the tracks below it.
107
+</p>
108
+<p>
109
+Parameters defining the resulting image are edited in the <b>Edit</b> tab.
110
+</p>
111
+
112
+<h3>Workflow</h3>
113
+<p>
114
+By combining multiple tracks and multiple Compositors complex composite images can be achieved.
115
+</p>
116
+<ol>
117
+<li>Creating a Compositor
118
+<ul>
119
+<li> Click <b>Right Mouse</b> on any clip on tracks from V5 to V2 and select for example <b>Add Compositor -> Dissolve</b> or <b>Add Blender -> Softlight</b> from popupmenu to create a new Compositor.</li>
120
+</ul>
121
+<li>Trimmimg or Moving a Compositor</li>
122
+<ul>
123
+<li> To trim Compositor start and end points: Press and drag <b>Left Mouse</b> near either end of Compositor on Timeline.</li>
124
+<li> To move Compositor: Press and drag <b>Left Mouse</b> in the middle of Compositor on Timeline.</li>
125
+</ul>
126
+<li>Editing Compositor Parameters in Compositors Tab</li>
127
+<ul>
128
+<li> Double click Compositor with <b>Left Mouse</b>.</li>
129
+<li> Click <b>Right Mouse</b> on any Compositor and select Open In Compositor Editor</li>
130
+<li> Edit parameters using value editors.</li>
131
+</ul>
132
+<li>Deleting Compositor</li>
133
+<ul>
134
+<li> Click <b>Left Mouse</b> on any Compositor to select it and press <b>Delete</b> key.</li>
135
+</ul>
136
+</ol>
137
+
138
+<h3>Compositor are executed from top to bottom in Top Down Compositing modes</h3>
139
+In Flowblade Movie Editor <b>the order of rendering is top-to-bottom</b>,
140
+instead of bottom-to-top like in Gimp or Photoshop.
141
+
142
+When attempting certain type of multilayer composites this yields results that seem unintuitive,
143
+unless the user is aware of rendering order of Compositors.
144
+
145
+<h4>Rendering A Composited Frame</h4>
146
+<ol>
147
+<li>For each frame it is checked if there is a Compositor covering this frame on the top most track.</li>
148
+<li>If such Compositor is found, do composite on Destination track.</li>
149
+<li>Frame on Destination track is now altered and if that frame is used as source the altered version is used</li>
150
+<li>Check if frame on next track below has compositor and if Compositor is found render the composite image</li>
151
+<li>This is done for each track.</li>
152
+<li>Output image on is from the topmost track that has media on the frame and does not have a compostor on the frame.</li>
153
+</ol>
154
+
155
+<h3>Using Filters</h3>
156
+<p> Except for <b>Blend</b> Filter, all filters can used in the same way to achieve compositions as in <b>Standard Free Move</b> compositing mode.</p>
157
+
158
+<h3>EXAMPLE: Creating a 3-layer composite</h3>
159
+<p style="margin-bottom:45px" >
160
+In this example we demonstrate how top-to-bottom Compositor
161
+order affects compositing. We are trying to make word 'GO' appear on top of 2-color
162
+background made by combining red and blue Color Clips using 'Free Stripes' wipe.
163
+</p>
164
+<h4>Media Items and desired result</h4>
165
+<p>
166
+To make alpha transparency work the GO.PNG graphic has to composited using 'Dissolve'.
167
+</p>
168
+<p>
169
+<i><b>Clips: RED and BLUE Color Clips and GO.PNG graphic with alpha transparency</b></i>
170
+</p>
171
+<img src="comp_clips.png">
172
+
173
+<p>
174
+<i><b>Desired result</b></i>
175
+</p>
176
+
177
+<img style="margin-bottom:45px" src="correct_comp.png">
178
+
179
+<h4>Gimp/Photoshop style layer order yields wrong result</h4>
180
+<p>
181
+Here we have arranged clips on the tracks as we would arrange layers in Gimp.
182
+</p>
183
+<p>
184
+<i><b>Gimp style layer order</b></i>
185
+</p>
186
+<img src="wrong_timeline.png">
187
+
188
+<p>
189
+What happens here is that first 'GO.PNG' is composited on 'RED' Color Clip, and the resulting image is composited using 'Free Stripes' wipe on top of 'BLUE' Color Clip. We get the wrong result.
190
+</p>
191
+<p>
192
+<i><b>Wrong result</b></i>
193
+</p>
194
+<img  style="margin-bottom:45px" src="wrong_comp.png">
195
+<h4>Correct layer order when compositing order is top-to-bottom</h4>
196
+<p>
197
+Here we have arranged clips in correct order for the desired result.
198
+</p>
199
+<p>
200
+<i><b>Correct layer order</b></i>
201
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/container_clips.html Added
169
 
1
@@ -0,0 +1,167 @@
2
+<!DOCTYPE html>
3
+ 
4
+<html>
5
+<head>
6
+  <title>Container Clips</title>
7
+  <link rel="stylesheet" href="style.css">
8
+<script src="toc.js" type="text/javascript"></script>
9
+</head>
10
+
11
+<body>
12
+
13
+<div id="content">
14
+<img src="header_text_5.png">
15
+
16
+<script src="tocgen.js"></script>
17
+
18
+<div id="toccontent">
19
+
20
+<div class="subject-header">Container Clips</div>
21
+
22
+
23
+
24
+<div id="toc"></div>
25
+
26
+<h2>Container Clips Concept</h2>
27
+<p>
28
+A <b>Container Clip</b> is a Media Item and the Timeline Clip made from it that has three items packed together as a single entity: <i>Program, Unrendered Media</i> and <i>Rendered Media</i>.
29
+</p>
30
+<h3>Components</h3>
31
+<ol>
32
+<li><b>Unrendered Media</b> This is what is displayed on timeline if container clip media is not rendered.</li>
33
+<li><b>Program</b> This data is used to render a media clip on timeline, sometimes using unrendered media as input.</li>
34
+<li><b>Rendered Media</b> This is what is displayed on timeline when Container Clip is rendered.</li>
35
+</ol>
36
+
37
+<h2>Selection Container Clips</h2>
38
+<h5>Components</h5>
39
+<p>
40
+<ul style="list-style-type:none">
41
+<li><b>Unrendered Media</b> A MLT XML vdieo clip created from selection or sequence like Compound clips previously.</li>
42
+<li><b>Program</b> A MLT XML video clip created from selection or sequence like Compound clips previously. Here Program is the same as unrendered media.</li>
43
+<li><b>Rendered Media</b> Clip Rendered from MLT XML Clip.</li>
44
+</ul>
45
+</p>
46
+<h5>Use Cases</h5>
47
+
48
+<ul>
49
+<li>Make possible to create Media items from selections and full Sequences.</li>
50
+<li>Give better timeline performance for complex multitrack container clips by pre-rendering them on timeline.</li>
51
+</ul>
52
+
53
+<h5> Creating Selection Container Clip from Selection</h5>
54
+
55
+<ol>
56
+<li> Select 2 or more adjacent clips from a single track.</li>
57
+<li> Select <b>Project->Create Container Clip->From Selected Clips</b></li>
58
+<li> A new Media Item appears in the current Bin.</li>
59
+</ol>
60
+
61
+<h5> Creating Selection Container Clip from Sequence</h5>
62
+
63
+<ol>
64
+<li> Select <b>Project->Create Container Clip->From Current Sequence</b></li>
65
+<li> A new Media Item appears in the current Bin.</li>
66
+</ol>
67
+
68
+<h5> Creating audio synced Selection Container Clip from two Media Items</h5>
69
+
70
+<ol>
71
+<li> Select 2 Media Items in Media panel.</b>
72
+   <ul>
73
+   <li> The expected case is to select <b>1 Video and 1 Audio Clip</b>.</li>
74
+   <li> If you select <b>2 Video Clips</b> then which is used as video depends on selection order.</li>
75
+   <li> Audio from clip treated as video is muted.</li>
76
+   </ul>
77
+</li>
78
+<li> Select <b>Project->Create Compound Clip->Audio Sync Merge Clip From 2 Media Items</b></li>
79
+<li> If audio sync is successful a dialog appears. Give a name for the new Media Item in the dialog.</li>
80
+<li> A new Media Item appears in the current Bin.</li>
81
+</ol>
82
+
83
+<div class="note">
84
+Audio syncing looks for best mathemathical match between two audio waveforms, so <b>audio syncing non-matching audio will produce random results.</b>
85
+</div>
86
+
87
+<h2>Generator Container Clips</h2>
88
+<p>
89
+<b>Generators</b> are Container Clips too, see more info in chapter <a href="generatorsfluxity.html">Generators and Fluxity API</a>
90
+</p>
91
+
92
+<h2>Sequence Link Container Clips</h2>
93
+
94
+<p>
95
+<ul style="list-style-type:none">
96
+<li><b>Unrendered Media</b> A MLT XML video clip created or recreated from Contents of a Sequence on request</li>
97
+<li><b>Program</b>  Contents of a Sequence.</li>
98
+<li><b>Rendered Media</b> Clip Rendered from MLT XML Clip.</li>
99
+</ul>
100
+</p>
101
+
102
+<h5>Use Cases</h5>
103
+<ul>
104
+<li>Provide a convenient way to use Sequences as parts of a master Sequence.</li>
105
+</ul>
106
+
107
+<h5> Creating Sequence Link Container Clips</h5>
108
+<ul>
109
+<li>Select from menu <b>Project->Add Sequence Link Container Clip</b> to create a <b>Sequence Link Container Clip</b> media item.</li>
110
+<li>Drag <b>Sequence Link Container Clip</b> Media Item on Timeline to create a clip.</li>
111
+<li><b>Sequence Link Container Clips</b> can't be placed on Sequences they link to and creating cyclic dependencies between sequencse using <b>Sequence Link Container Clips</b> is not allowed.</li>
112
+</ul>
113
+<h5> Updating Sequence Link Container Clips</h5>
114
+<ul>
115
+<li>Click <b>Right Mouse</b> on clip and select <b>Update Sequence Link Clip</b> to update clip to display current contents of Sequence it is linked to.</li>
116
+</ul>
117
+<h5> Replacing Sequence Link Container Clip with Sequence Contents</h5>
118
+<ul>
119
+<li>Place Playhead at the beginning of <b>Sequence Link Container Clip</b>.</li>
120
+<li>Select from menu <b>Sequence->Import Another Sequence Into This Sequence...</b> and select option <b>Insert Sequence at Playhead position</b> and do import.</li>
121
+<li>Delete <b>Sequence Link Container Clip</b>.</li>
122
+</ul>
123
+
124
+<h2>G'Mic Script Container Clips</h2>
125
+
126
+<h5>Components</h5>
127
+<p>
128
+<ul style="list-style-type:none">
129
+<li><b>Unrendered Media</b> Video Clip.</li>
130
+<li><b>Program</b> G'Mic script created and saved from G'Mic tool.</li>
131
+<li><b>Rendered Media</b> A clip rendered with G'mic effect.</li>
132
+</ul>
133
+</p>
134
+<p>
135
+<h5>Use Cases</h5>
136
+<ul>
137
+<li>Render G'Mic effects only on clip ranges used on timeline.</li>
138
+<li>Make easier to use single user defined G'Mic effect on multiple clips.</li>
139
+</ul>
140
+
141
+<h5> Creating G'Mic Script Container Clips</h5>
142
+
143
+<ol>
144
+<li>Open <b>G'Mic tool</b>.</li>
145
+<li>Create G'Mic effect script. See section on <b>G'Mic Effects</b> in Chapter <b>Tools</b>.</li>
146
+<li>Press <b>Save Script</b> button in bottom left corner and save effect.</li>
147
+<li>Select menu item <b>Project -> Create Container Clip -> From G'Mic Script</b>.</li>
148
+<li>Select the script you saved and the clip that it will be applied on to create Container Clip.</li>
149
+</ol>
150
+
151
+<h2>Rendering Container Clips</h2>
152
+<h4>Container Clip Render Actions</h4>
153
+<p> Render actions are available from Clip <b>Right Mouse</b> context menu in <b>Generator and Container Rendering</b> submenu.
154
+<ul>
155
+<li><b>Render Clip...</b> Renders Clip and stops using <b>Unrendered Media</b> on timeline.</li>
156
+<li><b>Render Settings...</b> Allows setting how and where a clip is rendered.</li>
157
+<li><b>Switch to Unrendered Media</b> Switch to using <b>Unrendered Media</b> and drops the current <b>Rendered Media</b> version of <b>Program</b>.</li>
158
+<li><b>Set Default Encoding...</b> Allows setting encoding format that is used for all <b>Container Clips</b> and <b>Generator</b> as default video encoding.</li>
159
+</ul>
160
+
161
+</div>
162
+
163
+</div>
164
+</div>
165
+
166
+</body>
167
+
168
+</html> 
169
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/correct_comp.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/correct_comp.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/correct_dest.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/correct_dest.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/correct_timeline.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/correct_timeline.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/datastores.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/datastores.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/edit_tools.html Added
201
 
1
@@ -0,0 +1,259 @@
2
+ <!DOCTYPE html>
3
+<html>
4
+<head>
5
+  <title>Timeline Edit Tools</title>
6
+  <link rel="stylesheet" href="style.css">
7
+  <META CHARSET="UTF-8">
8
+</head>
9
+
10
+<body>
11
+
12
+<div id="content">
13
+
14
+<img src="header_text_5.png" >
15
+
16
+<script src="tocgen.js"></script>
17
+
18
+<div class="subject-header">Timeline Edit Tools</div>
19
+
20
+<p>
21
+Flowblade Movie Editor has 6 edit tools for doing timeline edits.
22
+</p>
23
+
24
+<div id="toccontent">
25
+<div id="toc"></div>
26
+
27
+<h2>Selecting Tools</h2>
28
+
29
+<p>
30
+Use <b>Tool Switcher</b> button drop menu or press key <b>1 - 6</b>  to pick a tool.
31
+</p>
32
+
33
+<p>
34
+It is also possible to use Tool Dock instead of <b>Tool Switcher</b> button by selecting <b>Dock</b> in <b>View->Edit Tool Selection Widget</b>.
35
+</p>
36
+
37
+
38
+<div class="note">
39
+<b>Use Keyboard Shortcuts!</b> It is much faster to use keys <b>1 - 6</b> to change tools. Note that keys 1-6 only change tools if timeline has keyboard focus. 
40
+</div>
41
+
42
+
43
+<h2>Move Tools</h2>
44
+
45
+
46
+<a id="overwrite"></a>
47
+<h3>Move</h3>
48
+
49
+<p>
50
+Lift out one or more clips and insert them at any point to overwrite on any track.
51
+</p>
52
+
53
+<ol>
54
+<li>Select clip
55
+   <ul>
56
+   <li><b> Click </b>Left Mouse on a clip.</li>
57
+   </ul>
58
+</li>
59
+<li>Select other end of clip range if moving multiple clips
60
+   <ul>
61
+   <li> Click <b>CTRL+Left Mouse</b> on the clip you wish to be the other end of move clip range.</li>
62
+   </ul>
63
+</li>
64
+<li>Drag Clip(s) to new position
65
+   <ul>
66
+   <li> Press <b>Left Mouse</b> on a selected clip and drag clip/s to a new position.</li>
67
+   <li> Red shadow clips show overwrite area.</li>
68
+   <li> You can also move clips to a different track.</li>
69
+   </ul>
70
+</li>
71
+</ol>
72
+
73
+<p>
74
+Drag clip ends to change clip length.
75
+</p>
76
+
77
+<ol>
78
+<li>Place cursor near clip end
79
+   <ul>
80
+   <li>When cursor changes to horizontal arrow with vertical bar you can start clip end drag edit.</li>
81
+   </ul>
82
+</li>
83
+<li>Drag clip end with <b>Left Mouse</b>.
84
+   <ul>
85
+   <li> Added clip length will perform overwrite on blanks and empty space</li>
86
+   </ul>
87
+   <ul>
88
+   <li> Added clip length will perform insert on other clips</li>
89
+   </ul>
90
+   <ul>
91
+   <li> Decreased clip length will perform splice out.</li>
92
+   </ul>
93
+</li>
94
+<li>Drag clip end with <b>CTRL + Left Mouse</b>.
95
+   <ul>
96
+   <li> Added clip length will perform overwrite on all clips up length of the adjacent clip.</li>
97
+   </ul>
98
+   <ul>
99
+   <li> Decreased clip length will add material as much as possible from the adjacent clip.</li>
100
+   </ul>
101
+</li>
102
+</ol> 
103
+
104
+<p>
105
+Select and overwrite move all Timeline items contained in a box selection.
106
+</p>
107
+
108
+<ol>
109
+<li>Select an area on Timeline by dragging a box selection with <b>Left Mouse</b> around all items you wish to move and release mouse button.</li>
110
+<li>Press <b>Left Mouse</b> inside the box selection and drag the box into new position on timeline and release mouse.</li>
111
+<li>Box contents are overwritten on new position and Compositors are moved.</li>
112
+
113
+</ol>
114
+
115
+
116
+<a id="insert"></a>
117
+<h3>Insert</h3>
118
+
119
+<p>
120
+Splice out one or more clips and insert them at desired cut on any track.
121
+</p>
122
+
123
+<ol>
124
+<li>Select clip
125
+   <ul>
126
+   <li> Click <b>Left Mouse</b> on a clip.</li>
127
+   </ul>
128
+</li>
129
+<li>Select other end of clip range if moving multiple clips
130
+   <ul>
131
+   <li> Click <b>CTRL+Left Mouse</b> on the clip you wish to be the other end of move clip range.</li>
132
+   </ul>
133
+</li>
134
+<li>Drag Clip(s) to new position
135
+   <ul>
136
+   <li> Press <b>Left Mouse</b> on a selected clip and drag clip/s to a new position.</li>
137
+   <li> Yellow arrow displays insert point.</li>
138
+   <li> You can also move clips to a different track.</li>
139
+   </ul>
140
+</li>
141
+</ol>
142
+
143
+<p>
144
+Drag clip ends to change clip length.
145
+</p>
146
+
147
+<ol>
148
+<li>Place cursor near clip end 
149
+   <ul>
150
+   <li>When cursor changes to horizontal arrow with vertical bar you can start clip end drag edit.</li>
151
+   </ul>
152
+</li>
153
+<li>Drag clip end with <b>Left Mouse</b>.
154
+   <ul>
155
+   <li> Added clip length will perform overwrite on blanks and empty space</li>
156
+   </ul>
157
+   <ul>
158
+   <li> Added clip length will perform insert on other clips</li>
159
+   </ul>
160
+   <ul>
161
+   <li> Decreased clip length will perform splice out.</li>
162
+   </ul>
163
+</li>
164
+
165
+</ol> 
166
+
167
+
168
+
169
+
170
+
171
+
172
+<a id="spacer"></a>
173
+<h3>Spacer</h3>
174
+
175
+<p>Move all Timeline items after pressed frame on all tracks or on a single track</p>
176
+<ol>
177
+<li>Select a clip on Timeline and move it and all items to the right of it
178
+   <ul>
179
+   <li> Press <b>Left Mouse</b> on a clip.</li>
180
+   <li> Continue to <b>Left drag</b> clip and all clips and compositors to right of it into a new position</li>
181
+   <li> It is not possible to move items on top of clips. Items can only be moved on top of empty space </li>
182
+       </ul>
183
+   <li>Use <b>Control</b> button to only affect items on a single track</li>
184
+       <ul>
185
+   <li> Press <b>Control</b> and use <b>Left Mouse</b> to move all items on single track to the right of the selected clip</li>
186
+   </ul>
187
+</li>
188
+</ol>
189
+
190
+
191
+ 
192
+ 
193
+<h2>Trim Tools</h2>
194
+
195
+<a id="multitrim"></a>
196
+<h3>Multitrim</h3>
197
+<p>
198
+Do  <b>Trim</b>, <b>Roll</b> or <b>Slip</b> tool edits based on cursor position on timeline.
199
+</p>
200
+<ol>
201
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/encoding.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/encoding.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/filter_mask.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/filter_mask.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/filtering.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/filtering.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/filters_list.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/filters_list.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/fluxity.html Added
201
 
1
@@ -0,0 +1,3836 @@
2
+<!doctype html>
3
+<html lang="en">
4
+<head>
5
+<meta charset="utf-8">
6
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
7
+<meta name="generator" content="pdoc 0.10.0" />
8
+<title>fluxity API documentation</title>
9
+<meta name="description" content="GPL Licence text …" />
10
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
11
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
12
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
13
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2id^="header-"{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
14
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
15
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}ahref:after{content:" (" attr(href) ")";font-size:90%}ahreftitle:after{content:none}abbrtitle:after{content:" (" attr(title) ")"}.ir a:after,ahref^="javascript:":after,ahref^="#":after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
16
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
17
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
18
+</head>
19
+<body>
20
+<main>
21
+<article id="content">
22
+<header>
23
+<h1 class="title">Module <code>fluxity</code></h1>
24
+</header>
25
+<section id="section-intro">
26
+<h3 id="gpl-licence-text">GPL Licence text</h3>
27
+<p>Flowblade Movie Editor is a nonlinear video editor.
28
+Copyright 2021 Janne Liljeblad.</p>
29
+<p>This file is part of Flowblade Movie Editor <a href="https://github.com/jliljebl/flowblade/">https://github.com/jliljebl/flowblade/</a>.</p>
30
+<p>Flowblade Movie Editor is free software: you can redistribute it and/or modify
31
+it under the terms of the GNU General Public License as published by
32
+the Free Software Foundation, either version 3 of the License, or
33
+(at your option) any later version.</p>
34
+<p>Flowblade Movie Editor is distributed in the hope that it will be useful,
35
+but WITHOUT ANY WARRANTY; without even the implied warranty of
36
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
37
+See the
38
+GNU General Public License for more details.</p>
39
+<p>You should have received a copy of the GNU General Public License
40
+along with Flowblade Movie Editor. If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.</p>
41
+<h1 id="fluxity-scripting">FLUXITY SCRIPTING AND API</h1>
42
+<p>Fluxity scripting is a <strong>Python scripting solution</strong> created to provide <strong>Flowblade Movie Editor</strong> with a <em>Plugin API</em>.
43
+Currently <em>Fluxity API</em>
44
+is used by Flowblade <em>Generators</em> feature.</p>
45
+<p><em>Fluxity API</em> is made available to scripts mainly by <em>fluxity.FluxityContext</em> object and its methods.
46
+This object is created to communicate with the script before calling any of the methods of the script.</p>
47
+<p>Some constants mentioned in this source file - such as <code><a title="fluxity.EDITOR_FLOAT" href="#fluxity.EDITOR_FLOAT">EDITOR_FLOAT</a></code> or <code><a title="fluxity.PROFILE_WIDTH" href="#fluxity.PROFILE_WIDTH">PROFILE_WIDTH</a></code> - can also be used by scripts. </p>
48
+<p>See below for <em>fluxity.FluxityContext</em> object API details.</p>
49
+<h2 id="script-interface">SCRIPT INTERFACE</h2>
50
+<p>A Python script needs to have the following functions to load and run without crashing as a Fluxity API conforming script.</p>
51
+<pre><code>def init_script(fctx):
52
+    pass
53
+
54
+def init_render(fctx):
55
+    pass
56
+
57
+def render_frame(frame, fctx, w, h):
58
+    pass
59
+</code></pre>
60
+<h2 id="script-lifecycle">SCRIPT LIFECYCLE</h2>
61
+<p><strong><code>init_script(fctx):</code></strong> This method is called when script is first loaded by Flowblade to create data structures with info on editors and script metadata. </p>
62
+<p><strong><code>init_render(fctx):</code></strong> This method is called before a render is started to get user input from editors and possibly to create some additional data structures.</p>
63
+<p><strong><code>render_frame(frame, fctx, w, h):</code></strong> This method is called for each frame rendered to create an output image for that frame.</p>
64
+<p>Object <strong><code>fctx</code></strong> is object of class <strong><code>fluxity.FluxityContext</code></strong>.</p>
65
+<h2 id="example-script">EXAMPLE SCRIPT</h2>
66
+<h3 id="init_script">init_script()</h3>
67
+<pre><code>import cairo
68
+import numpy as np
69
+import random
70
+import math
71
+
72
+import fluxity
73
+
74
+def init_script(fctx):
75
+    fctx.set_name(&quot;Floating Balls&quot;)
76
+    fctx.set_version(1)
77
+    fctx.set_author(&quot;Janne Liljeblad&quot;)
78
+
79
+    fctx.add_editor(&quot;Hue&quot;, fluxity.EDITOR_COLOR, (0.8, 0.50, 0.3, 1.0))
80
+    fctx.add_editor(&quot;Speed&quot;, fluxity.EDITOR_FLOAT_RANGE, (1.0, -5.0, 5.0))
81
+    fctx.add_editor(&quot;Speed Variation %&quot;, fluxity.EDITOR_INT_RANGE, (40, 0, 99))
82
+    fctx.add_editor(&quot;Number of Items&quot;, fluxity.EDITOR_INT_RANGE, (50, 10, 500))
83
+    fctx.add_editor(&quot;Size&quot;, fluxity.EDITOR_INT_RANGE, (330, 10, 800))
84
+    fctx.add_editor(&quot;Size Variation %&quot;, fluxity.EDITOR_INT_RANGE, (0, 0, 80))
85
+    fctx.add_editor(&quot;Opacity&quot;, fluxity.EDITOR_INT_RANGE, (100, 5, 100))
86
+    fctx.add_editor(&quot;Random Seed&quot;, fluxity.EDITOR_INT, 42)
87
+</code></pre>
88
+<p>In <em>init_script()</em> we define the editors that will be presented to the user and set some metadata like the name of the script displayed to the user and the script author.</p>
89
+<p>Object <strong><code>fctx</code></strong> is object of class <strong><code>fluxity.FluxityContext</code></strong>.</p>
90
+<h3 id="init_render">init_render()</h3>
91
+<pre><code>def init_render(fctx):
92
+    # The script is possibly rendered using multiple processes and we need to have the
93
+    # same sequence of random numbers in all processes. If we don't set seed we'll get completely different
94
+    # ball positions, colors and speeds in different rendering processes.
95
+    random.seed(fctx.get_editor_value(&quot;Random Seed&quot;))
96
+
97
+    # Ball colors data structure
98
+    hue = fctx.get_editor_value(&quot;Hue&quot;)
99
+    hr, hg, hb, alpha = hue
100
+    fctx.set_data_obj(&quot;hue_tuple&quot;, hue)
101
+    color_array = list(hue)
102
+    ball_colors = 
103
+    color_mult = 1.05
104
+    opacity = float(fctx.get_editor_value(&quot;Opacity&quot;)) / 100.0
105
+
106
+    for i in range(0, 10):
107
+        array = np.array(color_array) * color_mult
108
+        r, g, b, a = array
109
+        ball_colors.append(cairo.SolidPattern(_clamp(r), _clamp(g), _clamp(b), opacity))
110
+        color_array = array
111
+    fctx.set_data_obj(&quot;ball_colors&quot;, ball_colors)
112
+
113
+    # Ball animations data structure
114
+    ball_data = 
115
+    number_of_balls = fctx.get_editor_value(&quot;Number of Items&quot;)
116
+    speed = fctx.get_editor_value(&quot;Speed&quot;)
117
+    speed_var_size_precentage = fctx.get_editor_value(&quot;Speed Variation %&quot;)
118
+    speed_var_max = speed * (speed_var_size_precentage  / 100.0)
119
+    size = fctx.get_editor_value(&quot;Size&quot;)
120
+    size_var_size_precentage = fctx.get_editor_value(&quot;Size Variation %&quot;)
121
+    size_var_max = size * (size_var_size_precentage / 100.0)
122
+    size_max = size + size_var_max
123
+    fctx.set_data_obj(&quot;size_max&quot;, size_max)
124
+
125
+    for i in range(0, number_of_balls):
126
+        path_pos = random.uniform(0.0, 1.0)
127
+        y = random.randint(-330, 1080 + 330)
128
+        speed_var = random.uniform(-1.0, 1.0)
129
+
130
+        ball_speed = speed + (speed_var * speed_var_max)
131
+        size_var = random.uniform(-1.0, 1.0)
132
+        ball_size = size + (size_var * size_var_max)
133
+        color_index = random.randint(0, 9)
134
+        ball_data.append((path_pos, y, ball_speed, ball_size, color_index))
135
+
136
+    fctx.set_data_obj(&quot;ball_data&quot;, ball_data)
137
+</code></pre>
138
+<p>In <em>init_render() </em> we read editor values set by the user and create some data structures for moving ball animations based on that data.</p>
139
+<p>Also note that <strong>we need to set seed for Pythom module 'random'</strong> because when a frame sequence is rendered using multiple processes we need the exact same sequence of random numbers produced in every process. </p>
140
+<p>Object <strong><code>fctx</code></strong> is object of class <strong><code>fluxity.FluxityContext</code></strong>.</p>
141
+<h3 id="render_frame">render_frame()</h3>
142
+<pre><code>def render_frame(frame, fctx, w, h):
143
+    cr = fctx.get_frame_cr()
144
+
145
+    # Draw bg
146
+    bg_color = cairo.SolidPattern(*fctx.get_data_obj(&quot;hue_tuple&quot;))
147
+    ball_colors = fctx.get_data_obj(&quot;ball_colors&quot;)
148
+    ball_data = fctx.get_data_obj(&quot;ball_data&quot;)
149
+
150
+    cr.set_source(bg_color)
151
+    cr.rectangle(0, 0, w, h)
152
+    cr.fill()
153
+
154
+    # Draw balls
155
+    number_of_balls = fctx.get_editor_value(&quot;Number of Items&quot;)
156
+    size_max = fctx.get_data_obj(&quot;size_max&quot;)
157
+    path_start_x = - size_max
158
+    path_end_x =  w + size_max
159
+    path_len = path_end_x - path_start_x
160
+    SPEED_NORM_PER_FRAME = 15.0 / float(w) # Speed value 1.0 gets 15 pixels of movement per frame.
161
+    for i in range(0, number_of_balls):
162
+        path_pos, y, ball_speed, ball_size, color_index = ball_datai
163
+        xc = ball_size / 2.0
164
+        yc = ball_size / 2.0
165
+        xpos_norm = path_pos + (float(frame) * ball_speed * SPEED_NORM_PER_FRAME)
166
+        while xpos_norm &gt; 1.0:
167
+            xpos_norm = xpos_norm - 1.0
168
+        x = path_start_x + path_len * xpos_norm
169
+        cr.save()
170
+        cr.translate(x, y)
171
+        cr.arc(xc, yc, ball_size / 4.0, 0.0, 2.0 * math.pi)
172
+        cr.set_source(ball_colorscolor_index)
173
+        cr.fill()
174
+        cr.restore()
175
+
176
+# ----------------------- helper func
177
+def _clamp(v):
178
+    return max(min(v, 1.0), 0.0)
179
+
180
+</code></pre>
181
+<p>In <em>render_frame()</em> we first acquire <em>Cairo.Context</em> object that can be drawn onto to create output for the frame.</p>
182
+<p>After that the data structures created in <em>init_render()</em> are accessed and image is drawn.</p>
183
+<p>There is a helper function <em>_clamp(v)</em> used to make sure that all color values are in range 0-1. Any number of helper functions, objects and data structures can be created.</p>
184
+<h2 id="developing-fluxity-scripts">DEVELOPING FLUXITY SCRIPTS</h2>
185
+<p><strong>Flowblade</strong> comes with a simple GUI tool for developing Fluxity scripts. It can be accessed from menu <strong>Tools-&gt;Generator Script Editor</strong>.</p>
186
+<p>Using the development tool you can edit scripts, render output from them, and get receive error messages when something goes wrong. From hamburger menu you can open and save your own scripts, access this document, and open and inspect example code of the <em>Generators</em> distributed with Flowblade. </p>
187
+<p>Since the text editor in the development tool is quite rudimentary <em>(with a future GTK4 port we may get improvement here)</em>, it can be a useful workflow to use an external text editor to edit the scripts, and press <em>Reload Script</em> button to update text area contents before attempting render.</p>
188
+<h1 id="fluxity-api_1">FLUXITY API</h1>
189
+<details class="source">
190
+<summary>
191
+<span>Expand source code</span>
192
+</summary>
193
+<pre><code class="python">&#34;&#34;&#34;
194
+    ### GPL Licence text
195
+
196
+    Flowblade Movie Editor is a nonlinear video editor.
197
+    Copyright 2021 Janne Liljeblad.
198
+
199
+    This file is part of Flowblade Movie Editor &lt;https://github.com/jliljebl/flowblade/&gt;.
200
+
201
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/generatorsfluxity.html Added
131
 
1
@@ -0,0 +1,129 @@
2
+<!DOCTYPE html>
3
+ 
4
+<html>
5
+<head>
6
+  <title>Generators</title>
7
+  <link rel="stylesheet" href="style.css">
8
+<script src="toc.js" type="text/javascript"></script>
9
+</head>
10
+
11
+<body>
12
+
13
+<div id="content">
14
+
15
+<img src="header_text_5.png">
16
+
17
+<script src="tocgen.js"></script>
18
+
19
+<div id="toccontent">
20
+
21
+<div class="subject-header">Generators</div>
22
+
23
+<div id="toc"></div>
24
+
25
+<p>
26
+<b>Generators</b> are <b>Media Items</b> that render into animated media clips when placed on timeline.
27
+</p>
28
+
29
+<p>
30
+Currently there are three different types of <b>Generators</b> available:
31
+<ul style="list-style-type:none">
32
+<li><b>Backgrounds</b> Animated backgrounds.</li>
33
+<li><b>Texts</b> Animated texts.</li>
34
+<li><b>Cover Transitions</b> Incoming shapes cover frame fully and then disappear creating a transition.</li>
35
+</ul>
36
+
37
+</p>
38
+
39
+<p>
40
+Flowblade <b>Generators</b> are implemented as Python scripts using <i>Fluxity API</i> <i>(see below)</i> packed inside <a href="container_clips.html">Container Clips.</a>
41
+</p>
42
+
43
+
44
+<h3>Using Generators</h3>
45
+
46
+<h4>Adding Generators</h4>
47
+<ol>
48
+<li>Select menu item <b>Project -> Add Generator</b>.</li>
49
+<li>Select <b>Generator</b> using <b>Generator</b> drop down menu.</li>
50
+<li>Set properties using left side panel, select frame using <b>Clip Frame</b> spin button and press <b>Preview</b> button to view results.</li>
51
+<li>Use <b>Generator Length</b> spin button to set generator maximum length. Use <b>Import Action</b> drop down menu to either add as <b>Media Item</b> or render a video clip.</b></li>
52
+<li>Use <b>Add Generator</b> button to complete <b>Generator</b> creation.</li>
53
+</ol>
54
+
55
+<h4>Editing Generator Clips</h4>
56
+<ol>
57
+<li>Open timeline clip <b>Right Mouse</b> pop-up menu and select item <b>Edit Generator Properties...</b>.</li>
58
+<li>Set <b>Generator</b> properties using editors opened in <b>Edit</b> panel.</li>
59
+<li>Select frame using spin button and press <b>Preview</b> button to view results.</li>
60
+<li>Use <b>Apply</b> button to re-render timeline clip using edited properties.</li>
61
+</ol>
62
+
63
+<h3>Generators List</h3>
64
+ <table>
65
+  <tr>
66
+    <th>Category</th>
67
+    <th>Name</th>
68
+    <th>Description</th>
69
+  </tr>
70
+  <tr>
71
+    <td><i>Backgrounds</i></td>
72
+    <td><b>Floating Balls</b></td>
73
+    <td>Colored balls moving horizontally with differing sizes and speeds.</td>
74
+  </tr>
75
+  <tr>
76
+    <td><i>Backgrounds</i></td>
77
+    <td><b>Hex Colors</b></td>
78
+    <td>Colored hexagonals of selected size changing color at selected speed.</td>
79
+  </tr>
80
+  <tr>
81
+    <td><i>Texts</i></td>
82
+    <td><b>Multiline text</b></td>
83
+    <td>Animated lines of text with multiple in and out animation types, with optional lines or rectangle background.</td>
84
+  </tr>
85
+  <tr>
86
+    <td><i>Texts</i></td>
87
+    <td><b>TypeWriter</b></td>
88
+    <td>Text typewriter effect with steps of adding a letter, word or line.</td>
89
+  </tr>
90
+  <tr>
91
+    <td><i>Cover Transitions</i></td>
92
+    <td><b>Lines Sweep</b></td>
93
+    <td>Cover transition with horizontally moving colored lines.</td>
94
+  </tr>
95
+   <tr>
96
+    <td><i>Cover Transitions</i></td>
97
+    <td><b>Hex Overlay</b></td>
98
+    <td>Cover transition with apperaing and disappearing hexagonals.</td>
99
+  </tr>
100
+</table> 
101
+
102
+<h2>Fluxity Scripting</h2>
103
+<p>Fluxity scripting is a <strong>Python scripting solution</strong> created to provide <strong>Flowblade Movie Editor</strong> with a <em>Plugin API</em> used to create <em>Generators</em> providing means to create e.g. animated text and animated background clips.</p>
104
+
105
+
106
+<h3>Fluxity API</h3>
107
+<p>Instructions on how to create <strong>Generators</strong> using <strong>Fluxity API</strong> <a href="fluxity.html">here.</a></p>
108
+
109
+<h2>Render Actions</h2>
110
+<h4>Applying Property Edits</h4>
111
+
112
+<ul>
113
+<li>Use <b>Apply</b> button in <b>Edit</b> panel to re-render timeline clip using edited properties, see above.</li>
114
+</ul>
115
+
116
+<h4>Container Clip Render Actions</h4>
117
+<p> Render actions are available from Clip <b>Right Mouse</b> context menu in <b>Generator and Container Rendering</b> submenu.
118
+<ul>
119
+<li><b>Render Clip...</b> Renders Clip and stops using <b>Unrendered Media</b> on timeline.</li>
120
+<li><b>Render Settings...</b> Allows setting how and where a clip is rendered.</li>
121
+<li><b>Switch to Unrendered Media</b> Switch to using <b>Unrendered Media</b> and drops the current <b>Rendered Media</b> version of <b>Program</b>.</li>
122
+<li><b>Set Default Encoding...</b> Allows setting encoding format that is used for all <b>Container Clips</b> and <b>Generator</b> as default video encoding.</li>
123
+</ul>
124
+
125
+</div>
126
+</div>
127
+
128
+</body>
129
+
130
+</html> 
131
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/header_text_5.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/ru/header_text_5.png)
2
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/help/help.html -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/help.html Changed
101
 
1
@@ -1,17 +1,85 @@
2
-<!DOCTYPE html>
3
+ <!DOCTYPE html>
4
 <html>
5
 <head>
6
-<title>Flowblade help</title>
7
-<script type="text/javascript">
8
-var lang=(navigator.language||navigator.systemLanguage||navigator.userLanguage).substr(0, 2).toLowerCase();
9
-function actLang() {
10
-if (lang=='en') {nameweb='en/help.html';}
11
-else if (lang=='ru') {nameweb='ru/help.html';}
12
-else if (lang=='your_lang') {nameweb='your_lang/help.html';}
13
-else {nameweb='en/help.html';}
14
-parent.location=nameweb;
15
-return true;}
16
-actLang()
17
-</script>
18
+  <title>Flowblade Reference Guide</title>
19
+  <link rel="stylesheet" href="style.css">
20
+<script src="toc.js" type="text/javascript"></script>
21
 </head>
22
-<body></script></body></html>
23
+
24
+<body>
25
+
26
+<div id="content">
27
+<img src="header_text_5.png" >
28
+
29
+<a class="french-link" href="https://github.com/jliljebl/flowblade/blob/master/flowblade-trunk/docs/FLOWBLADE_manuel_fr.pdf">Manuel en français</a>
30
+
31
+<div id="help-index">
32
+       <div class="subject-cell">
33
+           <a href="intro.html">Introduction</a>
34
+       </div>
35
+
36
+       <div class="subject-cell">
37
+           <a href="basic_editing.html">Basic Editing</a> 
38
+       </div>
39
+
40
+       <div class="subject-cell">
41
+           <a href="edit_tools.html">Timeline Edit Tools</a> 
42
+       </div> 
43
+
44
+       <div class="subject-cell">
45
+           <a href="compositor.html">Creating Composited Images</a>
46
+       </div>
47
+
48
+       <div class="subject-cell">
49
+           <a href="filtering.html">Filtering image and audio</a> 
50
+       </div>
51
+
52
+       <div class="subject-cell">
53
+           <a href="advanced.html">Advanced Editing Features</a> 
54
+       </div> 
55
+
56
+       <div class="subject-cell">
57
+           <a href="range_log.html">Range Log</a>
58
+       </div>
59
+
60
+       <div class="subject-cell">
61
+           <a href="proxy.html">Proxy Editing</a>
62
+       </div>
63
+       
64
+       <div class="subject-cell">
65
+           <a href="container_clips.html">Container Clips</a>
66
+       </div>
67
+
68
+       <div class="subject-cell">
69
+            <a href="generatorsfluxity.html">Generators</a>
70
+       </div>
71
+
72
+       <div class="subject-cell">
73
+           <a href="tools.html">Tools</a>
74
+       </div>
75
+       
76
+       <div class="subject-cell">
77
+            <a href="rendering.html">Rendering</a>
78
+       </div>
79
+
80
+       <div class="subject-cell">
81
+           <a href="datastores.html">Data Stores</a>
82
+       </div>
83
+
84
+        <div class="subject-cell">
85
+           <a href="infotips.html">Info & Tips</a>
86
+       </div>
87
+        
88
+</div>
89
+
90
+<h6 class="appendix-title">Appendices:</h6>
91
+<a class="appendix-index" href="filters_list.html">Filters list</a>
92
+<a class="appendix-index" href="fluxity.html">Fluxity API doc</a>
93
+<a class="appendix-index" href="kbshortcuts.html">Keyboard Shortcuts</a>
94
+
95
+<div class="copyright-info">Flowblade Reference Guide v 3.0 9-3-2017.</div> 
96
+
97
+</div>
98
+</body>
99
+
100
+</html> 
101
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/infotips.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/infotips.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/intro.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/intro.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/kbshortcuts.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/kbshortcuts.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/only_one_comp.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/ru/only_one_comp.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/proxy.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/proxy.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/range_log.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/range_log.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/rendering.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/rendering.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/style.css Added
201
 
1
@@ -0,0 +1,330 @@
2
+html {
3
+   font-size: 100%;
4
+   -webkit-text-size-adjust: 100%;
5
+   -ms-text-size-adjust: 100%;
6
+}
7
+
8
+body {
9
+   font-family: Georgia, "Times New Roman", Times, serif;
10
+   color:#222222;
11
+   background-color: #ffffff; 
12
+   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
13
+   font-family: sans-serif;
14
+   word-wrap: break-word;
15
+   line-height: 1.4;
16
+   vertical-align: baseline;
17
+}
18
+
19
+#content {
20
+  width: 700px ;
21
+  margin-left: auto ;
22
+  margin-right: auto ;
23
+}
24
+
25
+#help-index{
26
+   margin-top: 80px;
27
+   width: 900px;
28
+   margin-bottom: 80px;
29
+   display: flex;
30
+   justify-content: center;
31
+   flex-direction: column;
32
+   text-align: center;
33
+}
34
+
35
+.appendix-index{
36
+   margin-top: 10px;
37
+   width: 900px;
38
+   margin-bottom: 10px;
39
+   display: flex;
40
+   justify-content: center;
41
+   flex-direction: column;
42
+   text-align: left;
43
+   color: #666666;
44
+   font-size:18px;
45
+}
46
+
47
+.french-link{
48
+   margin-top: 40px;
49
+   width: 900px;
50
+   margin-bottom: 0px;
51
+   display: flex;
52
+   justify-content: center;
53
+   flex-direction: column;
54
+   text-align: left;
55
+   font-size:18px;
56
+}
57
+
58
+.subject-cell {
59
+   padding-right: 20px;
60
+   color:#222222;
61
+   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
62
+   font-family: sans-serif;
63
+   word-wrap: break-word;
64
+   line-height: 1.4;
65
+   vertical-align: baseline;
66
+   font-weight:400;
67
+   font-size:30px;
68
+   margin-bottom: 35px;
69
+}
70
+
71
+.grid-container {
72
+   margin-top: 80px;
73
+        width: 700px;
74
+   margin-bottom: 80px;
75
+}
76
+
77
+.row:before, 
78
+.row:after {
79
+   content:"";
80
+   display: table ;
81
+   clear:both;
82
+}
83
+
84
+.column4 {
85
+   float: left; 
86
+   width: 33.3%;
87
+   margin-bottom: 50px;
88
+}
89
+
90
+.subject-cell {
91
+   padding-right: 20px;
92
+   color:#222222;
93
+   /*font:normal 400 14px/1 'robotoregular', Arial, sans-serif;*/
94
+   font-family: sans-serif;
95
+   word-wrap: break-word;
96
+   line-height: 1.4;
97
+   vertical-align: baseline;
98
+   font-weight:400;
99
+   font-size:22px;
100
+   text-transform: uppercase;
101
+}
102
+
103
+.appendix-pad {
104
+   color: #666666;
105
+   font-size:14px;
106
+}
107
+.appendix-title {
108
+   color: #666666;
109
+   font-size:20px;
110
+}
111
+
112
+.note {
113
+   background-color: #f3f3f0;
114
+   padding: 25px;
115
+   margin-bottom: 10px ;
116
+}
117
+
118
+.important {
119
+   background-color: #f5d77d;
120
+   padding: 25px;
121
+   margin-bottom: 10px ;
122
+}
123
+
124
+.tabbed {
125
+   padding-left: 25px;
126
+   margin-bottom: 10px ;
127
+}
128
+
129
+.tabbed_line {
130
+   padding-left: 25px;
131
+}
132
+
133
+.tocitem {
134
+   font-size:12px;
135
+   line-height: 1.0;
136
+
137
+}
138
+
139
+.tocli {
140
+   list-style-type: none;
141
+}
142
+
143
+.copyright-info {
144
+   font-family: Georgia, "Times New Roman", Times, serif;
145
+   margin-top:80px;
146
+   color: #444444;
147
+   font-weight:400;
148
+   font-size:12px;
149
+}
150
+
151
+.code-text {
152
+   font-family: "Lucida Console", "Courier New", monospace;
153
+   background-color: #f3f3f0;
154
+   padding: 10px;
155
+   margin-bottom: 5px ;
156
+   line-height: 10px
157
+}
158
+
159
+.subject-header {
160
+   text-transform: uppercase;
161
+   margin-top:10px;
162
+   color: #000000;
163
+   font-weight:400;
164
+   font-size:26px;
165
+}
166
+
167
+.filter {
168
+   margin-bottom: 25px;
169
+   color: #000000;
170
+   font-weight:400;
171
+   font-family: sans-serif;
172
+   word-wrap: break-word;
173
+   line-height: 1.4;
174
+   vertical-align: baseline;
175
+}
176
+
177
+.filter-name {
178
+   padding-left: 20px;
179
+}
180
+
181
+.filter-property {
182
+   padding-left: 50px;
183
+   font-size:12px;
184
+}
185
+.filter-value {
186
+   display:inline-block;
187
+   color: #0000bb;
188
+   font-size: 8;
189
+}
190
+
191
+.filter-group {
192
+   color: #000000;
193
+   font-size: 26;
194
+   text-transform: uppercase;
195
+   margin-top: 50px;
196
+   margin-bottom: 10px;
197
+}
198
+
199
+.r-widget {
200
+   display: inline-block;
201
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/tlinerender.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/tlinerender.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/tocgen.js Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/ru/tocgen.js)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/tools.html Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/tools.html)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/workflow.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/ru/workflow.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/wrong_comp.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/wrong_comp.png)
2
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/help/wrong_timeline.png Changed
2
 
1
(renamed from flowblade-trunk/Flowblade/res/help/en/wrong_timeline.png)
2
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/animations_1/floating_boxes.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/animations_1/floating_boxes.py Changed
10
 
1
@@ -46,7 +46,7 @@
2
     fctx.add_editor("Random Seed", fluxity.EDITOR_INT, 42)
3
     
4
 def init_render(fctx):
5
-    # The script is usually rendered using multiple prosesses so we need to have the
6
+    # The script is usually rendered using multiple processes so we need to have the
7
     # same sequence of random numbers in all processes.
8
     random.seed(fctx.get_editor_value("Random Seed"))
9
 
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/animations_2/hex_colors.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/animations_2/hex_colors.py Changed
10
 
1
@@ -41,7 +41,7 @@
2
     fctx.set_data_obj("points", _points)
3
     
4
 def init_render(fctx):
5
-    # The script is possibly rendered using multiple prosesses and we need to have the
6
+    # The script is possibly rendered using multiple processes and we need to have the
7
     # same sequence of random numbers in all processes. If we don't set seed we'll get completely different
8
     # ball positions, colors and speeds in different rendering processes.
9
     random.seed(fctx.get_editor_value("Random Seed"))
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/fluxity.html -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/fluxity.html Changed
10
 
1
@@ -89,7 +89,7 @@
2
 <p>In <em>init_script()</em> we define the editors that will be presented to the user and set some metadata like the name of the script displayed to the user and the script author.</p>
3
 <h3 id="init_render">init_render()</h3>
4
 <pre><code>def init_render(fctx):
5
-    # The script is possibly rendered using multiple prosesses and we need to have the
6
+    # The script is possibly rendered using multiple processes and we need to have the
7
     # same sequence of random numbers in all processes. If we don't set seed we'll get completely different
8
     # ball positions, colors and speeds in different rendering processes.
9
     random.seed(fctx.get_editor_value(&quot;Random Seed&quot;))
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/text_3/credit_scroll.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/text_3/credit_scroll.py Changed
10
 
1
@@ -524,7 +524,7 @@
2
 
3
 class AbstractCreditBlock(AbstractTextBlock):
4
     
5
-    # These indexs must match those in editor "Credits Layout".
6
+    # These indexes must match those in editor "Credits Layout".
7
     LAYOUT_SINGLE_LINE_CENTERED = 0
8
     LAYOUT_TWO_LINE_CENTERED = 1
9
     LAYOUT_SINGLE_LINE_RIGHT_JUSTIFIED = 2
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/transitions_2/hex_overlay.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/res/mediaplugins/transitions_2/hex_overlay.py Changed
10
 
1
@@ -35,7 +35,7 @@
2
     fctx.set_data_obj("points", _points)
3
     
4
 def init_render(fctx):
5
-    # The script is usually rendered using multiple prosesses and we need to have the exact
6
+    # The script is usually rendered using multiple processes and we need to have the exact
7
     # same random number sequence in all processes.
8
     random.seed(fctx.get_editor_value("Random Seed"))
9
     
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/respaths.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/respaths.py Changed
12
 
1
@@ -87,10 +87,3 @@
2
     FLUXITY_API_DOC = root_path + "/res/mediaplugins/fluxity.html"
3
     INFO_TIPS_DOC = root_path + "/res/help/en/infotips.html"
4
     USBHID_DRIVERS_PATH = root_path + "/res/usbhid/"
5
-    
6
-def apply_dark_theme():
7
-    global IMAGE_PATH
8
-    IMAGE_PATH = ROOT_PATH + "/res/darktheme/"
9
-
10
-
11
-
12
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/resync.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/resync.py Changed
86
 
1
@@ -63,20 +63,21 @@
2
     calculate_and_set_child_clip_sync_states()
3
 
4
 def calculate_and_set_child_clip_sync_states():
5
-    parent_track = current_sequence().first_video_track()
6
     for child_clip, track in sync_children.items():
7
         child_index = track.clips.index(child_clip)
8
         child_clip_start = track.clip_start(child_index) - child_clip.clip_in
9
 
10
         parent_clip = child_clip.sync_data.master_clip
11
+        parent_track = child_clip.sync_data.master_clip_track 
12
         try:
13
             parent_index = parent_track.clips.index(parent_clip)
14
         except:
15
             child_clip.sync_data.sync_state = appconsts.SYNC_PARENT_GONE
16
             continue
17
-        parent_clip_start = parent_track.clip_start(parent_index) - parent_clip.clip_in
18
 
19
+        parent_clip_start = parent_track.clip_start(parent_index) - parent_clip.clip_in
20
         pos_offset = child_clip_start - parent_clip_start
21
+
22
         if pos_offset == child_clip.sync_data.pos_offset:
23
             child_clip.sync_data.sync_state = appconsts.SYNC_CORRECT
24
         else:
25
@@ -89,7 +90,7 @@
26
     # Returns list of tuples with data needed to do resync.
27
     # Return tuples are of type (clip, track, index, child_clip_start_on_timeline, pos_off)
28
     resync_data = 
29
-    parent_track = current_sequence().first_video_track()
30
+
31
     for clip_track_tuple in clips_list:
32
         child_clip, track = clip_track_tuple
33
         child_index = track.clips.index(child_clip)
34
@@ -97,13 +98,14 @@
35
         child_clip_start = child_clip_pos_on_tline - child_clip.clip_in
36
 
37
         parent_clip = child_clip.sync_data.master_clip
38
+        parent_track = child_clip.sync_data.master_clip_track
39
         try:
40
             parent_index = parent_track.clips.index(parent_clip)
41
         except:
42
             # Parent clip no longer awailable
43
             continue
44
+            
45
         parent_clip_start = parent_track.clip_start(parent_index) - parent_clip.clip_in
46
-
47
         pos_offset = child_clip_start - parent_clip_start
48
 
49
         resync_data.append((child_clip, track, child_index, child_clip_pos_on_tline, pos_offset))
50
@@ -119,6 +121,35 @@
51
     
52
     return clips_data
53
 
54
+def get_track_all_resync_action_data(child_track, parent_track):
55
+    orig_sync_data = {}
56
+    for clip in child_track.clips:
57
+        if clip.is_blanck_clip == True:
58
+            continue
59
+        orig_sync_dataclip = clip.sync_data
60
+    
61
+    new_sync_data = {}
62
+    for i in range(0, len(child_track.clips)):
63
+        clip = child_track.clipsi
64
+        if clip.is_blanck_clip == True:
65
+            continue
66
+        clip_start_frame = child_track.clip_start(i)
67
+        parent_clip = current_sequence().find_parent_clip_for_clip_start(parent_track, clip_start_frame)
68
+        if parent_clip != None:
69
+            parent_index = parent_track.clips.index(parent_clip)
70
+
71
+            # Get offset
72
+            child_clip_start = clip_start_frame - clip.clip_in
73
+            parent_clip_start = parent_track.clip_start(parent_index) - parent_clip.clip_in
74
+            pos_offset = child_clip_start - parent_clip_start
75
+            sync_data = (pos_offset, parent_clip, parent_track)
76
+        else:
77
+            sync_data = (None, None, None)
78
+            
79
+        new_sync_dataclip = sync_data
80
+    
81
+    return (orig_sync_data, new_sync_data)
82
+
83
 def print_sync_children():
84
     for child_clip, track in sync_children.items():
85
         print(child_clip.id)
86
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/sequence.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/sequence.py Changed
91
 
1
@@ -26,6 +26,8 @@
2
     import mlt7 as mlt
3
 except:
4
     import mlt
5
+
6
+import hashlib
7
 import os
8
 
9
 import appconsts
10
@@ -116,7 +118,8 @@
11
         self.watermark_file_path = None
12
         self.seq_len = 0 # used in trim crash hack, remove when fixed
13
         self.compositing_mode = initial_comp_mode
14
-
15
+        self.uid = hashlib.md5(str(os.urandom(32)).encode('utf-8')).hexdigest()
16
+ 
17
         # MLT objects for a multitrack sequence
18
         self.init_mlt_objects()
19
         
20
@@ -257,6 +260,7 @@
21
         
22
         # Add method that returns track name
23
         new_track.get_name = lambda : utils.get_track_name(new_track, self) 
24
+        new_track.parent_track = None
25
         
26
         return new_track
27
 
28
@@ -505,6 +509,7 @@
29
         clip.titler_data = None # titler_data != None defines clips as a title clip that can be edited in Titler.
30
         clip.slowmo_data = None # tuple (slowmo_type, orig_media_file_path, slowmo_clip_media_area, slowmo_speed_data,
31
                                 #        orig_media_in, orig_media_out)
32
+        clip.link_seq_data = None # link_seq_data is uid of linked sequence
33
 
34
     def clone_track_clip(self, track, index):
35
         orig_clip = track.clipsindex
36
@@ -518,6 +523,7 @@
37
         if clip.media_type != appconsts.PATTERN_PRODUCER:
38
             clone_clip = self.create_file_producer_clip(clip.path, None, False, clip.ttl) # file producer
39
         else:
40
+            # Pattern producers are deprecated, look to remove this.
41
             clone_clip = self.create_pattern_producer(clip.create_data) # pattern producer
42
         self.clone_clip_and_filters(clip, clone_clip)
43
         return clone_clip
44
@@ -528,10 +534,11 @@
45
         used in another clip's place, but not id, master_clip and selection
46
         properties that are part of original clips state in sequence.
47
         """
48
+        clone_clip.name = clip.name
49
         clone_clip.clip_in = clip.clip_in
50
         clone_clip.clip_out = clip.clip_out
51
         clone_clip.filters = 
52
-        
53
+    
54
         for f in clip.filters:
55
             clone_filter = mltfilters.clone_filter_object(f, self.profile)
56
             clone_clip.attach(clone_filter.mlt_filter)
57
@@ -1020,6 +1027,33 @@
58
                 
59
         return cut_frame
60
 
61
+    def find_parent_clip_for_clip_start(self, parent_track, clip_start_frame):
62
+        parent_clip = None
63
+        last_pos_diff = None
64
+        for i in range(0, len(parent_track.clips)):
65
+
66
+            clip = parent_track.clipsi            
67
+            parent_clip_start_frame = parent_track.clip_start(i)
68
+            if clip.is_blanck_clip == True:
69
+                continue
70
+            
71
+            new_diff = parent_clip_start_frame - clip_start_frame
72
+
73
+            if parent_clip == None:
74
+                parent_clip = clip
75
+                last_pos_diff = new_diff
76
+            else:
77
+                if new_diff >= 0:
78
+                    if abs(new_diff) <= abs(last_pos_diff):
79
+                        return clip
80
+                    else:
81
+                        return parent_clip
82
+                else:
83
+                    parent_clip = clip
84
+                    last_pos_diff = new_diff
85
+
86
+        return parent_clip
87
+
88
     def find_prev_cut_frame(self, tline_frame):
89
         """
90
         Returns frame of next cut in active tracks relative to timeline.
91
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/syncsplitevent.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/syncsplitevent.py Changed
201
 
1
@@ -22,15 +22,18 @@
2
 Module handles events related to audiosplits and setting clip sync relationships.
3
 """
4
 
5
-from gi.repository import Gdk
6
+from gi.repository import Gdk, GLib, Gtk
7
 
8
 import appconsts
9
+import dialogs
10
 import dialogutils
11
 import edit
12
 import editorstate
13
 from editorstate import current_sequence
14
 from editorstate import get_track
15
+import editorpersistance
16
 import gui
17
+import guipopover
18
 import movemodes
19
 import resync
20
 import tlinewidgets
21
@@ -40,6 +43,9 @@
22
 
23
 parent_selection_data = None
24
 
25
+CHILD_SELECTION_SINGLE = 1
26
+CHILD_SELECTION_MULTIPLE = 2
27
+
28
 
29
 # ----------------------------------- split audio
30
 def split_audio_synched(popup_data):
31
@@ -57,7 +63,7 @@
32
         
33
     split_action, parent_clip, child_clip, child_clip_track = _get_split_audio_edit_action(popup_data)
34
     split_action.do_edit()
35
-    sync_action = _get_set_sync_action(child_clip_track, child_clip, parent_clip)
36
+    sync_action = _get_set_sync_action(child_clip_track, child_clip, parent_clip, track)
37
     sync_action.do_edit()
38
 
39
 def split_audio_synched_from_clips_list(clips, track):
40
@@ -88,15 +94,44 @@
41
     for split_data in split_actions_data:
42
         parent_clip, child_clip, child_clip_track = split_data
43
         
44
-        sync_action = _get_set_sync_action(child_clip_track, child_clip, parent_clip)
45
+        sync_action = _get_set_sync_action(child_clip_track, child_clip, parent_clip, track)
46
         set_sync_actions.append(sync_action)
47
 
48
     sync_consolidated_action = edit.ConsolidatedEditAction(set_sync_actions)
49
     sync_consolidated_action.do_consolidated_edit()
50
-    
51
-def _get_set_sync_action(child_clip_track, child_clip, parent_clip):
52
-    # This is quarenteed because GUI option to do this is only available on this track
53
-    parent_track = current_sequence().trackscurrent_sequence().first_video_index
54
+
55
+def sync_menu_launch_pressed(launcher, widget, event):
56
+    guipopover.sync_menu_show(launcher, widget, _sync_property_item_activated, _sync_split_property_activated, _auto_sync_split_menu_item_item_activated)
57
+
58
+def _sync_property_item_activated(action, event, msg):
59
+    new_state = not(action.get_state().get_boolean())
60
+
61
+    if msg == "autosplit":
62
+        editorpersistance.prefs.sync_autosplit = new_state
63
+    elif msg == "dualtrim":
64
+        editorpersistance.prefs.sync_dualtrim = new_state
65
+    elif msg == "showsync":
66
+        editorpersistance.prefs.show_sync = new_state
67
+        
68
+    action.set_state(GLib.Variant.new_boolean(new_state))
69
+
70
+def _sync_split_property_activated(action, variant):
71
+    if variant.get_string() == "splitmirror":
72
+        editorpersistance.prefs.sync_mirror = True
73
+    else:
74
+        editorpersistance.prefs.sync_mirror = False
75
+
76
+    action.set_state(variant)
77
+    editorpersistance.save()
78
+    #guipopover._tline_properties_popover.hide()
79
+
80
+def _auto_sync_split_menu_item_item_activated(action, new_value_variant):
81
+    msg = int(new_value_variant.get_string())
82
+    editorpersistance.prefs.sync_autosplit = msg
83
+    editorpersistance.save()
84
+    action.set_state(new_value_variant)
85
+
86
+def _get_set_sync_action(child_clip_track, child_clip, parent_clip, parent_track):
87
     child_index = child_clip_track.clips.index(child_clip)
88
     parent_clip_index = parent_track.clips.index(parent_clip)
89
     
90
@@ -144,10 +179,16 @@
91
     return _get_split_audio_edit_action(popup_data)
92
 
93
 def _get_split_audio_edit_action(popup_data):
94
-    # NOTE: THIS HARD CODES ALL SPLITS TO HAPPEN TO TRACK A1, THIS MAY CHANGE
95
-    to_track = current_sequence().trackscurrent_sequence().first_video_index - 1
96
-
97
     clip, track, item_id, x = popup_data
98
+
99
+    if editorpersistance.prefs.sync_mirror == False:
100
+        to_track = current_sequence().trackscurrent_sequence().first_video_index - 1
101
+    else:
102
+        to_track_id = (current_sequence().first_video_index - 1) - (track.id - current_sequence().first_video_index)
103
+        if to_track_id < 1:
104
+            to_track_id = 1
105
+        to_track = current_sequence().tracksto_track_id
106
+        
107
     press_frame = tlinewidgets.get_frame(x)
108
     index = current_sequence().get_clip_index(track, press_frame)
109
     frame = track.clip_start(index)
110
@@ -165,30 +206,119 @@
111
     
112
     return (action, clip, audio_clip, to_track)
113
 
114
-# ---------------------------------------------- sync parent clips
115
-def init_select_master_clip(popup_data):
116
-    clip, track, item_id, x = popup_data
117
-    frame = tlinewidgets.get_frame(x)
118
-    child_index = current_sequence().get_clip_index(track, frame)
119
+def get_synched_split_action_for_clip_and_track(clip, track):
120
+    if editorpersistance.prefs.sync_mirror == False:
121
+        to_track = current_sequence().trackscurrent_sequence().first_video_index - 1
122
+    else:
123
+        to_track_id = (current_sequence().first_video_index - 1) - (track.id - current_sequence().first_video_index)
124
+        if to_track_id < 1:
125
+            to_track_id = 1
126
+        to_track = current_sequence().tracksto_track_id
127
+        
128
+    index = track.clips.index(clip)
129
+    frame = track.clip_start(index)
130
+
131
+    audio_clip = current_sequence().create_file_producer_clip(clip.path, None, False, clip.ttl)
132
+    audio_clip.media_type = appconsts.AUDIO
133
+    split_length = clip.clip_out - clip.clip_in + 1 # +1 out is inclusive and we're looking for length
134
+    data = { "parent_clip":clip,
135
+             "audio_clip":audio_clip,
136
+             "over_in":frame,
137
+             "over_out":frame + split_length,
138
+             "to_track":to_track,
139
+             "track":track}
140
+
141
+    action = edit.audio_synched_splice_action(data)
142
+    return action
143
 
144
-    if not (track.clipschild_index == clip):
145
-        # This should never happen 
146
-        print("big fu at _init_select_master_clip(...)")
147
+def set_track_clips_sync(child_track):
148
+    dialogs.set_parent_track_dialog(child_track, _parent_track_selected)
149
+ 
150
+def _parent_track_selected(dialog, response_id, data):
151
+    if response_id == Gtk.ResponseType.ACCEPT:
152
+        child_track, selection_data, tracks_combo = data
153
+        parent_track = selection_datatracks_combo.get_active()
154
+        
155
+        dialog.destroy()
156
+        
157
+        do_set_track_clips_sync(child_track, parent_track)
158
+        child_track.parent_track = parent_track
159
+    else:
160
+        dialog.destroy()
161
+
162
+def do_set_track_clips_sync(child_track, parent_track):
163
+    if len(parent_track.clips) == 0:
164
+        return
165
+    if len(child_track.clips) == 0:
166
+        return
167
+        
168
+    orig_sync_data, new_sync_data = resync.get_track_all_resync_action_data(child_track, parent_track)
169
+    
170
+    data = {"child_track":child_track,
171
+            "orig_sync_data":orig_sync_data,
172
+            "new_sync_data":new_sync_data}
173
+    
174
+    action = edit.set_track_sync_action(data)
175
+    action.do_edit()
176
+
177
+def clear_track_clips_sync(child_track):
178
+    orig_sync_data = {}
179
+    sync_data_exists = False
180
+    for clip in child_track.clips:
181
+        if clip.is_blanck_clip == True:
182
+            continue
183
+        if  clip.sync_data != None:
184
+            sync_data_exists = True
185
+        
186
+        orig_sync_dataclip = clip.sync_data
187
+    
188
+    # Let's not put noop edits in undo stack.
189
+    if sync_data_exists == False:
190
         return
191
 
192
+    data = {"child_track":child_track,
193
+            "orig_sync_data":orig_sync_data}
194
+    
195
+    action = edit.clear_track_sync_action(data)
196
+    action.do_edit()
197
+
198
+
199
+# ---------------------------------------------- sync parent clips
200
+def init_select_master_clip(popup_data):
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tlineaction.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tlineaction.py Changed
91
 
1
@@ -377,6 +377,10 @@
2
     Removes 1 - n long continuous clip range from track and closes
3
     the created gap.
4
     """
5
+    if boxmove.box_selection_data != None:
6
+        boxmove.box_selection_splice_out()
7
+        return
8
+
9
     if movemodes.selected_track == -1:
10
         return
11
 
12
@@ -457,7 +461,7 @@
13
         cover_form_clip = track.clipsmovemodes.selected_range_in - 1
14
         cover_to_clip = track.clipsmovemodes.selected_range_in + 1
15
         
16
-        real_length = clip.get_length() # this the mlt finction giving media length, not length on timeline
17
+        real_length = clip.get_length() # this the mlt function giving media length, not length on timeline
18
 
19
         to_part = real_length // 2
20
         from_part = real_length - to_part
21
@@ -497,6 +501,10 @@
22
     Removes 1 - n long continuous clip range from track and fills
23
     the created gap with a blank clip
24
     """
25
+    if boxmove.box_selection_data != None:
26
+        boxmove.box_selection_lift()
27
+        return
28
+
29
     if movemodes.selected_track == -1:
30
         return
31
 
32
@@ -831,6 +839,16 @@
33
 def resync_track_button_pressed():
34
     syncsplitevent.resync_track()
35
 
36
+def set_track_sync_button_pressed():
37
+    if movemodes.selected_track != -1:
38
+        child_track = current_sequence().tracksmovemodes.selected_track
39
+        syncsplitevent.set_track_clips_sync(child_track)
40
+
41
+def clear_track_sync_button_pressed():
42
+    if movemodes.selected_track != -1:
43
+        child_track = current_sequence().tracksmovemodes.selected_track
44
+        syncsplitevent.clear_track_clips_sync(child_track)
45
+        
46
 def sync_compositor(compositor):
47
     track = current_sequence().trackscompositor.transition.b_track # b_track is source track where origin clip is
48
     origin_clip = None
49
@@ -1014,7 +1032,12 @@
50
         
51
         # Paste clips.
52
         # Clips are pasted after track content end.
53
-        if track.get_length() < tline_pos:
54
+        if track.get_length() - 2 < tline_pos:
55
+            data = {"track":track,
56
+                    "clips":new_clips}
57
+            action = edit.append_multiple_action(data)
58
+            action.do_edit()
59
+        elif track.get_length() < tline_pos:
60
             blank_length = tline_pos - track.get_length() 
61
             # Do edit
62
             data = {"track":track,
63
@@ -1037,12 +1060,25 @@
64
             if paste_on_cut == True:
65
                 editevent.do_multiple_clip_insert(track, paste_clips, tline_pos)
66
             else:
67
-                cut_action = cut_pressed(True)
68
+                # Get index and clip
69
+                index = track.get_clip_index_at(int(tline_pos))
70
+                clip = track.clipsindex            
71
+
72
+                # Get cut frame in clip frames
73
+                clip_start_in_tline = track.clip_start(index)
74
+                clip_frame = tline_pos - clip_start_in_tline + clip.clip_in
75
+
76
+                # Do edit
77
+                data = {"track":track,
78
+                        "index":index,
79
+                        "clip":clip,
80
+                        "clip_cut_frame":clip_frame}
81
+                cut_action = edit.cut_action(data)
82
+        
83
                 multi_insert_action = editevent.do_multiple_clip_insert(track, paste_clips, tline_pos, True)
84
                 actions = cut_action, multi_insert_action
85
                 consolidated_action = edit.ConsolidatedEditAction(actions)
86
                 consolidated_action.do_consolidated_edit()
87
-                #editevent.do_multiple_clip_insert(track, paste_clips, tline_pos)
88
     else:
89
         # Paste clips
90
         editevent.do_multiple_clip_insert(track, paste_clips, tline_pos)
91
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tlinewidgets.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tlinewidgets.py Changed
201
 
1
@@ -105,7 +105,8 @@
2
 INSRT_ICON_POS_HIGH = (108, 32)
3
 INSRT_ICON_POS = (108, 18)
4
 INSRT_ICON_POS_SMALL = (108, 6)
5
-
6
+SYNC_ICON_POS_HIGH = (88, 12)
7
+ 
8
 # tracks column icons
9
 FULL_LOCK_ICON = None
10
 TRACK_BG_ICON = None
11
@@ -115,6 +116,7 @@
12
 MUTE_ALL_ICON = None
13
 TRACK_ALL_ON_V_ICON = None
14
 TRACK_ALL_ON_A_ICON = None
15
+SYNC_ICON = None
16
 
17
 # clip icons
18
 FILTER_CLIP_ICON = None
19
@@ -262,7 +264,8 @@
20
 INSERT_MODE_COLOR = (0.9,0.9,0.0)
21
 OVERWRITE_MODE_COLOR = (0.9,0.0,0.0)
22
 OVERLAY_TRIM_COLOR = (0.81, 0.82, 0.3)
23
-BOX_BOUND_COLOR =(0.137, 0.80, 0.85)
24
+OVERLAY_TRIM_OVERWRITE_COLOR = (0.81, 0.3, 0.3)
25
+BOX_BOUND_COLOR =(0.8, 0.8, 0.8, 0.3)
26
 TRIM_MAX_RED = (1.0,0.1,0.1)
27
 
28
 POINTER_TRIANGLE_COLOR = (0.6, 0.7, 0.8, 0.7)
29
@@ -313,7 +316,8 @@
30
 pointer_context = appconsts.POINTER_CONTEXT_NONE
31
 DRAG_SENSITIVITY_AREA_WIDTH_PIX = 6
32
 MULTI_TRIM_ROLL_SENSITIVITY_AREA_WIDTH_PIX = 2
33
-MULTI_TRIM_SLIP_SENSITIVITY_AREA_WIDTH_PIX = 14
34
+MULTI_TRIM_SLIP_SENSITIVITY_AREA_WIDTH_PIX = 20
35
+MULTI_TRIM_ENDS_SENSITIVITY_AREA_WIDTH_PIX = 18
36
 
37
 # ref to singleton TimeLineCanvas instance for mode setting and some position
38
 # calculations.
39
@@ -342,7 +346,7 @@
40
     VIDEO_MUTE_ICON, ALL_MUTE_ICON, TRACK_BG_ICON, MUTE_AUDIO_ICON, MUTE_VIDEO_ICON, MUTE_ALL_ICON, \
41
     TRACK_ALL_ON_V_ICON, TRACK_ALL_ON_A_ICON, MUTE_AUDIO_A_ICON, TC_POINTER_HEAD, EDIT_INDICATOR, \
42
     LEVELS_RENDER_ICON, SNAP_ICON, KEYBOARD_ICON, CLOSE_MATCH_ICON, CLIP_MARKER_ICON, \
43
-    INSERT_ARROW_ICON_INACTIVE, INSERT_ARROW_ICON_UP_INACTIVE, TITLE_ICON 
44
+    INSERT_ARROW_ICON_INACTIVE, INSERT_ARROW_ICON_UP_INACTIVE, TITLE_ICON, SYNC_ICON 
45
 
46
     FULL_LOCK_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "full_lock.png")
47
     FILTER_CLIP_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "filter_clip_icon_sharp.png")
48
@@ -360,6 +364,7 @@
49
     KEYBOARD_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "keyb_trim.png")
50
     CLOSE_MATCH_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "close_match.png")
51
     CLIP_MARKER_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "clip_marker.png")
52
+    SYNC_ICON = cairo.ImageSurface.create_from_png(respaths.IMAGE_PATH + "track_sync_icon.png")
53
     COMPOSITOR_ICON = guiutils.get_cairo_image("compositor_icon")
54
     TITLE_ICON = guiutils.get_cairo_image("open_titler")
55
         
56
@@ -690,6 +695,7 @@
57
         s_data = data"box_selection_data"
58
 
59
         # Draw moved clips
60
+        cr.set_source_rgba(*BOX_BOUND_COLOR)
61
         for i in range(0, len(s_data.track_selections)):
62
             track_selection = s_data.track_selectionsi
63
             y = _get_track_y(track_selection.track_id)
64
@@ -724,7 +730,7 @@
65
                     
66
         # Draw bounding box
67
         cr.set_line_width(6.0)
68
-        cr.set_source_rgb(*BOX_BOUND_COLOR)
69
+        cr.set_source_rgba(*BOX_BOUND_COLOR)
70
         x = (s_data.topleft_frame  - pos + data"delta") * pix_per_frame
71
         w = s_data.width_frames * pix_per_frame
72
         y = _get_track_y(s_data.topleft_track)
73
@@ -1167,10 +1173,10 @@
74
 def draw_clip_end_drag_overlay(cr, data):
75
     if data"editing_clip_end" == True:
76
         end = data"frame"  - pos
77
-        start = data"bound_start"  - pos
78
+        start = data"clip_start"  - pos
79
     else:
80
         start = data"frame"  - pos
81
-        end = data"bound_end"  - pos
82
+        end = data"clip_end"  - pos
83
 
84
     y = _get_track_y(data"track".id)
85
     
86
@@ -1186,7 +1192,10 @@
87
     cr.rectangle(scale_in, int(y) + 1.5, int(scale_length), track_height - 2.0)
88
     cr.set_source_rgba(*CLIP_END_DRAG_OVERLAY_COLOR)
89
     cr.fill_preserve()
90
-    cr.set_source_rgb(*OVERLAY_TRIM_COLOR)
91
+    if data"submode" == 0: # INSERT 
92
+        cr.set_source_rgb(*OVERLAY_TRIM_COLOR)
93
+    else:
94
+        cr.set_source_rgb(*OVERLAY_TRIM_OVERWRITE_COLOR)
95
     cr.stroke()
96
 
97
     if editorpersistance.prefs.delta_overlay == True:
98
@@ -1549,12 +1558,13 @@
99
         
100
         # INSERT, OVERWRITE
101
         if (EDIT_MODE() == editorstate.INSERT_MOVE or EDIT_MODE() == editorstate.OVERWRITE_MOVE) and editorstate.overwrite_mode_box == False:
102
-            # the + 4 is attempt to center sensitivity area at cut. Because we are doing sensitivity testing on opposite sides of a single clip, not on
103
-            # both sides of a cut we are having trouble centering the sensitivity area. 
104
-            if abs(x - _get_frame_x(clip_start_frame)) < DRAG_SENSITIVITY_AREA_WIDTH_PIX + 4:
105
-                return appconsts.POINTER_CONTEXT_END_DRAG_LEFT
106
-            if abs(x + 4 - _get_frame_x(clip_end_frame)) < DRAG_SENSITIVITY_AREA_WIDTH_PIX:
107
-                return appconsts.POINTER_CONTEXT_END_DRAG_RIGHT
108
+            if not(editorpersistance.prefs.disable_drag_when_selected == True and clip.selected == True):
109
+                # the + 4 is attempt to center sensitivity area at cut. Because we are doing sensitivity testing on opposite sides of a single clip, not on
110
+                # both sides of a cut we are having trouble centering the sensitivity area. 
111
+                if abs(x - _get_frame_x(clip_start_frame)) < DRAG_SENSITIVITY_AREA_WIDTH_PIX + 4:
112
+                    return appconsts.POINTER_CONTEXT_END_DRAG_LEFT
113
+                if abs(x + 4 - _get_frame_x(clip_end_frame)) < DRAG_SENSITIVITY_AREA_WIDTH_PIX:
114
+                    return appconsts.POINTER_CONTEXT_END_DRAG_RIGHT
115
             
116
             return appconsts.POINTER_CONTEXT_NONE
117
         # TRIM
118
@@ -1583,19 +1593,35 @@
119
                 return appconsts.POINTER_CONTEXT_MULTI_ROLL
120
             elif abs(x - clip_end_frame_x) < MULTI_TRIM_ROLL_SENSITIVITY_AREA_WIDTH_PIX:
121
                 return appconsts.POINTER_CONTEXT_MULTI_ROLL
122
-            elif abs(x - clip_center_x) < MULTI_TRIM_SLIP_SENSITIVITY_AREA_WIDTH_PIX:
123
-                if clip.is_blanck_clip == True:
124
-                     return appconsts.POINTER_CONTEXT_NONE
125
-                return appconsts.POINTER_CONTEXT_MULTI_SLIP
126
-            elif abs(frame - clip_start_frame) < abs(frame - clip_end_frame):
127
-                if clip.is_blanck_clip == True:
128
-                     return appconsts.POINTER_CONTEXT_NONE
129
-                return appconsts.POINTER_CONTEXT_TRIM_LEFT
130
+            
131
+            if editorpersistance.prefs.wide_multitrim_slip == False:
132
+                if abs(x - clip_center_x) < MULTI_TRIM_SLIP_SENSITIVITY_AREA_WIDTH_PIX:
133
+                    if clip.is_blanck_clip == True:
134
+                         return appconsts.POINTER_CONTEXT_NONE
135
+                    return appconsts.POINTER_CONTEXT_MULTI_SLIP
136
+                elif abs(frame - clip_start_frame) < abs(frame - clip_end_frame):
137
+                    if clip.is_blanck_clip == True:
138
+                         return appconsts.POINTER_CONTEXT_NONE
139
+                    return appconsts.POINTER_CONTEXT_TRIM_LEFT
140
+                else:
141
+                    if clip.is_blanck_clip == True:
142
+                         return appconsts.POINTER_CONTEXT_NONE
143
+                    return appconsts.POINTER_CONTEXT_TRIM_RIGHT
144
             else:
145
-                if clip.is_blanck_clip == True:
146
-                     return appconsts.POINTER_CONTEXT_NONE
147
-                return appconsts.POINTER_CONTEXT_TRIM_RIGHT
148
-                
149
+                # Wide slip trim activation area.                        
150
+                if abs(x - clip_start_frame_x) < MULTI_TRIM_ENDS_SENSITIVITY_AREA_WIDTH_PIX:
151
+                    if clip.is_blanck_clip == True:
152
+                         return appconsts.POINTER_CONTEXT_NONE
153
+                    return appconsts.POINTER_CONTEXT_TRIM_LEFT
154
+                elif abs(x - clip_end_frame_x) < MULTI_TRIM_ENDS_SENSITIVITY_AREA_WIDTH_PIX:
155
+                    if clip.is_blanck_clip == True:
156
+                         return appconsts.POINTER_CONTEXT_NONE
157
+                    return appconsts.POINTER_CONTEXT_TRIM_RIGHT
158
+                else:
159
+                    if clip.is_blanck_clip == True:
160
+                         return appconsts.POINTER_CONTEXT_NONE
161
+                    return appconsts.POINTER_CONTEXT_MULTI_SLIP
162
+
163
         return appconsts.POINTER_CONTEXT_NONE
164
 
165
     def connect_mouse_events(self):
166
@@ -1717,11 +1743,6 @@
167
         # the first maybe partially displayed clip.
168
         clip_start_frame = clip_start_in_tline - pos
169
 
170
-        # Check if we need to collect positions for drawing sync relations 
171
-        collect_positions = False
172
-        if track.id == current_sequence().first_video_index:
173
-            collect_positions = True
174
-
175
         proxy_paths = current_proxy_media_paths()
176
 
177
         global clip_thumbnails
178
@@ -1739,8 +1760,8 @@
179
             scale_in = clip_start_frame * pix_per_frame
180
             
181
             # Collect positions for drawing sync relations 
182
-            if collect_positions:
183
-                self.parent_positionsclip.id = scale_in
184
+            #if collect_positions:
185
+            self.parent_positionsclip.id = (scale_in, track.id)
186
             
187
             # Fill clip bg 
188
             if scale_length > FILL_MIN:
189
@@ -1921,8 +1942,29 @@
190
                     except: # thumbnail not found  in dict, get it and  paint it.
191
                         try:
192
                             if clip.container_data == None:
193
-                                media_file = PROJECT().get_media_file_for_path(clip.path)
194
-                                thumb_img = media_file.icon
195
+                                if clip.slowmo_data == None:
196
+                                    # normal clip
197
+                                    media_file = PROJECT().get_media_file_for_path(clip.path)
198
+                                    thumb_img = media_file.icon
199
+                                else:
200
+                                    # slowmo clip
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/batchrendering.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/batchrendering.py Changed
10
 
1
@@ -236,7 +236,7 @@
2
     
3
         # Should not happen.
4
         if timestamp == None:
5
-            print("Failed toi read timestamp in BatchRenderIPC.app_running()")
6
+            print("Failed to read timestamp in BatchRenderIPC.app_running()")
7
             return False
8
 
9
         # Running batch render app lockfile was timestamp longer then 3 ago or
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/ccrutils.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/ccrutils.py Changed
16
 
1
@@ -147,13 +147,11 @@
2
     session_folder_path = parent_folder + session_id
3
     return session_folder_path
4
 
5
-    #return userfolders.get_container_clips_dir() + session_id
6
-
7
 def get_session_folder(parent_folder, session_id):
8
     session_folder_path = parent_folder + session_id
9
     return session_folder_path
10
 
11
-    #return userfolders.get_container_clips_dir() + session_id
12
+    # Why two methods?
13
     
14
 def get_render_folder_for_session_id(parent_folder, session_id):
15
     return _get_session_folder(parent_folder, session_id) + RENDERED_FRAMES_DIR 
16
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/fluxity.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/fluxity.py Changed
10
 
1
@@ -88,7 +88,7 @@
2
     ### init_render()
3
     ```
4
     def init_render(fctx):
5
-        # The script is possibly rendered using multiple prosesses and we need to have the
6
+        # The script is possibly rendered using multiple processes and we need to have the
7
         # same sequence of random numbers in all processes. If we don't set seed we'll get completely different
8
         # ball positions, colors and speeds in different rendering processes.
9
         random.seed(fctx.get_editor_value("Random Seed"))
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/mltxmlheadless.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/mltxmlheadless.py Changed
54
 
1
@@ -45,6 +45,7 @@
2
 
3
 _render_thread = None
4
 
5
+NO_RENDER_TARGET_FILE_SPECIFIED = "###¤¤%%NOTARGET%%¤¤##"
6
 
7
 # ----------------------------------------------------- module interface with message files
8
 # We are using message files to communicate with application.
9
@@ -70,23 +71,24 @@
10
 
11
 
12
 # --------------------------------------------------- render thread launch
13
-def main(root_path, session_id, parent_folder, xml_file_path, range_in, range_out, profile_desc):
14
+def main(root_path, session_id, parent_folder, xml_file_path, video_file_name, range_in, range_out, profile_desc):
15
     
16
     render_data = mltheadlessutils.mlt_env_init(root_path, parent_folder, session_id)
17
 
18
     global _render_thread
19
-    _render_thread = MLTXMLHeadlessRunnerThread(render_data, xml_file_path, range_in, range_out, profile_desc)
20
+    _render_thread = MLTXMLHeadlessRunnerThread(render_data, xml_file_path, video_file_name, range_in, range_out, profile_desc)
21
     _render_thread.start()
22
 
23
        
24
 
25
 class MLTXMLHeadlessRunnerThread(threading.Thread):
26
 
27
-    def __init__(self, render_data, xml_file_path, range_in, range_out, profile_desc):
28
+    def __init__(self, render_data, xml_file_path, video_file_name, range_in, range_out, profile_desc):
29
         threading.Thread.__init__(self)
30
 
31
         self.render_data = render_data # toolsencoding.ToolsRenderData object
32
         self.xml_file_path = xml_file_path
33
+        self.video_file_name = video_file_name
34
         self.range_in = int(range_in)
35
         self.range_out = int(range_out)
36
         self.length = self.range_out - self.range_in + 1
37
@@ -106,9 +108,14 @@
38
         # Video clip consumer
39
         if self.render_data.do_video_render == True:
40
             if self.render_data.save_internally == True:
41
-                file_path = ccrutils.session_folder_saved_global() + "/" + appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME + self.render_data.file_extension
42
+                # "video_file_name" is used to to create differently named versions of internally saved video clips for sequence link containers. 
43
+                if self.video_file_name == NO_RENDER_TARGET_FILE_SPECIFIED:
44
+                    video_file_name = appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME
45
+                else:
46
+                    video_file_name = self.video_file_name
47
+                file_path = ccrutils.session_folder_saved_global() + "/" + video_file_name + self.render_data.file_extension
48
             else:
49
-                file_path = self.render_data.render_dir +  "/" + self.render_data.file_name + self.render_data.file_extension
50
+                file_path = self.render_data.render_dir + "/" + self.render_data.file_name + self.render_data.file_extension
51
 
52
             consumer = renderconsumer.get_mlt_render_consumer(file_path, profile, args_vals_list)
53
 
54
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/scripttool.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/scripttool.py Changed
10
 
1
@@ -1294,7 +1294,7 @@
2
     def run(self):
3
         GLib.idle_add(_update_buffer_text, self.rendering_txt)
4
 
5
-        # GUI quarantees valid range here.
6
+        # GUI guarantees valid range here.
7
         in_frame = _mark_in
8
         self.in_frame = in_frame
9
         out_frame = _mark_out
10
_service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/stabilizedvideoheadless.py Added
143
 
1
@@ -0,0 +1,141 @@
2
+"""
3
+    Flowblade Movie Editor is a nonlinear video editor.
4
+    Copyright 2012 Janne Liljeblad.
5
+
6
+    This file is part of Flowblade Movie Editor <https://github.com/jliljebl/flowblade/>.
7
+
8
+    Flowblade Movie Editor is free software: you can redistribute it and/or modify
9
+    it under the terms of the GNU General Public License as published by
10
+    the Free Software Foundation, either version 3 of the License, or
11
+    (at your option) any later version.
12
+
13
+    Flowblade Movie Editor is distributed in the hope that it will be useful,
14
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+    GNU General Public License for more details.
17
+
18
+    You should have received a copy of the GNU General Public License
19
+    along with Flowblade Movie Editor. If not, see <http://www.gnu.org/licenses/>.
20
+"""
21
+
22
+try:
23
+    import mlt7 as mlt
24
+except:
25
+    import mlt
26
+    
27
+import os
28
+import threading
29
+import time
30
+
31
+import ccrutils
32
+import mltheadlessutils
33
+import mltprofiles
34
+import renderconsumer
35
+
36
+_render_thread = None
37
+
38
+
39
+# ----------------------------------------------------- module interface with message files
40
+# We are using message files to communicate with application.
41
+def session_render_complete(parent_folder, session_id):
42
+    return ccrutils.session_render_complete(parent_folder, session_id)
43
+
44
+def get_session_status(parent_folder, session_id):
45
+    msg = ccrutils.get_session_status_message(parent_folder, session_id)
46
+    if msg == None:
47
+        return None
48
+    fraction, elapsed = msg.split(" ")
49
+    return (fraction, elapsed)
50
+    
51
+def abort_render(parent_folder, session_id):
52
+    ccrutils.abort_render(parent_folder, session_id)
53
+
54
+def delete_session_folders(parent_folder, session_id):
55
+     ccrutils.delete_internal_folders(parent_folder, session_id)
56
+
57
+# --------------------------------------------------- render thread launch
58
+def main(root_path, session_id, parent_folder, write_file, results_file, 
59
+         profile_desc, encoding_option_index, quality_option_index, source_path):
60
+        
61
+    mltheadlessutils.mlt_env_init(root_path, parent_folder, session_id)
62
+
63
+    global _render_thread
64
+    _render_thread = StaxbilizedVideoRenderThread(  write_file, results_file, profile_desc, encoding_option_index,
65
+                                                    quality_option_index, source_path)
66
+    _render_thread.start()
67
+
68
+       
69
+
70
+class StaxbilizedVideoRenderThread(threading.Thread):
71
+
72
+    def __init__(self, write_file, results_file, profile_desc, encoding_option_index,
73
+                                                    quality_option_index, source_path):
74
+        threading.Thread.__init__(self)
75
+
76
+        self.write_file = write_file
77
+        self.profile_desc = profile_desc
78
+        self.encoding_option_index = int(encoding_option_index)
79
+        self.quality_option_index = int(quality_option_index)
80
+        self.source_path = source_path
81
+        self.results_file = results_file
82
+
83
+        self.abort = False
84
+
85
+    def run(self):
86
+        self.start_time = time.monotonic()
87
+
88
+        profile = mltprofiles.get_profile(self.profile_desc) 
89
+        producer = mlt.Producer(profile, str(self.source_path)) # this runs 0.5s+ on some clips
90
+        
91
+        stabilize_filter = mlt.Filter(profile, "vidstab")
92
+        stabilize_filter.set("results", str(self.results_file))
93
+
94
+        # Add filter to producer.
95
+        producer.attach(stabilize_filter)
96
+
97
+        # Create tractor and track to get right length
98
+        tractor = renderconsumer.get_producer_as_tractor(producer, producer.get_length() - 1)
99
+        consumer = renderconsumer.get_render_consumer_for_encoding_and_quality(self.write_file, profile, self.encoding_option_index, self.quality_option_index)
100
+        
101
+        # start and end frames, renderer stop behaviour
102
+        start_frame = 0
103
+        end_frame = producer.get_length() - 1
104
+
105
+        # Launch render
106
+        self.render_player = renderconsumer.FileRenderPlayer(self.write_file, tractor, consumer, start_frame, end_frame)
107
+        self.render_player.wait_for_producer_end_stop = True
108
+        self.render_player.start()
109
+
110
+        while self.render_player.stopped == False:
111
+            
112
+            self.check_abort_requested()
113
+            
114
+            if self.abort == True:
115
+                self.render_player.shutdown()
116
+                os._exit(0) # We are having some issues with causing prosessor usage even after reaching here.
117
+                return
118
+            
119
+            fraction = self.render_player.get_render_fraction()
120
+            self.render_update(fraction)
121
+
122
+            time.sleep(0.3)
123
+
124
+        # Write out completed flag file.
125
+        ccrutils.write_completed_message()
126
+
127
+        global _render_thread
128
+        _render_thread = None
129
+
130
+        self.render_player.shutdown()        
131
+        os._exit(0) # We are having some issues with causing prosessor usage even after reaching here.
132
+                
133
+    def check_abort_requested(self):
134
+        self.abort = ccrutils.abort_requested()
135
+
136
+    def render_update(self, fraction):
137
+        elapsed = time.monotonic() - self.start_time
138
+        msg = str(fraction) + " " + str(elapsed)
139
+        ccrutils.write_status_message(msg)
140
+
141
+
142
+
143
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/stabilizeheadless.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/stabilizeheadless.py Changed
55
 
1
@@ -52,24 +52,26 @@
2
      ccrutils.delete_internal_folders(parent_folder, session_id)
3
 
4
 # --------------------------------------------------- render thread launch
5
-def main(root_path, session_id, parent_folder, profile_desc, write_file, clip_path, accuracy, shakiness):
6
+def main(root_path, session_id, parent_folder, profile_desc, write_file, clip_path, accuracy, shakiness, smoothing, zoom):
7
     
8
     mltheadlessutils.mlt_env_init(root_path, parent_folder, session_id)
9
 
10
     global _render_thread
11
-    _render_thread = StabilizeHeadlessRunnerThread(profile_desc, write_file, clip_path, accuracy, shakiness)
12
+    _render_thread = StabilizeHeadlessRunnerThread(profile_desc, write_file, clip_path, accuracy, shakiness,  smoothing, zoom)
13
     _render_thread.start()
14
 
15
 
16
 class StabilizeHeadlessRunnerThread(threading.Thread):
17
 
18
-    def __init__(self, profile_desc, write_file, clip_path, accuracy, shakiness):
19
+    def __init__(self, profile_desc, write_file, clip_path, accuracy, shakiness, smoothing, zoom):
20
         threading.Thread.__init__(self)
21
 
22
         self.write_file = write_file
23
         self.clip_path = clip_path
24
         self.shakiness = shakiness
25
         self.accuracy = accuracy
26
+        self.smoothing = smoothing
27
+        self.zoom = zoom
28
         self.profile_desc = profile_desc
29
         self.abort = False
30
 
31
@@ -80,7 +82,7 @@
32
         producer = mlt.Producer(profile, str(self.clip_path)) # this runs 0.5s+ on some clips
33
         
34
         stabilize_filter = mlt.Filter(profile, "vidstab")
35
-        # Init values, these may actually be defaults and not needed.
36
+        # Initial values.
37
         stabilize_filter.set("stepsize", "6")
38
         stabilize_filter.set("algo", "1")
39
         stabilize_filter.set("mincontrast", 0.3)
40
@@ -97,12 +99,13 @@
41
         stabilize_filter.set("zoomspeed", "0.25")
42
         stabilize_filter.set("reload", "0")
43
         stabilize_filter.set("analyze", "0")
44
-        #stabilize_filter.set("results", "")
45
 
46
         # Apply user set analyze parameters
47
         stabilize_filter.set("filename", str(self.write_file))
48
         stabilize_filter.set("shakiness", str(self.shakiness))
49
         stabilize_filter.set("accuracy", str(self.accuracy))
50
+        stabilize_filter.set("smoothing", str(self.smoothing))
51
+        stabilize_filter.set("zoom", str(self.zoom))
52
 
53
         # Add filter to producer.
54
         producer.attach(stabilize_filter)
55
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/titler.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/titler.py Changed
10
 
1
@@ -767,7 +767,7 @@
2
                 toolsdialogs.save_titler_graphic_as_dialog(self._save_title_dialog_callback, "title.png", _titler_lastdir)
3
             else:
4
                 dialog, entry = dialogutils.get_single_line_text_input_dialog(30, 130,
5
-                                                            _("Select Tile Name"),
6
+                                                            _("Select Title Name"),
7
                                                             _("Set Name"),
8
                                                             _("Title Name:"),
9
                                                             _("Title"))
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/toolsencoding.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/toolsencoding.py Changed
118
 
1
@@ -24,6 +24,7 @@
2
 import os
3
 
4
 import appconsts
5
+from editorstate import PROJECT
6
 import guiutils
7
 import gtkbuilder
8
 import mltprofiles
9
@@ -53,7 +54,7 @@
10
     """
11
     def __init__(self):
12
         self.profile_index = None
13
-        # The DEPRECATED values are part of save data and cannot be removed without braking save files.
14
+        # The DEPRECATED values are part of save data and cannot be removed without breaking save files.
15
         self.use_default_profile = None # DEPRECATED, 'profile_index' is used.
16
         self.use_preset_encodings = None  # DEPRECATED 'encoding_option_index', 'quality_option_index' are used.
17
         self.presets_index = None  # DEPRECATED, 'encoding_option_index', 'quality_option_index' are used.
18
@@ -99,6 +100,15 @@
19
     render_data.file_name = appconsts.CONTAINER_CLIP_VIDEO_CLIP_NAME
20
     render_data.file_extension = ".mp4"
21
 
22
+    # Set default encoding if available. Only main app usage has not-None PROJECT().
23
+    # Gmic and scriptool TOOLS don't get this data, but when rendered as timeline caontainer clips, data is used. 
24
+    if PROJECT() != None:
25
+        default_encoding = PROJECT().container_default_encoding
26
+        if default_encoding != None:
27
+            enc_index, q_index = default_encoding
28
+            render_data.encoding_option_index = enc_index
29
+            render_data.quality_option_index = q_index
30
+
31
     return render_data
32
 
33
 def create_container_clip_default_alpha_render_data_object(profile):
34
@@ -135,6 +145,8 @@
35
 def create_widgets(def_profile_index, disable_audio=True, create_container_file_panel=False):
36
     """
37
     Widgets for editing render properties and viewing render progress.
38
+    
39
+    These are RE_INITIALIZED always when using this module from main app.
40
     """
41
     global widgets, disable_audio_encoding, default_profile_index
42
     default_profile_index = def_profile_index
43
@@ -183,7 +195,8 @@
44
         widgets.file_panel.movie_name.set_text(render_data.file_name)
45
         widgets.file_panel.extension_label.set_text(render_data.file_extension)
46
         widgets.file_panel.out_folder.set_current_folder(render_data.render_dir + "/")
47
-        widgets.encoding_panel.encoding_selector.categorised_combo.set_selected(mltprofiles.get_profile_for_index(render_data.encoding_option_index).description())
48
+        enc_opt = renderconsumer.encoding_optionsrender_data.encoding_option_index
49
+        widgets.encoding_panel.encoding_selector.categorised_combo.set_selected(enc_opt.name)
50
         widgets.encoding_panel.quality_selector.widget.set_active(render_data.quality_option_index)
51
         profile_desc = mltprofiles.get_profile_for_index(render_data.profile_index).description()
52
         widgets.profile_panel.out_profile_combo.categories_combo.set_selected(profile_desc)
53
@@ -199,9 +212,26 @@
54
             widgets.video_clip_panel.video_clip_combo.set_active(video_clip_combo_index)
55
             widgets.file_panel.render_location_combo.set_active(render_location_combo_index)
56
             widgets.file_panel.frame_name.set_text(render_data.frame_name)
57
-            
58
+    else:
59
+        if PROJECT() != None:
60
+            if PROJECT().container_default_encoding != None:
61
+                encoding_option_index, quality_option_index =  PROJECT().container_default_encoding 
62
+                enc_opt = renderconsumer.encoding_optionsencoding_option_index
63
+                widgets.encoding_panel.encoding_selector.categorised_combo.set_selected(enc_opt.name)
64
+                widgets.encoding_panel.quality_selector.widget.set_active(quality_option_index)
65
+
66
     return render_panel
67
 
68
+def get_default_encoding_setting_panel(default_encoding):
69
+    encoding_panel = guiutils.get_named_frame(_("Encoding Format"), widgets.encoding_panel.vbox, 4)
70
+    if default_encoding != None:
71
+        encoding_option_index, quality_option_index = default_encoding
72
+        enc_opt = renderconsumer.encoding_optionsencoding_option_index
73
+        widgets.encoding_panel.encoding_selector.categorised_combo.set_selected(enc_opt.name)
74
+        widgets.encoding_panel.quality_selector.widget.set_active(quality_option_index)
75
+
76
+    return encoding_panel
77
+
78
 def get_profile_info_small_box(profile):
79
     text = get_profile_info_text(profile)
80
     label = Gtk.Label(label=text)
81
@@ -369,10 +399,8 @@
82
         encoding_vbox.pack_start(encoding_panel, False, False, 0)
83
 
84
         encoding_hbox = Gtk.HBox(False, 2)
85
-        encoding_hbox.pack_start(guiutils.pad_label(12, 12), False, False, 0)
86
         encoding_hbox.pack_start(encoding_vbox, True, True, 0)
87
 
88
-        
89
         self.vbox = Gtk.VBox(False, 2)
90
         self.vbox.pack_start(self.video_clip_combo, False, False, 0)
91
         self.vbox.pack_start(guiutils.pad_label(12, 24), False, False, 0)
92
@@ -449,7 +477,7 @@
93
     
94
     def __init__(self, extension_label):
95
         self.quality_selector = RenderQualitySelector()
96
-        self.quality_selector.widget.set_size_request(110, 34)
97
+        self.quality_selector.widget.set_size_request(140, 34)
98
         self.quality_selector.update_quality_selection(0)
99
         self.audio_desc = Gtk.Label()
100
         self.encoding_selector = RenderEncodingSelector(self.quality_selector,
101
@@ -459,10 +487,14 @@
102
 
103
         quality_row  = Gtk.HBox()
104
         quality_row.pack_start(self.quality_selector.widget, False, False, 0)
105
-        quality_row.pack_start(Gtk.Label(), True, False, 0)
106
+        quality_row.pack_start(Gtk.Label(), True, True, 0)
107
 
108
+        enconding_row  = Gtk.HBox()
109
+        enconding_row.pack_start(self.encoding_selector.widget, False, False, 0)
110
+        enconding_row.pack_start(Gtk.Label(), True, True, 0)
111
+        
112
         self.vbox = Gtk.VBox(False, 2)
113
-        self.vbox.pack_start(self.encoding_selector.widget, False, False, 0)
114
+        self.vbox.pack_start(enconding_row, False, False, 0)
115
         self.vbox.pack_start(quality_row, False, False, 0)
116
 
117
     def set_sensitive(self, value):
118
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/tools/trackingheadless.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/tools/trackingheadless.py Changed
69
 
1
@@ -81,6 +81,7 @@
2
         self.abort = False
3
 
4
     def run(self):
5
+        global _render_thread
6
         self.start_time = time.monotonic()
7
 
8
         profile = mltprofiles.get_profile(self.profile_desc) 
9
@@ -96,10 +97,6 @@
10
         tracker_filter.set("steps", str(self.steps))
11
         tracker_filter.set("algo", str(self.algo))
12
         tracker_filter.set("disable", 0)
13
-        #tracker_filter.clear("results")
14
-
15
-        #tracker_filter.set("in", str(self.clip_in))
16
-        #tracker_filter.set("out", str(self.clip_out))
17
 
18
         # Add filter to producer.
19
         producer.attach(tracker_filter)
20
@@ -125,11 +122,26 @@
21
         xml_consumer.start()
22
         tractor.set_speed(1)
23
 
24
+        self.producer = producer
25
+        self.consumer = xml_consumer
26
+
27
         # Wait until done
28
         while xml_consumer.is_stopped() == False:
29
+
30
+            self.check_abort_requested()
31
+            
32
+            if self.abort == True:
33
+                ccrutils.write_completed_message()
34
+                self.shutdown()
35
+                _render_thread = None
36
+                os._exit(0)
37
+                return
38
+
39
             render_fraction = float(tractor.frame()) / float(producer.get_length())
40
             self.render_update(render_fraction)
41
             time.sleep(0.3)
42
+
43
+        self.shutdown()
44
         
45
         # Write out results.
46
         results = tracker_filter.get("results")
47
@@ -143,6 +155,9 @@
48
         # Write out completed flag file.
49
         ccrutils.write_completed_message()
50
 
51
+        _render_thread = None
52
+        os._exit(0) # We are having some issues with causing prosessor usage even after reaching here.
53
+        
54
     def check_abort_requested(self):
55
         self.abort = ccrutils.abort_requested()
56
 
57
@@ -151,7 +166,9 @@
58
         msg = str(fraction) + " " + str(elapsed)
59
         ccrutils.write_status_message(msg)
60
 
61
-
62
-
63
+    def shutdown(self):
64
+        self.consumer.stop()
65
+        self.producer.set_speed(0)
66
+        
67
 
68
 
69
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/trackaction.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/trackaction.py Changed
84
 
1
@@ -37,12 +37,14 @@
2
 import movemodes
3
 import projectaction
4
 import snapping
5
+import syncsplitevent
6
 import tlinewidgets
7
 import updater
8
 
9
 
10
 _menu_track_index = None
11
-        
12
+
13
+
14
 # --------------------------------------- menu events
15
 def _track_menu_item_activated(widget, action, data):
16
     track, item_id, selection_data = data
17
@@ -74,6 +76,32 @@
18
     track.edit_freedom = appconsts.FREE
19
     updater.repaint_tline()
20
 
21
+
22
+def set_track_sync(track_index):
23
+    child_track = get_track(track_index)
24
+    syncsplitevent.set_track_clips_sync(child_track)
25
+
26
+def reset_treack_sync(track_index):
27
+    child_track = get_track(track_index)
28
+    parent_track = child_track.parent_track
29
+    syncsplitevent.do_set_track_clips_sync(child_track, parent_track)
30
+
31
+def clear_track_sync(track_index):
32
+    track = get_track(track_index)
33
+    if len(track.clips) == 0:
34
+        track.parent_track = None
35
+        updater.repaint_tline()
36
+        return
37
+
38
+    syncsplitevent.clear_track_clips_sync(track)
39
+
40
+def resync_track(track_index):
41
+    track = get_track(track_index)
42
+    if len(track.clips) == 0:
43
+        return
44
+
45
+    syncsplitevent.resync_selected_track(track)
46
+
47
 def toggle_track_output():
48
     if movemodes.selected_track == -1:
49
         return
50
@@ -273,6 +301,12 @@
51
         editorpersistance.prefs.audio_scrubbing = new_state
52
         editorpersistance.save()
53
         PLAYER().set_scrubbing(new_state)
54
+    elif msg == "wideslip":
55
+        editorpersistance.prefs.wide_multitrim_slip = new_state
56
+        editorpersistance.save()
57
+    elif msg == "disabledrag":
58
+        editorpersistance.prefs.disable_drag_when_selected = new_state
59
+        editorpersistance.save()
60
     else: # media thumbnails
61
         editorstate.display_clip_media_thumbnails = new_state
62
         updater.repaint_tline()
63
@@ -327,9 +361,7 @@
64
         y_off = press_y - tlinewidgets._get_track_y(track.id)
65
         ICON_WIDTH = 14
66
         ICON_HEIGHT = 10
67
-        if editorpersistance.prefs.double_track_hights == True:
68
-            ICON_WIDTH = 28
69
-            ICON_HEIGHT = 20
70
+
71
         X_CORR_OFF = 4 # icon edge not on image left edge
72
         if press_x > tlinewidgets.COLUMN_LEFT_PAD + X_CORR_OFF and press_x < tlinewidgets.COLUMN_LEFT_PAD + ICON_WIDTH + X_CORR_OFF:
73
             # Mute icon x area hit
74
@@ -391,4 +423,8 @@
75
 
76
 POPUP_HANDLERS = {"lock":lock_track,
77
                   "unlock":unlock_track,
78
-                  "mute_track":mute_track}
79
+                  "mute_track":mute_track,
80
+                  "clearsync":clear_track_sync,
81
+                  "resync":resync_track,
82
+                  "setsync":set_track_sync,
83
+                  "ressetsync":reset_treack_sync}
84
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/translations.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/translations.py Changed
10
 
1
@@ -688,7 +688,7 @@
2
     param_names"Fade In Type" = _("Fade In Type")
3
     param_names"Image" = _("Image")
4
     param_names"RMP-peak" = _("RMP-peak")
5
-    param_names"Relese(ms)" = _("Relese(ms)")
6
+    param_names"Release(ms)" = _("Release(ms)")
7
     param_names"Ratio" = _("Ratio")
8
     param_names"Knee Radius(dB)" = _("Knee Radius(dB)")
9
     param_names"Makeup gain(dB)" = _("Makeup gain(dB)")
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/undo.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/undo.py Changed
99
 
1
@@ -22,8 +22,14 @@
2
 Module manages undo and redo stacks and executes edit actions from them
3
 on user requests.
4
 """
5
+import gi
6
+from gi.repository import GLib
7
+
8
 import time
9
+
10
+import callbackbridge
11
 import editorstate
12
+import utils
13
 
14
 set_post_undo_redo_edit_mode = None # This is set at startup to avoid circular imports.
15
 repaint_tline = None
16
@@ -164,3 +170,82 @@
17
             do_redo()
18
 
19
             time.sleep(delay)
20
+
21
+# ------------------------------------------- LINKED SEQUENCE CYCLIC TESTING
22
+WHITE = 0
23
+GREY = 1
24
+BLACK = 2
25
+
26
+is_cyclic = False
27
+
28
+class LinkNode:
29
+    
30
+    def __init__(self, seq):
31
+        self.seq = seq
32
+        self.targets = 
33
+        self.color = WHITE
34
+
35
+    def get_target_nodes(self, nodes):
36
+        target_nodes = 
37
+        for node in nodes:
38
+            if node.seq.uid in self.targets:
39
+                target_nodes.append(node)
40
+        return target_nodes
41
+
42
+def force_revert_if_cyclic_seq_links(project):
43
+    test_thread = utils.LaunchThread(project, _run_seq_link_cyclic_test)
44
+    test_thread.run()
45
+
46
+def _run_seq_link_cyclic_test(project):
47
+    global is_cyclic
48
+    is_cyclic = False
49
+    nodes = 
50
+    
51
+    for seq in project.sequences:
52
+        node = LinkNode(seq)
53
+        nodes.append(node)
54
+        for track in seq.tracks:
55
+            for clip in track.clips:
56
+                if clip.link_seq_data == None:
57
+                    continue
58
+                else:
59
+                    try:
60
+                        node.targets.append(clip.link_seq_data)
61
+                    except AttributeError:
62
+                        # Is already a set.
63
+                        node.targets.add(clip.link_seq_data)
64
+                    node.targets = set(node.targets) 
65
+
66
+    for node in nodes:
67
+        _visitDFS(node, nodes)
68
+        
69
+    if is_cyclic == True:
70
+        GLib.idle_add(_do_force_undo_with_pop)
71
+
72
+def _visitDFS(node, nodes):
73
+    global is_cyclic
74
+    
75
+    node.color = GREY
76
+
77
+    target_nodes = node.get_target_nodes(nodes)
78
+
79
+    for target_node in target_nodes:
80
+        if target_node.color == GREY:
81
+            is_cyclic = True
82
+        if target_node.color == WHITE:
83
+            _visitDFS(target_node, nodes)
84
+
85
+    node.color = BLACK
86
+
87
+
88
+def _do_force_undo_with_pop():
89
+    global undo_stack, index
90
+    
91
+    # Revert edit 
92
+    do_undo()
93
+    
94
+    # Delete edit action creating cyclic state.
95
+    if index != len(undo_stack) and (len(undo_stack) != 0):
96
+        del undo_stackindex:
97
+
98
+    callbackbridge.dialogs_show_cyclic_error()
99
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/updater.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/updater.py Changed
72
 
1
@@ -462,7 +462,11 @@
2
             PLAYER().seek_frame(0)
3
                     
4
     display_marks_tc()
5
-    
6
+
7
+    css_str = "#player-bar { background-color: #464646; border-radius: 10px;}"
8
+    gui.apply_widget_css_class_style_from_string(gui.editor_window.player_buttons_row, css_str)
9
+    gui.editor_window.monitor_clip_type.widget.queue_draw()
10
+
11
     gui.pos_bar.widget.grab_focus()
12
     gui.media_list_view.widget.queue_draw()    
13
     gui.monitor_switch.widget.queue_draw()
14
@@ -470,7 +474,6 @@
15
 
16
 def display_monitor_clip_name():#we're displaying length and range length also
17
     clip_len = utils.get_tc_string(gui.pos_bar.producer.get_length())
18
-    range_info = _get_marks_range_info(MONITOR_MEDIA_FILE().mark_in, MONITOR_MEDIA_FILE().mark_out)
19
 
20
     gui.editor_window.monitor_tc_info.set_source_name(MONITOR_MEDIA_FILE().name + " - ")
21
     gui.editor_window.monitor_tc_info.set_source_tc(clip_len)
22
@@ -492,7 +495,7 @@
23
         (f_oath, ext) = MONITOR_MEDIA_FILE().path.split(".")
24
         gui.editor_window.monitor_desc_label.set_text(ext + "(image sequence)")
25
 
26
-    gui.editor_window.monitor_tc_info.set_range_info(*range_info)
27
+    gui.editor_window.monitor_tc_info.set_range_info(MONITOR_MEDIA_FILE().mark_in, MONITOR_MEDIA_FILE().mark_out)
28
 
29
 def display_sequence_in_monitor():
30
     """
31
@@ -519,6 +522,10 @@
32
     gui.pos_bar.update_display_from_producer(PLAYER().producer)
33
     display_marks_tc()
34
 
35
+    css_str = "#player-bar { background-color: #363636; border-radius: 10px;}"
36
+    gui.apply_widget_css_class_style_from_string(gui.editor_window.player_buttons_row, css_str)
37
+    gui.editor_window.monitor_clip_type.widget.queue_draw()
38
+
39
     gui.monitor_switch.widget.queue_draw()
40
     repaint_tline()
41
 
42
@@ -535,28 +542,7 @@
43
     profile = PROJECT().profile
44
     gui.editor_window.monitor_desc_label.set_text(profile.description())
45
     
46
-    range_info = _get_marks_range_info(PLAYER().producer.mark_in, PLAYER().producer.mark_out)
47
-    gui.editor_window.monitor_tc_info.set_range_info(*range_info)
48
-
49
-def _get_marks_range_info(mark_in, mark_out):
50
-
51
-    if mark_in != -1:
52
-        mark_in_info = utils.get_tc_string(mark_in)
53
-    else:
54
-        mark_in_info = "--:--:--:--" 
55
-
56
-    if mark_out != -1:
57
-        mark_out_info = utils.get_tc_string(mark_out)
58
-    else:
59
-        mark_out_info = "--:--:--:--"
60
-
61
-    range_len = mark_out - mark_in + 1 # +1, out incl.
62
-    if mark_in != -1 and mark_out != -1:
63
-        range_info = utils.get_tc_string(range_len)
64
-    else:
65
-        range_info = "--:--:--:--" 
66
-    
67
-    return (mark_in_info, mark_out_info, range_info)
68
+    gui.editor_window.monitor_tc_info.set_range_info(PLAYER().producer.mark_in, PLAYER().producer.mark_out)
69
 
70
 def switch_monitor_display():
71
     monitorevent.stop_pressed()
72
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/usbhid.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/usbhid.py Changed
10
 
1
@@ -40,7 +40,7 @@
2
 import usbhiddrivers
3
 
4
 # how often should the USB input handler function be called?
5
-# set this too high, and there will be noticable latency in processing input
6
+# set this too high, and there will be noticeable latency in processing input
7
 # set this too low, and performance of everything else will suffer
8
 HANDLER_FREQUENCY_MSEC = 10
9
 
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/userfolders.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/userfolders.py Changed
14
 
1
@@ -44,9 +44,9 @@
2
     _xdg_data_dir = os.path.join(GLib.get_user_data_dir(), "flowblade")
3
     _xdg_cache_dir = os.path.join(GLib.get_user_cache_dir(), "flowblade")
4
 
5
-    #print("XDG Config", _xdg_config_dir)
6
-    #print("XDG Data", _xdg_data_dir)
7
-    #print("XDG Cache",_xdg_cache_dir)
8
+    print("XDG Config", _xdg_config_dir)
9
+    print("XDG Data", _xdg_data_dir)
10
+    print("XDG Cache",_xdg_cache_dir)
11
 
12
     # Make sure XDG dirs data is available and usable by trying to create XDG folders
13
     try:
14
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/utils.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/utils.py Changed
127
 
1
@@ -90,7 +90,8 @@
2
         
3
     def run(self):
4
         self.callback(self.data)
5
-        
6
+
7
+
8
 # -------------------------------- UTIL FUNCTIONS
9
 def fps():
10
     return editorstate.PROJECT().profile.fps()
11
@@ -189,6 +190,66 @@
12
     mins = mins % 60
13
     return "%02d:%02d:%02d:%02d" % (hours, mins, sec, fr)
14
 
15
+def get_tc_zeros_overlay(frame):
16
+    return get_tc_zeros_overlay_string_with_fps_v2(frame, fps())
17
+
18
+def get_tc_zeros_overlay_fine_grained(frame):
19
+    return get_tc_zeros_overlay_string_with_fps(frame, fps())
20
+    
21
+def get_tc_zeros_overlay_string_with_fps(frame, frames_per_sec):
22
+    # convert fractional frame rates (like 23.976) into integers,
23
+    # otherwise the timeline will slowly drift over time
24
+    frames_per_sec = int(round(frames_per_sec))
25
+
26
+    fr = frame % frames_per_sec
27
+    sec = frame // frames_per_sec
28
+    mins = sec // 60
29
+    sec = sec % 60
30
+    hours = mins // 60
31
+    mins = mins % 60
32
+
33
+    if hours > 9:
34
+        return ""
35
+    elif hours > 0:
36
+        return "0"
37
+    elif hours == 0 and mins > 9:
38
+        return "00:"
39
+    elif mins > 0:
40
+        return "00:0"
41
+    elif sec > 9:
42
+        return "00:00:"
43
+    elif sec > 0:
44
+        return "00:00:0"
45
+    elif fr > 9:
46
+        return "00:00:00:"
47
+    elif fr > 0:
48
+        return "00:00:00:0"
49
+    else:
50
+        return "00:00:00:00"
51
+
52
+def get_tc_zeros_overlay_string_with_fps_v2(frame, frames_per_sec):
53
+    # convert fractional frame rates (like 23.976) into integers,
54
+    # otherwise the timeline will slowly drift over time
55
+    frames_per_sec = int(round(frames_per_sec))
56
+
57
+    fr = frame % frames_per_sec
58
+    sec = frame // frames_per_sec
59
+    mins = sec // 60
60
+    sec = sec % 60
61
+    hours = mins // 60
62
+    mins = mins % 60
63
+
64
+    if hours > 0:
65
+        return ""
66
+    elif mins > 0:
67
+        return "00:"
68
+    elif sec > 0:
69
+        return "00:00:"
70
+    elif fr > 0:
71
+        return "00:00:00:"
72
+    else:
73
+        return "00:00:00:00"
74
+        
75
 def get_tc_string_with_fps_for_filename(frame, frames_per_sec):
76
     frames_per_sec = int(round(frames_per_sec))
77
 
78
@@ -199,7 +260,7 @@
79
     hours = mins / 60
80
     mins = mins % 60
81
     return "%02d-%02d-%02d-%02d" % (hours, mins, sec, fr)
82
-    
83
+
84
 def get_time_str_for_sec_float(sec):
85
     mins = sec / 60
86
     sec = sec % 60
87
@@ -387,7 +448,7 @@
88
     info = {}
89
     info"width" = clip.get_int("width")
90
     info"height" = clip.get_int("height")
91
-    info"length"  = clip.get_length()
92
+    info"length" = clip.get_length()
93
     
94
     video_index = clip.get_int("video_index")
95
     audio_index = clip.get_int("audio_index")
96
@@ -395,7 +456,9 @@
97
     long_audio_property = "meta.media." + str(audio_index) + ".codec.long_name"
98
     sample_rate_property = "meta.media." + str(audio_index) + ".codec.sample_rate"
99
     channels_property = "meta.media." + str(audio_index) +  ".codec.channels"
100
-    
101
+    pix_ftm_property = "meta.media." + str(video_index) + ".codec.pix_fmt"
102
+    color_space_property = "meta.media." + str(video_index) + ".codec.colorspace"
103
+
104
     info"vcodec" = clip.get(str(long_video_property))
105
     info"acodec" = clip.get(str(long_audio_property))
106
     info"channels" = clip.get_int(str(channels_property))
107
@@ -405,7 +468,9 @@
108
     info"fps_den" = frame.get_double("meta.media.frame_rate_den")
109
     info"progressive" = frame.get_int("meta.media.progressive") == 1
110
     info"top_field_first" = frame.get_int("meta.media.top_field_first") == 1
111
-    
112
+    info"pixel_format" = clip.get(str(pix_ftm_property))
113
+    info"colorspace" = clip.get(str(color_space_property))
114
+
115
     resource = clip.get("resource")
116
     name, ext = os.path.splitext(resource)
117
     ext = ext.lstrip(".")
118
@@ -453,7 +518,7 @@
119
 
120
     return False
121
     
122
-# File exntension lists
123
+# File extension lists
124
 _audio_file_extensions =   "act",
125
                             "aif",
126
                             "aiff",
127
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/Flowblade/workflow.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/Flowblade/workflow.py Changed
10
 
1
@@ -78,7 +78,7 @@
2
                   }
3
                   
4
     _TOOL_TIPS =  { appconsts.TLINE_TOOL_INSERT:        _("<b>Left Mouse</b> to move and insert single clip between clips.\n<b>CTRL + Left Mouse</b> to select and move clip range.\n\n<b>Left Mouse</b> on clip ends to trim clip length."),
5
-                    appconsts.TLINE_TOOL_OVERWRITE:     _("<b>Left Mouse</b> to select a clip, or to move clip or clip range into new position.\n<b>CTRL + Left Mouse</b> to select a clip range.\n\n<b>Left Mouse</b> near clip's end to trim clip length.<b>\n\nLeft Mouse Drag</b> to draw a box to select a group of clips. Multitrack selection disallows moving clips to another track."),
6
+                    appconsts.TLINE_TOOL_OVERWRITE:     _("<b>Left Mouse</b> to select a clip, or to move clip or clip range into new position.\n<b>CTRL + Left Mouse</b> to select a clip range.\n\n<b>Left Mouse</b> near clip's end to trim clip length.n\n<b>ALT + Left Mouse</b> near clip's end to overwrite trim clip length.<b>\n\nLeft Mouse Drag</b> to draw a box to select a group of clips. Multitrack selection disallows moving clips to another track."),
7
                     appconsts.TLINE_TOOL_TRIM:          _("<b>Left Mouse</b> to trim closest clip end.\n<b>Left or Right Arrow Key</b> + <b>Enter Key</b> to do the edit using keyboard."), 
8
                     appconsts.TLINE_TOOL_ROLL:          _("<b>Left Mouse</b> to move closest edit point between 2 clips.\n<b>Left or Right Arrow Key</b> + <b>Enter Key</b> to do the edit using keyboard."), 
9
                     appconsts.TLINE_TOOL_SLIP:          _("<b>Left Mouse</b> to move clip contents within clip.\n<b>Left or Right Arrow Key</b> + <b>Enter Key</b> to do the edit using keyboard."), 
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/docs/CONTRIBUTING.md -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/docs/CONTRIBUTING.md Changed
10
 
1
@@ -22,7 +22,7 @@
2
 
3
 # Code contributions
4
 
5
-**Reqiured skills** Flowblade is Python application so to get going you will need to have some experience in working in that language.
6
+**Required skills** Flowblade is Python application so to get going you will need to have some experience in working in that language.
7
 
8
 * There are many tasks that could maybe taken on at let's say beginner+ level of competence.
9
 * Solid medium level will very likely be adequate to handle most tasks.
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/docs/FAQ.md -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/docs/FAQ.md Changed
10
 
1
@@ -38,7 +38,7 @@
2
 
3
 ### Rendering with a profile with different framerate changes video playback speed and loses audio sync
4
 
5
-Yes, this will happen. When rendering the video frames are just copied, no complex slowdown/speedup prosessing is done, and audio is **not** resampled.
6
+Yes, this will happen. When rendering the video frames are just copied, no complex slowdown/speedup processing is done, and audio is **not** resampled.
7
 
8
 To maintain sync and playback both Project Profile and Render Profile both need to match the frame rate of original material.  
9
 
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/docs/Migrating_from_GTK_3_to_GTK_4.md -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/docs/Migrating_from_GTK_3_to_GTK_4.md Changed
10
 
1
@@ -43,7 +43,7 @@
2
 | Adapt to GtkStack, GtkAssistant and GtkNotebook API changes(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.27)                                                                                                                                                                                                                                                                                                                                        | Test didn't hit any, not going to be big issue.                                                                                                                                                                                                                                                                                                |
3
 | Adapt to button class hierarchy changes(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.28)                                                                                                                                                                                                                                                                                                                                                            | Gtk.RadioButton removed, 6 instances.                                                                                                                                                                                                                                                                                                          |
4
 | Adapt to GtkScrolledWindow API changes(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.29)                                                                                                                                                                                                                                                                                                                                                             | With scrollbar we hit need to set orientation, other issues likely.                                                                                                                                                                                                                                                                            |
5
-| Adapt to GtkBin removal(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.30) - Adapt to GtkContainer removal(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.31)  - Switch to GtkWidget’s children APIs(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.40)                                                                                                                                                 | In test these were succesfully handled with mostly scripted conversion.                                                                                                                                                                                                                                                                        |
6
+| Adapt to GtkBin removal(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.30) - Adapt to GtkContainer removal(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.31)  - Switch to GtkWidget’s children APIs(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.40)                                                                                                                                                 | In test these were successfully handled with mostly scripted conversion.                                                                                                                                                                                                                                                                        |
7
 | Adapt to GtkStyleContext API changes(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.35)                                                                                                                                                                                                                                                                                                                                                               | Single instance, need use function **add_provider_for_display (display, provider, priority)**                                                                                                                                                                                                                                                  |
8
 | Adapt to GtkWidget’s size request changes(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.38)                                                                                                                                                                                                                                                                                                                                                          | **get_preferred_width()** 9 instances, Gtk4 has  **GtkWidgetClass::measure()**                                                                                                                                                                                                                                                                 |
9
 | Adapt to GtkWidget’s size allocation changes(https://developer-old.gnome.org/gtk4/stable/ch41s02.html#id-1.7.4.4.39)                                                                                                                                                                                                                                                                                                                                                       | "size-allocate" signal 3 instances, The ::size-allocate signal has been removed, since it is easy to misuse. If you need to learn about sizing changes of custom drawing widgets, use the “resize” or “resize” signals. If you want to track the size of toplevel windows, use property notification for “default-width” and “default-height”. |
10
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/docs/RELEASE_NOTES.md -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/docs/RELEASE_NOTES.md Changed
201
 
1
@@ -1,5 +1,224 @@
2
 # Release Notes
3
 
4
+## FLOWBLADE 2.20
5
+Date: March 25, 2025
6
+
7
+We have now moved to SDL2 video playback for Flatpak and all systems with MLT 7.30 or higher. 
8
+
9
+Video playback for native Wayland without XWayland or for Gtk 4 (that does not support the per widget Xwindow paradigm) does not currently seem possible with SDL. Moving forward we will develop some alternative video display approach. 
10
+
11
+### Sync editing improvements
12
+
13
+A large number of changes were made to improve Flowblade sync editing worflow:
14
+
15
+* New track sync actions:
16
+  
17
+  * **Sync All Clips Action...** sets all clips in Track to be parented to closest clip on target Track. Target Track is remembered to enable single action update feature, see below.
18
+  * **Update Sync to Clips' Positions** updates parenting sync to current positions to relative to Track that was previous selected as parenting target Track.
19
+
20
+* Sync parent clips can now be on any track, not just V1. Track V1 can now also contain child clips.
21
+
22
+* Clips can now be automatically audio sync split when added to user defined set of Tracks.
23
+
24
+* Audio splits can be set to go on mirrored tracks instead of always going on track A1
25
+
26
+* Clip multiselection popup offers now *Resync*, *Clear Sync* or *Set Parent Clip* actions.
27
+
28
+* New delete edits:
29
+  
30
+  * Box selection delete and lift.
31
+  * Single and  multiselection Ripple Delete Range action.
32
+
33
+* Clip end trims can now be done in *overwrite* mode which help maintaining sync between tracks. 
34
+
35
+### Sequence Link Container Clips
36
+
37
+New **Sequence Link Container Clips** feature streamlines workflow where *Sequences* are used as parts of another *Sequence*. **Sequence Link Container Clips** can be updated to display changed contents of another *Sequence* without having to manually create a new clip and replace old clip on *Timeline*.
38
+
39
+### Preset keyframe animations
40
+
41
+Filters **Position Scale** and **Position Scale Rotate** have a new feature making it possible to add some frequently needed animations such as slide-ins and zooms in a single action.
42
+
43
+Feature is available in keyframe editor hamburger menu when selecting item **Add Preset Keyframed Movement...**.
44
+
45
+#### Monitor player buttons Row UX update
46
+
47
+Though perfectly functional, the monitor player buttons row was always visually a bit rough. We did a visual and functional update in this area, switched to a using single centered Play/Stop button, moved marks buttons to the side and made larger the visual difference between displaying Timeline and Clips in the monitor. 
48
+
49
+In a related update the timecode displays were made to display the active part of timecode in a brighter color to improve readability.   
50
+
51
+### New features
52
+
53
+* Rendered **Stabilized Media Item** creation is now possible.
54
+* **Duplicate Sequence** feature allows creating copies of *Sequences*.
55
+* **Generator Templates** feature makes possible to create **Generators** with user set properties to avoid having to set properties multiple times when creating **Generators**.
56
+
57
+### Double sized icons deprecated
58
+
59
+Double sized icons preference was removed. The results were always visually unsatisfactory. Tracks scaling preference remains, and when used in combination with scaling options provided by desktop environments it be possible to always achieve good results.
60
+
61
+### Contributions
62
+
63
+* **luzpaz** contributed a patch fixing large number of typos.
64
+
65
+### New small features and bug fixes
66
+
67
+* Zoom and shakiness parameters were activated for Stabilization filter.
68
+* Add multi-item popup menu to Media Panel.
69
+* Add 'Delete' item to Media Panel hamburger menu.
70
+* Add feature to open keyframe editor params parameter in Keyframe Tool.
71
+* Add Open in Edit Panel feature to Keyframe Tool.
72
+* Add disable clip end drags when selected feature to improve targeting small clips.
73
+* Add wide Slip trim activation area preference.
74
+* Feature to delete motion tracking data to make motion tracking more manageable.
75
+* Fix off by one issue with track syncs.
76
+* Make Media Items grab keyboard focus when selected with hamburger menu.
77
+* Add pixel format and colorspace info to file properties dialog.
78
+* Clone sync data for cut clip clones.
79
+* Fix Credit Scroll typo.
80
+* Drop cyan color from box selection display.
81
+* Updated create bindings documentation.
82
+* Make second window part of applica too to fix non-working menu actions.
83
+* Replace Pattern Producer file filering item with Container option.
84
+* Process shutdown fixes.
85
+* Show consumer type in env dialog.
86
+* Delete consumer start/stop hack.
87
+* Fix media item gmic icon bug.
88
+* Fix paste append off by one and multitrack bugs.
89
+* Add Filter Stack move arrows.
90
+* Fix Filter editing file select button replacement.
91
+* Add default container encoding options feature.
92
+* Fix Container Clips losing sync on render.
93
+
94
+## FLOWBLADE 2.18.1
95
+Date: February 17, 2025
96
+
97
+Flatpak fix for Credit Scroll generator.
98
+
99
+## FLOWBLADE 2.18
100
+Date: December 18, 2024
101
+
102
+With this release we worked on gradual improvement on features, correctness and code structure. We had some great progress in moving forward from SDL 1 video display, but there were still some issues, so that was postponed for now.
103
+
104
+
105
+### Timeline Clip slowmotion
106
+
107
+Previously Flowblade only offered workflow in which slowmotion needed to be created by adding new rendered Media Items.
108
+
109
+With this release Timeline Clips can be directly turned into slowmotion or reversed clips, a more interactive and responsive workflow requested by users.
110
+
111
+### Generator work
112
+
113
+- **Credits Scroll Generator** With this new generator scrolled or paged credit sequences can be created easily and with great amount of control over presentation. Text presentation and layout changes are controlled using a bit of MarkDown inspired markup, see documentation. Users can set initial layout parameters with GUI editors.
114
+
115
+**Other improvements:**
116
+
117
+- Upgrade **Hex Colors** generator to do boxes and triangles too, changed generator name to **Color Polygons**.
118
+  
119
+- Added **From Left Solid** and **From Right Solid** background types to **Multiline Animation** generator.
120
+  
121
+- Made generators use appropriate video clip default renders instead of frame sequences. This provided a nice performance for text animation generators.
122
+  
123
+- Made new HTML Link Button editor available to be used with generator to link to outside resources for e.g. added documentation.
124
+  
125
+
126
+### Alpha video rendering
127
+
128
+Support for rendering VP9 WebM videos with alpha channel included was added.
129
+
130
+### Gtk 4 work
131
+
132
+Object creation for quite many often used widgets is subtly different between Gtk3 and Gtk4.
133
+
134
+We added a builder module so that when we make the eventual switch we can only edit a few tens of lines of code instead of hundrends code points at widget creation sites.
135
+
136
+Work was started by porting Gtk.HPaned / Vpaned and Gtk.FileChooserButton widgets to use the new module, and for the next few cycles will work to include all possible widgets.
137
+
138
+### GUI / UX updates
139
+
140
+- Add new Project Info and Data -dialog
141
+  
142
+- Move to 3-column view for Jobs whendisplayed in left column panel
143
+  
144
+- Make Media panel minimum size configurable
145
+  
146
+- Display Project Profile in topbar
147
+  
148
+- Add box selection functionality to Insert tool
149
+  
150
+- Add mute and unmute actions to multiclip popup
151
+  
152
+- Add keyboard shortcuts for showing vector scope and rgbparade
153
+  
154
+- Improve filter edit panels expanded states initialization after moves or mask adds
155
+  
156
+
157
+### Contributions
158
+
159
+- Updated Polish translation by Stanisław Polak, who also provided a lot of valuable help in finding and fixing some missing translations.
160
+  
161
+- Typo fix from user Surfoo.
162
+  
163
+- Spanish translation update by David Gámiz Jiménez.
164
+  
165
+
166
+### Bug fixes, UX updates and other work
167
+
168
+- Fix motion several tracking bugs
169
+  
170
+- Fix non-updating numerical entry values when swicthing keyframes in GUI canvas editors
171
+  
172
+- Fix save bug when image sequence being displayed on monitor
173
+  
174
+- Fix cloning to default XDG Data Store
175
+  
176
+- Fix project Data Store clone selection combo creation bug
177
+  
178
+- Fix default renders for generator clones
179
+  
180
+- Fix media item popover initialization
181
+  
182
+- Fix mouse scrolling for GeometryNoKeyframes editor
183
+  
184
+- Fix multiclip menu delete action
185
+  
186
+- Fix multiclip menu add filter action
187
+  
188
+- Fix SyntaxWarnings for regexes
189
+  
190
+- Fix G'Mic launch visual glitch
191
+  
192
+- Fix G'Mic containers
193
+  
194
+- Update Compositing chapter in docs
195
+  
196
+- Create shortcutsdialog.py module
197
+  
198
+- Add arg to launch all tools
199
+  
200
+- Code cleanups, move monkeypatches to dedicated bridge modules
201
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/docs/creating_user_folder_bindings.md -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/docs/creating_user_folder_bindings.md Changed
26
 
1
@@ -6,13 +6,13 @@
2
 Please create pull request against this document if you have corrections or additions to improve this guide.
3
 
4
 ### Install Flowblade from OS repository
5
-See here(./INSTALLING.md). This installs the runtime dependecies to run Flowblade and use MLT. *(Note that Flatpak install does not work here because dependencies when installed by Flatpak will not be avilable to the local install of MLT we are creating)*
6
+See here(./INSTALLING.md). This installs the runtime dependencies to run Flowblade and use MLT. *(Note that Flatpak install does not work here because dependencies when installed by Flatpak will not be available to the local install of MLT we are creating)*
7
 
8
 ### Install MLT build dependencies
9
 Here is list of Ubuntu build dependencies. There could be some omissions, please file a pull request to update the list if something is found to be missing.
10
 
11
 ```bash
12
-sudo apt-get install git swig python3-dev python3-numpy libxml2-dev libsdl-dev libavdevice-dev libswscale-dev libvorbis-dev libsamplerate-dev frei0r-plugins-dev libdv-dev libavformat-dev libquicktime-dev libsox-dev libjack-dev ladspa-sdk
13
+sudo apt-get install git swig python3-dev python3-numpy libxml2-dev libsdl-dev libavdevice-dev libswscale-dev libvorbis-dev libsamplerate-dev frei0r-plugins-dev libdv-dev libavformat-dev libquicktime-dev libsox-dev libjack-dev ladspa-sdk libopencv-dev librubberband-dev libvidstab-dev
14
 ```
15
 
16
 ### Create work directory 
17
@@ -31,7 +31,7 @@
18
 #### Configure and build
19
 With terminal still open in **\<ROOT_DIR\>**.
20
 ```bash
21
-cmake -DCMAKE_BUILD_TYPE=Release -DSWIG_PYTHON=ON -DMOD_GLAXNIMATE_QT6=OFF -DMOD_GLAXNIMATE=OFF -DMOD_QT=OFF -DMOD_QT6=OFF -DMOD_MOVIT=OFF -S ./mlt -B ./build
22
+cmake -DCMAKE_BUILD_TYPE=Release -DSWIG_PYTHON=ON -DMOD_GLAXNIMATE_QT6=OFF -DMOD_GLAXNIMATE=OFF -DMOD_QT=OFF -DMOD_QT6=OFF -DMOD_MOVIT=OFF -DMOD_OPENCV=ON -S ./mlt -B ./build
23
 
24
 cmake --build ./build --config Release
25
 ```
26
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/flowblade -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/flowblade Changed
12
 
1
@@ -24,8 +24,8 @@
2
 import sys
3
 
4
 
5
-print ("FLOWBLADE MOVIE EDITOR 2.18.1")
6
-print ("-----------------------------")
7
+print ("FLOWBLADE MOVIE EDITOR 2.20")
8
+print ("---------------------------")
9
 
10
 # Get launch script dir
11
 launch_dir = os.path.dirname(os.path.abspath(sys.argv0))
12
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/installdata/io.github.jliljebl.Flowblade.appdata.xml -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/installdata/io.github.jliljebl.Flowblade.appdata.xml Changed
18
 
1
@@ -21,6 +21,16 @@
2
   </screenshots>
3
   <content_rating type="oars-1.1" />
4
   <releases>
5
+     <release version="2.20" date="2025-3-24">
6
+      <description>
7
+      <p>New features:</p>
8
+        <ul>
9
+          <li>SDL 2 playback</li>
10
+          <li>Sync editing updates</li>
11
+          <li>Sequence Link Container Clip</li>
12
+        </ul>
13
+      </description>
14
+    </release>
15
      <release version="2.18.1" date="2025-2-16">
16
       <description>
17
       <p>New features:</p>
18
_service:obs_scm:flowblade-2.18.1.obscpio/flowblade-trunk/setup.py -> _service:obs_scm:flowblade-2.20.obscpio/flowblade-trunk/setup.py Changed
19
 
1
@@ -42,7 +42,7 @@
2
                           'res/mediaplugins/animations_2/*', 'res/mediaplugins/text_1/*',
3
                           'res/mediaplugins/text_2/*', 'res/mediaplugins/transitions_1/*',
4
                           'res/mediaplugins/transitions_2/*','res/gpu-test/*','res/scripttool/*',
5
-                          'res/usbhid/*', 'res/mediaplugins/text_3/*'
6
+                          'res/usbhid/*','res/mediaplugins/text_3/*'
7
 
8
 locale_files = 
9
 for filepath in glob.glob("Flowblade/locale/*/LC_MESSAGES/*"):
10
@@ -50,7 +50,7 @@
11
     locale_files.append(filepath)
12
 
13
 setup(  name='flowblade',
14
-        version='2.18.1',
15
+        version='2.20',
16
         author='Janne Liljeblad',
17
         author_email='janne.liljeblad at gmail dot com',
18
         description='Non-linear video editor',
19
_service:obs_scm:flowblade.obsinfo Changed
9
 
1
@@ -1,4 +1,4 @@
2
 name: flowblade
3
-version: 2.18.1
4
-mtime: 1739778503
5
-commit: 8bede966fa66c526ec97d35254cca75704799e58
6
+version: 2.20
7
+mtime: 1742892056
8
+commit: cce3d674b796f5cc2ccaf3c40611faf3b6b4d74e
9