Skip to content

Commit

Permalink
Improve code format and readability (Zulko#1077)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgaitan authored Mar 17, 2020
1 parent 628e79d commit f22e663
Show file tree
Hide file tree
Showing 24 changed files with 381 additions and 468 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@

- New version of imageio with imageio\_ffmpeg for python 3.4+ [\#907](https://github.com/Zulko/moviepy/pull/907) ([Zulko](https://github.com/Zulko))
- fix typo that introduces audio regression [\#894](https://github.com/Zulko/moviepy/pull/894) ([chrox](https://github.com/chrox))
- fixing the git remote syntax in documentions [\#887](https://github.com/Zulko/moviepy/pull/887) ([ishandutta2007](https://github.com/ishandutta2007))
- fixing the git remote syntax in documentations [\#887](https://github.com/Zulko/moviepy/pull/887) ([ishandutta2007](https://github.com/ishandutta2007))
- modified max duration error for better understanding [\#875](https://github.com/Zulko/moviepy/pull/875) ([kapilkd13](https://github.com/kapilkd13))
- Fixed typo in docstring for VideoClip class [\#871](https://github.com/Zulko/moviepy/pull/871) ([Armcollector](https://github.com/Armcollector))
- Fix a small typing error [\#845](https://github.com/Zulko/moviepy/pull/845) ([yuvallanger](https://github.com/yuvallanger))
Expand Down
9 changes: 4 additions & 5 deletions moviepy/Clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,10 @@ def fl(self, fun, apply_to=None, keep_duration=True):
apply_to = [apply_to]

for attr in apply_to:
if hasattr(newclip, attr):
a = getattr(newclip, attr)
if a is not None:
new_a = a.fl(fun, keep_duration=keep_duration)
setattr(newclip, attr, new_a)
a = getattr(newclip, attr, None)
if a is not None:
new_a = a.fl(fun, keep_duration=keep_duration)
setattr(newclip, attr, new_a)

return newclip

Expand Down
8 changes: 2 additions & 6 deletions moviepy/audio/AudioClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,6 @@ def concatenate_audioclips(clips):

result = CompositeAudioClip(newclips).set_duration(tt[-1])

fpss = [c.fps for c in clips if hasattr(c, 'fps') and c.fps is not None]
if len(fpss) == 0:
result.fps = None
else:
result.fps = max(fpss)

fpss = [c.fps for c in clips if getattr(c, 'fps', None)]
result.fps = max(fpss) if fpss else None
return result
14 changes: 6 additions & 8 deletions moviepy/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def apply_to_mask(f, clip, *a, **k):
the clip created with f """

newclip = f(clip, *a, **k)
if hasattr(newclip, 'mask') and (newclip.mask is not None):
if getattr(newclip, 'mask', None):
newclip.mask = f(newclip.mask, *a, **k)
return newclip

Expand All @@ -39,7 +39,7 @@ def apply_to_audio(f, clip, *a, **k):
the clip created with f """

newclip = f(clip, *a, **k)
if hasattr(newclip, 'audio') and (newclip.audio is not None):
if getattr(newclip, 'audio', None):
newclip.audio = f(newclip.audio, *a, **k)
return newclip

Expand Down Expand Up @@ -112,14 +112,12 @@ def use_clip_fps_by_default(f, clip, *a, **k):
def fun(fps):
if fps is not None:
return fps
else:
if hasattr(clip, 'fps') and clip.fps is not None:
return clip.fps
else:
raise AttributeError("No 'fps' (frames per second) attribute specified"
elif getattr(clip, 'fps', None):
return clip.fps
raise AttributeError("No 'fps' (frames per second) attribute specified"
" for function %s and the clip has no 'fps' attribute. Either"
" provide e.g. fps=24 in the arguments of the function, or define"
" the clip's fps with `clip.fps=24`"%f.__name__)
" the clip's fps with `clip.fps=24`" % f.__name__)


if hasattr(f, "func_code"):
Expand Down
75 changes: 43 additions & 32 deletions moviepy/tools.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""
Misc. useful functions that can be used at many places in the program.
"""

import os
import re
import subprocess as sp
import sys
import warnings
Expand All @@ -13,6 +11,7 @@
from .compat import DEVNULL



def sys_write_flush(s):
""" Writes and flushes without delay a text in the console """
# Reason for not using `print` is that in some consoles "print"
Expand Down Expand Up @@ -66,39 +65,41 @@ def is_string(obj):
except NameError:
return isinstance(obj, str)


def cvsecs(time):
""" Will convert any time into seconds.
Here are the accepted formats:
>>> cvsecs(15.4) -> 15.4 # seconds
>>> cvsecs( (1,21.5) ) -> 81.5 # (min,sec)
>>> cvsecs( (1,1,2) ) -> 3662 # (hr, min, sec)
>>> cvsecs('01:01:33.5') -> 3693.5 #(hr,min,sec)
>>> cvsecs('01:01:33.045') -> 3693.045
>>> cvsecs('01:01:33,5') #coma works too
""" Will convert any time into seconds.
If the type of `time` is not valid,
it's returned as is.
Here are the accepted formats::
>>> cvsecs(15.4) # seconds
15.4
>>> cvsecs((1, 21.5)) # (min,sec)
81.5
>>> cvsecs((1, 1, 2)) # (hr, min, sec)
3662
>>> cvsecs('01:01:33.045')
3693.045
>>> cvsecs('01:01:33,5') # coma works too
3693.5
>>> cvsecs('1:33,5') # only minutes and secs
99.5
>>> cvsecs('33.5') # only secs
33.5
"""
factors = (1, 60, 3600)

if is_string(time):
time = [float(f.replace(',', '.')) for f in time.split(':')]

if is_string(time):
if (',' not in time) and ('.' not in time):
time = time + '.0'
expr = r"(\d+):(\d+):(\d+)[,|.](\d+)"
finds = re.findall(expr, time)[0]
nums = list( map(float, finds) )
return ( 3600*int(finds[0])
+ 60*int(finds[1])
+ int(finds[2])
+ nums[3]/(10**len(finds[3])))

elif isinstance(time, tuple):
if len(time)== 3:
hr, mn, sec = time
elif len(time)== 2:
hr, mn, sec = 0, time[0], time[1]
return 3600*hr + 60*mn + sec

else:
if not isinstance(time, (tuple, list)):
return time

return sum(mult * part for mult, part in zip(factors, reversed(time)))


def deprecated_version_of(f, oldname, newname=None):
""" Indicates that a function is deprecated and has a new name.
Expand Down Expand Up @@ -159,8 +160,18 @@ def fdepr(*a, **kw):
for ext in ["jpg", "jpeg", "png", "bmp", "tiff"]:
extensions_dict[ext] = {'type':'image'}


def find_extension(codec):
if codec in extensions_dict:
# codec is already the extension
return codec

for ext,infos in extensions_dict.items():
if ('codec' in infos) and codec in infos['codec']:
if codec in infos.get('codec', []):
return ext
raise ValueError
raise ValueError(
"The audio_codec you chose is unknown by MoviePy. "
"You should report this. In the meantime, you can "
"specify a temp_audiofile with the right extension "
"in write_videofile."
)
13 changes: 7 additions & 6 deletions moviepy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
from moviepy.video.VideoClip import ImageClip


CLIP_TYPES = {
'audio': AudioFileClip,
'video': VideoFileClip,
'image': ImageClip,
}

def close_all_clips(objects='globals', types=('audio', 'video', 'image')):
if objects == 'globals':
objects = globals()
if hasattr(objects, 'values'):
objects = objects.values()
types_tuple = tuple([
{'audio': AudioFileClip,
'video': VideoFileClip,
'image': ImageClip}[t]
for t in types
])
types_tuple = tuple(CLIP_TYPES[key] for key in types)
for obj in objects:
if isinstance(obj, types_tuple):
obj.close()
92 changes: 30 additions & 62 deletions moviepy/video/VideoClip.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def __init__(self, make_frame=None, ismask=False, duration=None,
self.audio = None
self.pos = lambda t: (0, 0)
self.relative_pos = False
if make_frame is not None:
if make_frame:
self.make_frame = make_frame
self.size = self.get_frame(0).shape[:2][::-1]
self.ismask = ismask
Expand Down Expand Up @@ -120,7 +120,6 @@ def save_frame(self, filename, t=0, withmask=True):
"""

im = self.get_frame(t)

if withmask and self.mask is not None:
mask = 255 * self.mask.get_frame(t)
im = np.dstack([im, mask]).astype('uint8')
Expand Down Expand Up @@ -280,30 +279,12 @@ def write_videofile(self, filename, fps=None, codec=None,
make_audio = ((audiofile is None) and (audio == True) and
(self.audio is not None))

if make_audio:
if make_audio and temp_audiofile:
# The audio will be the clip's audio
if temp_audiofile is not None:
audiofile = temp_audiofile

else:

# make a name for the temporary audio file

if audio_codec in extensions_dict:
audio_ext = audio_codec
else:
try:
audio_ext = find_extension(audio_codec)
except ValueError:

raise ValueError(
"The audio_codec you chose is unknown by MoviePy. "
"You should report this. In the meantime, you can "
"specify a temp_audiofile with the right extension "
"in write_videofile.")

audiofile = (name + Clip._TEMP_FILES_PREFIX +
"wvf_snd.%s" % audio_ext)
audiofile = temp_audiofile
elif make_audio:
audio_ext = find_extension(audio_codec)
audiofile = (name + Clip._TEMP_FILES_PREFIX + "wvf_snd.%s" % audio_ext)

# enough cpu for multiprocessing ? USELESS RIGHT NOW, WILL COME AGAIN
# enough_cpu = (multiprocessing.cpu_count() > 1)
Expand Down Expand Up @@ -380,7 +361,6 @@ def write_images_sequence(self, nameformat, fps=None, verbose=True,
tt = np.arange(0, self.duration, 1.0 / fps)

filenames = []
total = int(self.duration / fps) + 1
for i, t in logger.iter_bar(t=list(enumerate(tt))):
name = nameformat % i
filenames.append(name)
Expand Down Expand Up @@ -455,26 +435,18 @@ def write_gif(self, filename, fps=None, program='imageio',
elif tempfiles:
# convert imageio opt variable to something that can be used with
# ImageMagick
opt1 = opt
if opt1 == 'nq':
opt1 ='optimizeplus'
else:
opt1 ='OptimizeTransparency'
opt = 'optimizeplus' if opt == 'nq' else 'OptimizeTransparency'
write_gif_with_tempfiles(self, filename, fps=fps,
program=program, opt=opt1, fuzz=fuzz,
program=program, opt=opt, fuzz=fuzz,
verbose=verbose, loop=loop,
dispose=dispose, colors=colors,
logger=logger)
else:
# convert imageio opt variable to something that can be used with
# ImageMagick
opt1 = opt
if opt1 == 'nq':
opt1 ='optimizeplus'
else:
opt1 ='OptimizeTransparency'
opt = 'optimizeplus' if opt == 'nq' else 'OptimizeTransparency'
write_gif(self, filename, fps=fps, program=program,
opt=opt1, fuzz=fuzz, verbose=verbose, loop=loop,
opt=opt, fuzz=fuzz, verbose=verbose, loop=loop,
dispose=dispose, colors=colors,
logger=logger)

Expand All @@ -496,11 +468,11 @@ def subfx(self, fx, ta=0, tb=None, **kwargs):
>>> newclip = clip.subapply(lambda c:c.speedx(0.5) , 3,6)
"""
left = None if (ta == 0) else self.subclip(0, ta)
left = self.subclip(0, ta) if ta else None
center = self.subclip(ta, tb).fx(fx, **kwargs)
right = None if (tb is None) else self.subclip(t_start=tb)
right = self.subclip(t_start=tb) if tb else None

clips = [c for c in [left, center, right] if c is not None]
clips = [c for c in (left, center, right) if c]

# beurk, have to find other solution
from moviepy.video.compositing.concatenate import concatenate_videoclips
Expand All @@ -514,8 +486,7 @@ def fl_image(self, image_func, apply_to=None):
Modifies the images of a clip by replacing the frame
`get_frame(t)` by another frame, `image_func(get_frame(t))`
"""
if apply_to is None:
apply_to = []
apply_to = apply_to or []
return self.fl(lambda gf, t: image_func(gf(t)), apply_to)

# --------------------------------------------------------------
Expand Down Expand Up @@ -546,23 +517,22 @@ def blit_on(self, picture, t):
"""
hf, wf = framesize = picture.shape[:2]

if self.ismask and picture.max() != 0:
if self.ismask and picture.max():
return np.minimum(1, picture + self.blit_on(np.zeros(framesize), t))

ct = t - self.start # clip time

# GET IMAGE AND MASK IF ANY

img = self.get_frame(ct)
mask = (None if (self.mask is None) else
self.mask.get_frame(ct))
if mask is not None:
if (img.shape[0] != mask.shape[0]) or (img.shape[1] != mask.shape[1]):
img = self.fill_array(img, mask.shape)
mask = self.mask.get_frame(ct) if self.mask else None

if mask is not None and ((img.shape[0] != mask.shape[0]) or (img.shape[1] != mask.shape[1])):
img = self.fill_array(img, mask.shape)

hi, wi = img.shape[:2]

# SET POSITION

pos = self.pos(ct)

# preprocess short writings of the position
Expand Down Expand Up @@ -688,7 +658,7 @@ def set_mask(self, mask):
Returns a copy of the VideoClip with the mask attribute set to
``mask``, which must be a greyscale (values in 0-1) VideoClip"""
assert ( (mask is None) or mask.ismask )
assert mask is None or mask.ismask
self.mask = mask

@add_mask_if_none
Expand Down Expand Up @@ -969,11 +939,10 @@ def fl_image(self, image_func, apply_to=None):
self.img = arr

for attr in apply_to:
if hasattr(self, attr):
a = getattr(self, attr)
if a is not None:
new_a = a.fl_image(image_func)
setattr(self, attr, new_a)
a = getattr(self, attr, None)
if a is not None:
new_a = a.fl_image(image_func)
setattr(self, attr, new_a)

@outplace
def fl_time(self, time_func, apply_to=None,
Expand All @@ -987,13 +956,12 @@ def fl_time(self, time_func, apply_to=None,
masks or their audios). The result is still an ImageClip.
"""
if apply_to is None:
apply_to = ['mask', 'audio']
apply_to = ['mask', 'audio']
for attr in apply_to:
if hasattr(self, attr):
a = getattr(self, attr)
if a is not None:
new_a = a.fl_time(time_func)
setattr(self, attr, new_a)
a = getattr(self, attr, None)
if a is not None:
new_a = a.fl_time(time_func)
setattr(self, attr, new_a)


# ##
Expand Down
Loading

0 comments on commit f22e663

Please sign in to comment.