11import os
22import math
3+ from fractions import Fraction
34import torch .multiprocessing as multiprocessing
45import subprocess as sp
56import time
1415multiprocessing .set_start_method ('spawn' , force = True )
1516
1617
18+ def _parse_frame_rate (rate_str ):
19+ try :
20+ return float (Fraction (rate_str ))
21+ except Exception :
22+ return float (rate_str )
23+
24+
25+ def _alpha_encoding_args (output , alpha_codec , alpha_pix_fmt ):
26+ ext = Path (output ).suffix .lower ()
27+ if alpha_codec in (None , "auto" ):
28+ if ext == ".webm" :
29+ alpha_codec = "libvpx-vp9"
30+ else :
31+ alpha_codec = "qtrle"
32+
33+ if alpha_codec == "prores_ks" :
34+ args = ["-c:v" , "prores_ks" , "-profile:v" , "4" ]
35+ pix_fmt = alpha_pix_fmt or "yuva444p10le"
36+ args += ["-pix_fmt" , pix_fmt ]
37+ return args
38+
39+ if alpha_codec == "libvpx-vp9" :
40+ args = ["-c:v" , "libvpx-vp9" , "-crf" , "30" , "-b:v" , "0" ]
41+ pix_fmt = alpha_pix_fmt or "yuva420p"
42+ args += ["-pix_fmt" , pix_fmt ]
43+ return args
44+
45+ if alpha_codec == "qtrle" :
46+ pix_fmt = alpha_pix_fmt or "argb"
47+ return ["-c:v" , "qtrle" , "-pix_fmt" , pix_fmt ]
48+
49+ args = ["-c:v" , alpha_codec ]
50+ if alpha_pix_fmt :
51+ args += ["-pix_fmt" , alpha_pix_fmt ]
52+ return args
53+
54+
1755def worker (worker_nodes ,
1856 worker_index ,
1957 result_dict ,
@@ -104,9 +142,13 @@ def matte_key(output, file_path,
104142
105143 if framerate == - 1 :
106144 print (F"FRAME RATE DETECTED: { frame_rate_str } (if this looks wrong, override the frame rate)" )
107- framerate = math .ceil (eval (frame_rate_str ))
145+ framerate_str = frame_rate_str
146+ framerate_value = _parse_frame_rate (frame_rate_str )
147+ else :
148+ framerate_str = str (framerate )
149+ framerate_value = float (framerate )
108150
109- print (F"FRAME RATE: { framerate } TOTAL FRAMES: { total_frames } " )
151+ print (F"FRAME RATE: { framerate_value } TOTAL FRAMES: { total_frames } " )
110152
111153 p = multiprocessing .Process (target = capture_frames ,
112154 args = (file_path , frames_dict , gpu_batchsize * prefetched_batches , total_frames ))
@@ -163,7 +205,7 @@ def matte_key(output, file_path,
163205 '-vcodec' , 'rawvideo' ,
164206 '-s' , F"{ frame .shape [1 ]} x320" ,
165207 '-pix_fmt' , 'gray' ,
166- '-r' , F" { framerate } " ,
208+ '-r' , framerate_str ,
167209 '-i' , '-' ,
168210 '-an' ,
169211 '-vcodec' , 'mpeg4' ,
@@ -260,7 +302,9 @@ def transparentvideo(output, file_path,
260302 model_name ,
261303 frame_limit = - 1 ,
262304 prefetched_batches = 4 ,
263- framerate = - 1 ):
305+ framerate = - 1 ,
306+ alpha_codec = "auto" ,
307+ alpha_pix_fmt = None ):
264308 temp_dir = tempfile .TemporaryDirectory ()
265309 tmpdirname = Path (temp_dir .name )
266310 temp_file = os .path .abspath (os .path .join (tmpdirname , "matte.mp4" ))
@@ -272,10 +316,13 @@ def transparentvideo(output, file_path,
272316 prefetched_batches ,
273317 framerate )
274318 print ("Starting alphamerge" )
319+ encoding_args = _alpha_encoding_args (output , alpha_codec , alpha_pix_fmt )
275320 cmd = [
276321 'ffmpeg' , '-y' , '-i' , file_path , '-i' , temp_file , '-filter_complex' ,
277- '[1][0]scale2ref[mask][main];[main][mask]alphamerge' , '-c:v' , 'qtrle' , '-shortest' , output
322+ '[1][0]scale2ref[mask][main];[main][mask]alphamerge[v]' ,
323+ '-map' , '[v]' , '-map' , '0:a?' , '-shortest'
278324 ]
325+ cmd += encoding_args + [output ]
279326
280327 sp .run (cmd )
281328 print ("Process finished" )
@@ -292,7 +339,9 @@ def transparentvideoovervideo(output, overlay, file_path,
292339 model_name ,
293340 frame_limit = - 1 ,
294341 prefetched_batches = 4 ,
295- framerate = - 1 ):
342+ framerate = - 1 ,
343+ alpha_codec = "auto" ,
344+ alpha_pix_fmt = None ):
296345 temp_dir = tempfile .TemporaryDirectory ()
297346 tmpdirname = Path (temp_dir .name )
298347 temp_file = os .path .abspath (os .path .join (tmpdirname , "matte.mp4" ))
@@ -304,10 +353,13 @@ def transparentvideoovervideo(output, overlay, file_path,
304353 prefetched_batches ,
305354 framerate )
306355 print ("Starting alphamerge" )
356+ encoding_args = _alpha_encoding_args (output , alpha_codec , alpha_pix_fmt )
307357 cmd = [
308358 'ffmpeg' , '-y' , '-i' , file_path , '-i' , temp_file , '-i' , overlay , '-filter_complex' ,
309- '[1][0]scale2ref[mask][main];[main][mask]alphamerge[vid];[vid][2:v]scale2ref[fg][bg];[bg][fg]overlay[out]' , '-map' , '[out]' , '-shortest' , output
359+ '[1][0]scale2ref[mask][main];[main][mask]alphamerge[vid];[vid][2:v]scale2ref[fg][bg];[bg][fg]overlay[out]' ,
360+ '-map' , '[out]' , '-map' , '2:a?' , '-shortest'
310361 ]
362+ cmd += encoding_args + [output ]
311363 sp .run (cmd )
312364 print ("Process finished" )
313365 try :
@@ -323,7 +375,9 @@ def transparentvideooverimage(output, overlay, file_path,
323375 model_name ,
324376 frame_limit = - 1 ,
325377 prefetched_batches = 4 ,
326- framerate = - 1 ):
378+ framerate = - 1 ,
379+ alpha_codec = "auto" ,
380+ alpha_pix_fmt = None ):
327381 temp_dir = tempfile .TemporaryDirectory ()
328382 tmpdirname = Path (temp_dir .name )
329383 temp_file = os .path .abspath (os .path .join (tmpdirname , "matte.mp4" ))
@@ -342,11 +396,13 @@ def transparentvideooverimage(output, overlay, file_path,
342396 ]
343397 sp .run (cmd )
344398 print ("Starting alphamerge" )
399+ encoding_args = _alpha_encoding_args (output , alpha_codec , alpha_pix_fmt )
345400 cmd = [
346401 'ffmpeg' , '-y' , '-i' , temp_image , '-i' , file_path , '-i' , temp_file , '-filter_complex' ,
347- '[0:v] scale2ref=oh*mdar:ih[bg];[1 :v]scale2ref=oh*mdar:ih [fg];[bg][fg]overlay=(W-w)/2:(H-h)/2:shortest=1[out]' ,
348- '-map' , '[out]' , '-shortest ' , output
402+ '[2][1] scale2ref[mask][main];[main][mask]alphamerge[fg];[0 :v]scale2ref[bg] [fg];[bg][fg]overlay=(W-w)/2:(H-h)/2:shortest=1[out]' ,
403+ '-map' , '[out]' , '-map ' , '1:a?' , '-shortest'
349404 ]
405+ cmd += encoding_args + [output ]
350406 sp .run (cmd )
351407 print ("Process finished" )
352408 try :
0 commit comments