From b93b3217f3acba7e5e4e37f295e4cff2ad2a821d Mon Sep 17 00:00:00 2001 From: Zulko Date: Fri, 11 Oct 2013 23:21:23 +0200 Subject: [PATCH] Various small bug fixes --- moviepy/audio/AudioClip.py | 13 ++++++++----- moviepy/audio/fx/audio_fadein.py | 12 +++++++++++- moviepy/audio/fx/audio_fadeout.py | 3 ++- moviepy/audio/io/preview.py | 12 +++++++----- moviepy/video/VideoClip.py | 15 +++------------ moviepy/video/compositing/concatenate.py | 2 +- moviepy/video/io/ffmpeg_reader.py | 6 ++++-- moviepy/video/io/ffmpeg_tools.py | 3 ++- moviepy/video/io/ffmpeg_writer.py | 4 +++- moviepy/video/io/preview.py | 6 +++--- moviepy/video/tools/drawing.py | 5 ++--- setup.py | 2 +- 12 files changed, 47 insertions(+), 36 deletions(-) diff --git a/moviepy/audio/AudioClip.py b/moviepy/audio/AudioClip.py index e71d1d857..f2f8b1215 100644 --- a/moviepy/audio/AudioClip.py +++ b/moviepy/audio/AudioClip.py @@ -76,8 +76,11 @@ def to_audiofile(self, filename, fps=44100, nbytes = 2, @property def nchannels(self): return len(list(self.get_frame(0))) - -AudioClip.to_audiofile = ffmpeg_audiowrite + + def to_audiofile(self,filename, fps=44100, nbytes=2, buffersize=5000, + codec='libvorbis', bitrate=None, verbose=True): + return ffmpeg_audiowrite(self,filename, fps, nbytes, buffersize, + codec, bitrate, verbose) try: # Add methods preview (only if pygame installed) @@ -110,11 +113,11 @@ def gf(t): is a list of the form sin(t) """ if isinstance(t, np.ndarray): - array_inds = int(self.fps*t) + array_inds = (self.fps*t).astype(int) in_array = (array_inds>0) & (array_inds < len(self.array)) result = np.zeros((len(t),2)) - result[in_array] = self.array(array_inds[in_array]) - return results + result[in_array] = self.array[array_inds[in_array]] + return result else: i = int(self.fps * t) if i < 0 or i >= len(self.array): diff --git a/moviepy/audio/fx/audio_fadein.py b/moviepy/audio/fx/audio_fadein.py index 0505de65b..aef930d95 100644 --- a/moviepy/audio/fx/audio_fadein.py +++ b/moviepy/audio/fx/audio_fadein.py @@ -1,8 +1,18 @@ from moviepy.decorators import audio_video_fx +import numpy as np @audio_video_fx def audio_fadein(clip, duration): """ Return an audio (or video) clip that is first mute, then the sound arrives progressively over ``duration`` seconds. """ - fading = lambda gf, t: min(1.0 * t / duration, 1) * gf(t) + def fading(gf,t): + gft = gf(t) + + if np.isscalar(t): + factor = min(1.0 * t / duration, 1) + factor = np.array([factor,factor]) + else: + factor = np.minimum(1.0 * t / duration, 1).T + factor = np.vstack([factor.T,factor.T]).T + return factor * gft return clip.fl(fading, keep_duration = True) diff --git a/moviepy/audio/fx/audio_fadeout.py b/moviepy/audio/fx/audio_fadeout.py index 1d8a44b62..524d70222 100644 --- a/moviepy/audio/fx/audio_fadeout.py +++ b/moviepy/audio/fx/audio_fadeout.py @@ -1,10 +1,11 @@ from moviepy.decorators import audio_video_fx, requires_duration +import numpy as np @audio_video_fx @requires_duration def audio_fadeout(self, duration): """ Return a sound clip where the sound fades out progressively over ``duration`` seconds at the end of the clip. """ - fading = lambda gf, t: max( + fading = lambda gf, t: np.maximum( 1.0 * (self.duration - t) / duration, 0) * gf(t) return self.fl(fading, keep_duration = True) diff --git a/moviepy/audio/io/preview.py b/moviepy/audio/io/preview.py index a6f8f7175..1547c5c8b 100644 --- a/moviepy/audio/io/preview.py +++ b/moviepy/audio/io/preview.py @@ -47,7 +47,8 @@ def preview(clip, fps=22050, buffersize=50000, nbytes= 2, sndarray = clip.to_soundarray(tt,nbytes) chunk = pg.sndarray.make_sound(sndarray) Delta = tt[1]-tt[0] - if audioFlag and videoFlag: + + if (audioFlag !=None) and (videoFlag!= None): audioFlag.set() videoFlag.wait() @@ -58,8 +59,9 @@ def preview(clip, fps=22050, buffersize=50000, nbytes= 2, chunk = pg.sndarray.make_sound(sndarray) while channel.get_queue(): time.sleep(0.003) - if not videoFlag.is_set(): - channel.stop() - del channel - return + if (videoFlag!= None): + if not videoFlag.is_set(): + channel.stop() + del channel + return channel.queue(chunk) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index 0822e6167..d32195d3d 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -251,17 +251,16 @@ def verbose_print(s): # Don't parallelize if make_audio: self.audio.to_audiofile(temp_wav,audio_fps, audio_nbytes, - audio_bufsize, verbose) + audio_bufsize, audio_codec, audio_bitrate, verbose) ffmpeg_writer.ffmpeg_write(self, videofile, fps, codec, bitrate=bitrate, verbose=verbose) # Merge with audio if any and trash temporary files. - if merge_audio: verbose_print("\nNow merging video and audio...\n") ffmpeg_tools.merge_video_audio(videofile,temp_wav,filename, - ffmpeg_output=False) + ffmpeg_output=True) if remove_temp: os.remove(videofile) if not isinstance(audio,str): @@ -517,7 +516,7 @@ def without_audio(self): """--------------------------------------------------------------------- - ImageClip (bas class for all 'static clips') and its subclasses + ImageClip (base class for all 'static clips') and its subclasses ColorClip and TextClip. I would have liked to put these in a separate file but Python is bad at cyclic imports. @@ -525,14 +524,6 @@ def without_audio(self): ---------------------------------------------------------------------""" - - -""" -Classes for advantageous handling of static clips. -ImageClip, ColorClip, TextClip -""" - - class ImageClip(VideoClip): diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index 9e13bdb4a..33e9cb018 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -61,7 +61,7 @@ def gf(t): elif method == 'compose': tt = np.maximum(0, tt - crossover*np.arange(len(tt))) - result = CompositeVideoClip( [c.set_start(t).set_pos('center') + result = concatenate( [c.set_start(t).set_pos('center') for (c, t) in zip(clipslist, tt)], size = (w, h), bg_color=bg_color, ismask=ismask, transparent=transparent) diff --git a/moviepy/video/io/ffmpeg_reader.py b/moviepy/video/io/ffmpeg_reader.py index 919ac8507..2fb6cc222 100644 --- a/moviepy/video/io/ffmpeg_reader.py +++ b/moviepy/video/io/ffmpeg_reader.py @@ -2,9 +2,10 @@ import re import numpy as np -from moviepy.conf import FFMPEG_BINARY +from moviepy.conf import FFMPEG_BINARY # ffmpeg, ffmpeg.exe, etc... from moviepy.tools import cvsecs - + + class FFMPEG_VideoReader: def __init__(self, filename, print_infos=False, pix_fmt="rgb24"): @@ -144,6 +145,7 @@ def get_frame(self,t): result = self.read_frame() self.pos = pos return result + def read_image(filename,with_mask=True): pix_fmt='rgba' if with_mask else "rgb24" diff --git a/moviepy/video/io/ffmpeg_tools.py b/moviepy/video/io/ffmpeg_tools.py index 17de8cfba..3c5479cef 100644 --- a/moviepy/video/io/ffmpeg_tools.py +++ b/moviepy/video/io/ffmpeg_tools.py @@ -19,7 +19,8 @@ def subprocess_call(f, *a, **k): proc = sp.Popen(cmd, stdout=sp.PIPE, stdin = sp.PIPE, stderr = sp.PIPE) proc.wait() if proc.returncode: - sys.stdout.write( "WARNING: this command failed.") + sys.stdout.write( "\nWARNING: this command returned an error:") + sys.stdout.write(proc.stderr.read()) else: sys.stdout.write( "\n... ffmpeg command successful.\n") sys.stdout.flush() diff --git a/moviepy/video/io/ffmpeg_writer.py b/moviepy/video/io/ffmpeg_writer.py index 548c9a8af..2466b40df 100644 --- a/moviepy/video/io/ffmpeg_writer.py +++ b/moviepy/video/io/ffmpeg_writer.py @@ -60,6 +60,7 @@ def write_frame(self,img_array): def close(self): self.proc.stdin.close() + self.proc.wait() del self.proc def ffmpeg_write(clip, filename, fps, codec="libx264", bitrate=None, @@ -76,7 +77,7 @@ def verbose_print(s): writer = FFMPEG_VideoWriter(filename, clip.size, fps, codec = codec, bitrate=bitrate) i=0 - nframes = clip.duration*fps + nframes = int(clip.duration*fps) while (i < nframes): frame = clip.get_frame(1.0*i/fps) @@ -88,6 +89,7 @@ def verbose_print(s): if ((i+1) % (nframes/10)) == 0: verbose_print("=") i += 1 + writer.close() verbose_print("video done !") diff --git a/moviepy/video/io/preview.py b/moviepy/video/io/preview.py index 337d4a72a..1610f8d3d 100644 --- a/moviepy/video/io/preview.py +++ b/moviepy/video/io/preview.py @@ -31,14 +31,14 @@ def show(clip, t=0, with_mask=True): if clip.ismask: clip = clip.to_RGB() if with_mask and (clip.mask != None): - from moviepy.video.compositing import CompositeVideoClip - clip = CompositeVideoClip([clip]) + import moviepy.video.compositing.CompositeVideoClip as cvc + clip = cvc.CompositeVideoClip([clip]) imdisplay(clip.get_frame(t)) @requires_duration def preview(clip, fps=15, audio=True, audio_fps=22050, - audio_buffersize=10000, audio_nbytes=2): + audio_buffersize=3000, audio_nbytes=2): """ Displays the clip in a window, at the given frames per second (of movie) rate. It will avoid that the clip be played faster diff --git a/moviepy/video/tools/drawing.py b/moviepy/video/tools/drawing.py index 17c8e2e3a..09cddfa3d 100644 --- a/moviepy/video/tools/drawing.py +++ b/moviepy/video/tools/drawing.py @@ -196,11 +196,10 @@ def color_split(size,x=None,y=None,p1=None,p2=None,vector=None, shape = (h, w) if np.isscalar(col1) else (h, w, len(col1)) arr = np.zeros(shape) print shape - if x != None: + if x: arr[:,:x] = col1 arr[:,x:] = col2 - - elif y != None: + elif y: arr[:y] = col1 arr[y:] = col2 diff --git a/setup.py b/setup.py index 07dac0f7a..94e126ebc 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from setuptools import setup, find_packages setup(name='moviepy', - version='0.2.1.6.1', + version='0.2.1.6.2', author='Zulko 2013', description='Module for script-based video editing', long_description=open('README.rst').read(),