1 # gpl: authors Carlos Padial, Turi Scandurra
5 from bpy
.types
import (
9 from bpy
.props
import IntProperty
11 from . import functions
15 ("1", "25%", ""), ("2", "50%", ""),
16 ("3", "75%", ""), ("4", "100%", ""),
22 def setup_proxy(context
, strip
, size
):
23 preferences
= context
.preferences
24 prefs
= preferences
.addons
[__package__
].preferences
26 # set up proxy settings
27 strip
.use_proxy
= True
29 if prefs
.use_bi_custom_directory
:
30 strip
.use_proxy_custom_directory
= True
31 filename
= strip
.filepath
.rpartition("/")[2].rpartition(".")[0]
32 strip
.proxy
.directory
= bpy
.path
.relpath(prefs
.proxy_dir
+ filename
)
34 strip
.use_proxy_custom_directory
= False
36 if strip
.use_proxy_custom_file
is True:
37 strip
.use_proxy_custom_file
= False
39 strip
.proxy
.quality
= prefs
.quality
40 strip
.proxy
.timecode
= prefs
.timecode
43 strip
.use_proxy
= False
44 strip
.proxy
.build_25
= False
45 strip
.proxy
.build_50
= False
46 strip
.proxy
.build_75
= False
47 strip
.proxy
.build_100
= False
50 proxysuffix
= proxy_qualities
[size
- 1][1].split("%")[0]
52 if (proxysuffix
== "25"):
53 strip
.proxy
.build_25
= True
54 if (proxysuffix
== "50"):
55 strip
.proxy
.build_50
= True
56 if (proxysuffix
== "75"):
57 strip
.proxy
.build_75
= True
58 if (proxysuffix
== "100"):
59 strip
.proxy
.build_100
= True
64 def create_proxy(context
, strip
, size
, res
):
65 # calculate proxy resolution
67 newres
= (int(int(res
[0]) / div
), int(int(res
[1]) / div
))
69 preferences
= context
.preferences
70 proxy_dir
= preferences
.addons
[__package__
].preferences
.proxy_dir
71 scripts
= preferences
.addons
[__package__
].preferences
.proxy_scripts
72 ffmpeg_command
= preferences
.addons
[__package__
].preferences
.ffmpeg_command
74 functions
.create_folder(proxy_dir
)
80 if strip
.type == "MOVIE":
81 filename
= bpy
.path
.abspath(strip
.filepath
)
82 proxysuffix
= proxy_qualities
[size
- 1][1].split("%")[0]
83 proxy_dir
= bpy
.path
.abspath(proxy_dir
)
84 newfilename
= os
.path
.join(proxy_dir
, filename
.rpartition("/")[2])
85 fileoutput
= newfilename
.rpartition(".")[0] + "-" + proxysuffix
+ ".avi"
87 # default value for ffmpeg_command = "fmpeg -i {} -vcodec mjpeg -qv 1 -s {}x{} -y {}"
89 command
= ffmpeg_command
.format(filename
, newres
[0], newres
[1], fileoutput
)
93 commands
.append(command
)
95 # check for existing file
96 if not os
.path
.isfile(fileoutput
):
97 subprocess
.call(command
, shell
=True)
99 print("File already exists")
101 # set up proxy settings
102 strip
.use_proxy
= True
104 strip
.use_proxy_custom_file
= True
105 strip
.proxy
.filepath
= bpy
.path
.relpath(fileoutput
)
109 if (proxysuffix
== "25"):
110 strip
.proxy
.build_25
= True
111 if (proxysuffix
== "50"):
112 strip
.proxy
.build_50
= True
113 if (proxysuffix
== "75"):
114 strip
.proxy
.build_75
= True
115 if (proxysuffix
== "100"):
116 strip
.proxy
.build_100
= True
124 def create_proxy_scripts(scripts_dir
, commands
, strip_name
=None):
126 functions
.create_folder(bpy
.path
.abspath(scripts_dir
))
129 filename
= "{}/proxy_script_{}.sh".format(scripts_dir
, strip_name
)
130 text_file
= open(bpy
.path
.abspath(filename
), "w")
137 class CreateProxyOperator(Operator
):
138 bl_idname
= "sequencer.create_proxy_operator"
139 bl_label
= "Create Proxy"
140 bl_description
= ("Use ffmpeg to create a proxy from video\n"
141 "and setup proxies for selected strip")
142 bl_options
= {'REGISTER', 'UNDO'}
150 def poll(self
, context
):
151 strip
= functions
.act_strip(context
)
153 if scn
and scn
.sequence_editor
and scn
.sequence_editor
.active_strip
:
154 return strip
.type in ('MOVIE')
158 def execute(self
, context
):
159 preferences
= context
.preferences
160 proxy_scripts_path
= preferences
.addons
[__package__
].preferences
.proxy_scripts_path
162 for strip
in context
.selected_editable_sequences
:
163 # get resolution from active strip
165 bpy
.ops
.sequencerextra
.read_exif()
171 res
= sce
['metadata'][0]['Composite:ImageSize'].split("x")
173 res
= (sce
.render
.resolution_x
, sce
.render
.resolution_y
)
175 commands
= create_proxy(context
, strip
, self
.size
, res
)
179 context
.scene
.update()
180 newstrip
= context
.scene
.sequence_editor
.active_strip
182 # deselect all other strips
183 for i
in context
.selected_editable_sequences
:
184 if i
.name
!= newstrip
.name
:
188 context
.scene
.update()
190 create_proxy_scripts(proxy_scripts_path
, commands
, strip
.name
)
195 class CreateBIProxyOperator(Operator
):
196 bl_idname
= "sequencer.create_bi_proxy_operator"
197 bl_label
= "Create proxy with Blender Internal"
198 bl_description
= "Use BI system to create a proxy"
199 bl_options
= {'REGISTER', 'UNDO'}
207 def poll(self
, context
):
208 strip
= functions
.act_strip(context
)
210 if scn
and scn
.sequence_editor
and scn
.sequence_editor
.active_strip
:
211 return strip
.type in ('MOVIE')
215 def execute(self
, context
):
217 strips
= functions
.get_selected_strips(context
)
220 # deselect all other strips
223 # select current strip
225 if strip
.type == "MOVIE":
226 setup_proxy(context
, strip
, self
.size
)
227 except Exception as e
:
228 functions
.error_handlers(
230 "sequencer.create_bi_proxy_operator", e
,
231 "Create proxy with blender internal"
235 # select all strips again
239 except ReferenceError:
241 bpy
.ops
.sequencer
.reload()
246 class CreateProxyToolPanel(Panel
):
247 bl_label
= "Proxy Tools"
248 bl_idname
= "OBJECT_PT_ProxyTool"
249 bl_space_type
= 'SEQUENCE_EDITOR'
250 bl_region_type
= 'UI'
253 def poll(self
, context
):
254 if context
.space_data
.view_type
in {'SEQUENCER',
255 'SEQUENCER_PREVIEW'}:
256 strip
= functions
.act_strip(context
)
258 preferences
= context
.preferences
259 prefs
= preferences
.addons
[__package__
].preferences
260 if scn
and scn
.sequence_editor
and scn
.sequence_editor
.active_strip
:
261 if prefs
.use_proxy_tools
:
262 return strip
.type in ('MOVIE')
266 def draw_header(self
, context
):
268 layout
.label(text
="", icon
="AUTO")
270 def draw(self
, context
):
272 preferences
= context
.preferences
273 prefs
= preferences
.addons
[__package__
].preferences
276 layout
.prop(prefs
, "use_internal_proxy", text
="Use BI proxy builder")
278 strip
= functions
.act_strip(context
)
280 if prefs
.use_internal_proxy
:
282 row
= layout
.row(align
=True)
283 row
.prop(prefs
, "use_bi_custom_directory")
285 if prefs
.use_bi_custom_directory
:
286 row
.prop(prefs
, "proxy_dir", text
="")
287 filename
= strip
.filepath
.rpartition("/")[2].rpartition(".")[0]
288 layout
.label(text
="sample dir: //" + bpy
.path
.abspath(prefs
.proxy_dir
+ filename
))
291 col
= layout
.column()
292 col
.label(text
="Build JPEG quality")
293 col
.prop(prefs
, "quality")
295 if strip
.type == 'MOVIE':
296 col
= layout
.column()
297 col
.label(text
="Use timecode index:")
299 col
.prop(prefs
, "timecode")
302 layout
.label(text
="Setup and create BI proxy:")
303 row
= layout
.row(align
=True)
306 proxysuffix
= proxy_qualities
[i
][1]
307 row
.operator("sequencer.create_bi_proxy_operator",
308 text
=proxysuffix
).size
= i
+ 1
311 layout
.operator("sequencer.create_bi_proxy_operator",
312 text
="Clear proxy sizes").size
= 5
316 layout
.prop(prefs
, "proxy_dir", text
="Path for proxies")
319 layout
.label(text
="Create and import proxy from clip:")
320 row
= layout
.row(align
=True)
323 layout
.prop(prefs
, "ffmpeg_command", text
="command")
325 layout
.label(text
="{} = filename, with, height, fileoutput")
326 label
= prefs
.ffmpeg_command
.format("filename", "with", "height", "fileoutput")
330 proxysuffix
= proxy_qualities
[i
][1]
331 row
.operator("sequencer.create_proxy_operator",
332 text
=proxysuffix
).size
= i
+ 1
335 layout
.prop(prefs
, "proxy_scripts")
337 if prefs
.proxy_scripts
:
339 layout
.prop(prefs
, "proxy_scripts_path", text
="Path for scripts")
343 box
.prop(context
.space_data
, "proxy_render_size")
344 box
.operator("sequencer.rebuild_proxy", text
="Rebuild Proxies and TC")