From 4e60a710110caca3494dd1e695c68af6e5e4addb Mon Sep 17 00:00:00 2001 From: Timothy Emerick Date: Mon, 24 Aug 2015 16:00:29 -0400 Subject: [PATCH 01/55] Fixed copy-paste typo Changed documentation for the color parameter to distinguish from bg_color --- moviepy/video/VideoClip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index 7467a826b..f7dab4f27 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -1067,7 +1067,7 @@ class TextClip(ImageClip): for a list of acceptable names. color - Color of the background. See ``TextClip.list('color')`` for a + Color of the text. See ``TextClip.list('color')`` for a list of acceptable names. font From f0372ade94f001a4c76a44e99f08888f14412991 Mon Sep 17 00:00:00 2001 From: LunarLanding Date: Mon, 21 Sep 2015 00:45:13 +0100 Subject: [PATCH 02/55] Fixed missing list (using python 3) --- moviepy/video/VideoClip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index bcc6bb2bb..1368b9d5c 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -553,7 +553,7 @@ def blit_on(self, picture, t): # is the position relative (given in % of the clip's size) ? if self.relative_pos: - for i, dim in enumerate(wf, hf): + for i, dim in enumerate([wf, hf]): if not isinstance(pos[i], str): pos[i] = dim * pos[i] From efaba09667de8f1b62d6764e151dcaa011566c38 Mon Sep 17 00:00:00 2001 From: Bernhard Wagner Date: Wed, 7 Oct 2015 18:56:09 +0200 Subject: [PATCH 03/55] fixed module hierarchy for Trajectory --- moviepy/video/tools/tracking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/tools/tracking.py b/moviepy/video/tools/tracking.py index 21e62e485..e6164dfad 100644 --- a/moviepy/video/tools/tracking.py +++ b/moviepy/video/tools/tracking.py @@ -70,7 +70,7 @@ def manual_tracking(clip, t1=None, t2=None, fps=None, nobjects = 1, nobjects=3, savefile="track.txt") >>> # ... >>> # LATER, IN ANOTHER SCRIPT, RECOVER THESE TRAJECTORIES - >>> from moviepy.tools.tracking import Trajectory + >>> from moviepy.video.tools.tracking import Trajectory >>> traj1, traj2, traj3 = Trajectory.load_list('track.txt') >>> # If ever you only have one object being tracked, recover it with >>> traj, = Trajectory.load_list('track.txt') From 2153c201cee05546447fe2fee69977e6c10f6e1a Mon Sep 17 00:00:00 2001 From: Bernhard Wagner Date: Wed, 7 Oct 2015 21:39:53 +0200 Subject: [PATCH 04/55] fixed addy --- moviepy/video/tools/interpolators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/tools/interpolators.py b/moviepy/video/tools/interpolators.py index f5cd030eb..f6f5cc7dc 100644 --- a/moviepy/video/tools/interpolators.py +++ b/moviepy/video/tools/interpolators.py @@ -41,7 +41,7 @@ def addx(self, x): def addy(self, y): - return Trajectory(self.tt, self.xx+y, self.yy) + return Trajectory(self.tt, self.xx, self.yy+y) def update_interpolators(self): self.xi = Interpolator(self.tt, self.xx) From 3ae11f5be276ec5a18bbbb1e9e8152a16ea85be6 Mon Sep 17 00:00:00 2001 From: Andres Vargas Date: Wed, 23 Dec 2015 16:11:24 -0600 Subject: [PATCH 05/55] small recipe --- docs/examples/quick_recipes.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/examples/quick_recipes.rst b/docs/examples/quick_recipes.rst index ec92577da..736d29ce9 100644 --- a/docs/examples/quick_recipes.rst +++ b/docs/examples/quick_recipes.rst @@ -63,3 +63,12 @@ Getting the average frame of a video average_image = ImageClip(total_image/ nframes) average_image.save_frame("average_test.png") +Mirroring a video +"""""""""""""""""" + :: + import sys + from moviepy.editor import * + + clip = VideoFileClip(sys.argv[1]) + clip = clip.fx(vfx.mirror_x) + clip.write_videofile(sys.argv[2] From 8d0cc388311996bb0bdc2dab8dbac6eb923f0c5f Mon Sep 17 00:00:00 2001 From: Chris Blumentritt Date: Mon, 28 Dec 2015 13:24:33 -0600 Subject: [PATCH 06/55] on_color function docstring has wrong parameter The docstring for the on_color method has a parameter of bg_color but the function uses color as the parameter. --- moviepy/video/VideoClip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index bcc6bb2bb..06f3047fa 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -604,7 +604,7 @@ def on_color(self, size=None, color=(0, 0, 0), pos=None, Size (width, height) in pixels of the final clip. By default it will be the size of the current clip. - bg_color + color Background color of the final clip ([R,G,B]). pos From f0dc512ab6c76f22ba76ecc11f3229871cde5e12 Mon Sep 17 00:00:00 2001 From: Timothy Cyrus Date: Tue, 26 Jan 2016 16:32:36 -0500 Subject: [PATCH 07/55] Update README.rst Changed Code Block to use Python Syntax Highlighting --- README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index c95413664..0fc62ff79 100644 --- a/README.rst +++ b/README.rst @@ -12,7 +12,9 @@ MoviePy can read and write all the most common audio and video formats, includin Example -------- -In this example we open a video file, select the subclip between t=50s and t=60s, add a title at the center of the screen, and write the result to a new file: :: +In this example we open a video file, select the subclip between t=50s and t=60s, add a title at the center of the screen, and write the result to a new file: + +.. code:: python from moviepy.editor import * From 8986d2fcef988f7c18b39bded136d31a98b1104b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Gait=C3=A1n?= Date: Thu, 16 Jun 2016 12:49:18 -0300 Subject: [PATCH 08/55] fix deprecation message currently, the docstring is nonsense. ``` The function ``concatenate_videoclips`` is deprecated and is kept temporarily for backwards compatibility. Please use the new name, ``concatenate_videoclips``, instead. ``` --- moviepy/video/compositing/concatenate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index 358a93149..7c0831d38 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -115,4 +115,4 @@ def make_frame(t): return result -concatenate = deprecated_version_of(concatenate_videoclips, "concatenate_videoclips") +concatenate = deprecated_version_of(concatenate_videoclips, oldname="concatenate") From 85c631dcb926ec16312deda995c5a6a298cf8a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gross=C3=A9?= Date: Mon, 10 Oct 2016 15:01:00 +0200 Subject: [PATCH 09/55] ImageSequenceClip: Check for fps and durations rather than fps and duration --- moviepy/video/io/ImageSequenceClip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moviepy/video/io/ImageSequenceClip.py b/moviepy/video/io/ImageSequenceClip.py index a07bbd404..7aa50bd09 100644 --- a/moviepy/video/io/ImageSequenceClip.py +++ b/moviepy/video/io/ImageSequenceClip.py @@ -50,8 +50,8 @@ def __init__(self, sequence, fps=None, durations=None, with_mask=True, ismask=False, load_images=False): # CODE WRITTEN AS IT CAME, MAY BE IMPROVED IN THE FUTURE - - if (fps is None) and (duration is None): + + if (fps is None) and (durations is None): raise ValueError("Please provide either 'fps' or 'durations'.") VideoClip.__init__(self, ismask=ismask) From 33e29756a68ee3a74512c0f40016b09198907033 Mon Sep 17 00:00:00 2001 From: Andrew Wagner Date: Mon, 17 Oct 2016 15:57:31 +0200 Subject: [PATCH 10/55] Add a test case. --- tests/tests.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/tests.py b/tests/tests.py index 541d08faa..452969afa 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,12 +1,15 @@ """ -Tests meant to be run with pytest +To run the tests: + py.test tests.py """ -import pytest - from moviepy.editor import * - -@pytest.fixture -def example_video1(): - +#@pytest.fixture +def test_if_TextClip_crashes(): + overlay = TextClip(txt='foo', + color='white', + size=(640, 480), + method='caption', + align='center', + fontsize=25) From 870a5f421624fc1ce40583a9ee1ccd53e84bcafe Mon Sep 17 00:00:00 2001 From: Andrew Wagner Date: Mon, 17 Oct 2016 16:04:49 +0200 Subject: [PATCH 11/55] Add another test --- tests/tests.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/tests.py b/tests/tests.py index 452969afa..3cd55af83 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -6,10 +6,13 @@ from moviepy.editor import * #@pytest.fixture -def test_if_TextClip_crashes(): +def test_if_TextClip_crashes_in_caption_mode(): overlay = TextClip(txt='foo', color='white', size=(640, 480), method='caption', align='center', fontsize=25) + +def test_if_TextClip_crashes_in_label_mode(): + overlay = TextClip(txt='foo', method='label') From 814b77628a2fe73aa681c92273af40641911d27f Mon Sep 17 00:00:00 2001 From: tyarkoni Date: Sun, 15 Jan 2017 22:42:20 -0600 Subject: [PATCH 12/55] ensures int arguments to np.reshape; closes #383 --- moviepy/audio/io/readers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/audio/io/readers.py b/moviepy/audio/io/readers.py index 86084c96e..378c3c891 100644 --- a/moviepy/audio/io/readers.py +++ b/moviepy/audio/io/readers.py @@ -119,7 +119,7 @@ def read_chunk(self,chunksize): dt = {1: 'int8',2:'int16',4:'int32'}[self.nbytes] result = np.fromstring(s, dtype=dt) result = (1.0*result / 2**(8*self.nbytes-1)).\ - reshape((len(result)/self.nchannels, + reshape((int(len(result)/self.nchannels), self.nchannels)) #self.proc.stdout.flush() self.pos = self.pos+chunksize From 04b6bc65268e5066c2e9605008270ca43652b46b Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Fri, 10 Feb 2017 07:50:21 -0600 Subject: [PATCH 13/55] fix issue #401 --- moviepy/video/io/ffmpeg_writer.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/moviepy/video/io/ffmpeg_writer.py b/moviepy/video/io/ffmpeg_writer.py index 605015206..edf1b9fd9 100644 --- a/moviepy/video/io/ffmpeg_writer.py +++ b/moviepy/video/io/ffmpeg_writer.py @@ -7,6 +7,10 @@ import os import numpy as np +import sys + +PY3 = sys.version_info.major >=3 + try: from subprocess import DEVNULL # py3k except ImportError: @@ -134,14 +138,17 @@ def __init__(self, filename, size, fps, codec="libx264", audiofile=None, def write_frame(self, img_array): """ Writes one frame in the file.""" try: - self.proc.stdin.write(img_array.tostring()) + if PY3: + self.proc.stdin.write(img_array.tobytes()) + else: + self.proc.stdin.write(img_array.tostring()) except IOError as err: ffmpeg_error = self.proc.stderr.read() error = (str(err) + ("\n\nMoviePy error: FFMPEG encountered " "the following error while writing file %s:" "\n\n %s" % (self.filename, ffmpeg_error))) - if "Unknown encoder" in ffmpeg_error: + if b"Unknown encoder" in ffmpeg_error: error = error+("\n\nThe video export " "failed because FFMPEG didn't find the specified " @@ -150,7 +157,7 @@ def write_frame(self, img_array): "write_videofile. For instance:\n" " >>> clip.write_videofile('myvid.webm', codec='libvpx')")%(self.codec) - elif "incorrect codec parameters ?" in ffmpeg_error: + elif b"incorrect codec parameters ?" in ffmpeg_error: error = error+("\n\nThe video export " "failed, possibly because the codec specified for " @@ -164,13 +171,13 @@ def write_frame(self, img_array): "video codec." )%(self.codec, self.ext) - elif "encoder setup failed" in ffmpeg_error: + elif b"encoder setup failed" in ffmpeg_error: error = error+("\n\nThe video export " "failed, possibly because the bitrate you specified " "was too high or too low for the video codec.") - elif "Invalid encoder type" in ffmpeg_error: + elif b"Invalid encoder type" in ffmpeg_error: error = error + ("\n\nThe video export failed because the codec " "or file extension you provided is not a video") From 015f9a3ab57fd49ffbd0577f4d2f1a61ef1aef5a Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 06:52:35 -0600 Subject: [PATCH 14/55] fix issue #335 --- moviepy/audio/io/ffmpeg_audiowriter.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/moviepy/audio/io/ffmpeg_audiowriter.py b/moviepy/audio/io/ffmpeg_audiowriter.py index e895f5d80..81bc88848 100644 --- a/moviepy/audio/io/ffmpeg_audiowriter.py +++ b/moviepy/audio/io/ffmpeg_audiowriter.py @@ -2,6 +2,9 @@ import numpy as np import subprocess as sp +import sys +PY3=sys.version_info.major >= 3 + import os try: from subprocess import DEVNULL # py3k @@ -82,14 +85,17 @@ def __init__(self, filename, fps_input, nbytes=2, def write_frames(self,frames_array): try: - self.proc.stdin.write(frames_array.tostring()) + if PY3: + self.proc.stdin.write(frames_array.tobytes()) + else: + self.proc.stdin.write(frames_array.tostring()) except IOError as err: ffmpeg_error = self.proc.stderr.read() error = (str(err)+ ("\n\nMoviePy error: FFMPEG encountered " "the following error while writing file %s:"%self.filename + "\n\n"+ffmpeg_error)) - if "Unknown encoder" in ffmpeg_error: + if b"Unknown encoder" in ffmpeg_error: error = (error+("\n\nThe audio export failed because " "FFMPEG didn't find the specified codec for audio " @@ -99,7 +105,7 @@ def write_frames(self,frames_array): " >>> to_videofile('myvid.mp4', audio_codec='libmp3lame')" )%(self.codec)) - elif "incorrect codec parameters ?" in ffmpeg_error: + elif b"incorrect codec parameters ?" in ffmpeg_error: error = error+("\n\nThe audio export " "failed, possibly because the codec specified for " @@ -108,7 +114,7 @@ def write_frames(self,frames_array): "argument in to_videofile. This would be 'libmp3lame' " "for mp3, 'libvorbis' for ogg...")%(self.codec, self.ext) - elif "encoder setup failed": + elif b"encoder setup failed" in ffmpeg_error: error = error+("\n\nThe audio export " "failed, possily because the bitrate you specified " From afa1eb381135d9b6dc49e19b764c909ba8c14aae Mon Sep 17 00:00:00 2001 From: Mark Beacom Date: Wed, 15 Feb 2017 07:53:13 -0500 Subject: [PATCH 15/55] Update maintainer section in README --- README.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index c8320bab2..347b9e329 100644 --- a/README.rst +++ b/README.rst @@ -39,8 +39,8 @@ You can also discuss about the project on Reddit_ or on the mailing list moviepy Maintainers -------------- -- [Zulko](https://github.com/Zulko/) - Owner -- [mbeacom](https://github.com/mbeacom/) +- Zulko_ - Owner +- mbeacom_ Installation @@ -85,6 +85,7 @@ For advanced image processing you will need one or several of these packages. Fo .. _PyPI: https://pypi.python.org/pypi/moviepy .. _Pillow: http://pillow.readthedocs.org/en/latest/ .. _Zulko : https://github.com/Zulko +.. _mbeacom : https://github.com/mbeacom .. _Github: https://github.com/Zulko/moviepy .. _here: http://zulko.github.io/moviepy/ .. _Scipy: http://www.scipy.org/ From a87b99be70fc2d175c04b730ebb6fbc9ec7beaa8 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 07:40:50 -0600 Subject: [PATCH 16/55] make concatenate_videoclips Python 3 compatible.. fix issue #313 --- moviepy/video/compositing/concatenate.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index 358a93149..3d94aa255 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -1,5 +1,11 @@ import numpy as np +import sys +PY3 = sys.version_info.major >= 3 + +if PY3: + from functools import reduce + from moviepy.tools import deprecated_version_of from moviepy.video.VideoClip import VideoClip, ColorClip from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip From bed426645428fa390a4484680cf10632b09ec337 Mon Sep 17 00:00:00 2001 From: Mark Beacom Date: Wed, 15 Feb 2017 09:22:21 -0500 Subject: [PATCH 17/55] Increment release version --- moviepy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/version.py b/moviepy/version.py index 47f9323ca..66ae4c747 100644 --- a/moviepy/version.py +++ b/moviepy/version.py @@ -1 +1 @@ -__version__ = "0.2.2.12" +__version__ = "0.2.2.13" From 20a70f01dfbf28734afda4506adc9dc6d59c547b Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 12:06:20 -0600 Subject: [PATCH 18/55] CompositeVideoClip doesn't accept an argument of transparent --- examples/moving_letters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/moving_letters.py b/examples/moving_letters.py index dc724e478..61034e444 100644 --- a/examples/moving_letters.py +++ b/examples/moving_letters.py @@ -8,7 +8,7 @@ txtClip = TextClip('Cool effect',color='white', font="Amiri-Bold", kerning = 5, fontsize=100) cvc = CompositeVideoClip( [txtClip.set_pos('center')], - size=screensize, transparent=True) + size=screensize) # THE NEXT FOUR FUNCTIONS DEFINE FOUR WAYS OF MOVING THE LETTERS From a5a575a2bf7997b45682edc25be3214f505e9340 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 12:08:56 -0600 Subject: [PATCH 19/55] move PY3 variable to compat.py --- moviepy/audio/io/ffmpeg_audiowriter.py | 7 +++---- moviepy/audio/io/readers.py | 6 +++--- moviepy/compat.py | 2 ++ moviepy/video/compositing/concatenate.py | 5 ++--- moviepy/video/io/ffmpeg_reader.py | 5 +++-- moviepy/video/io/ffmpeg_writer.py | 8 +++----- 6 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 moviepy/compat.py diff --git a/moviepy/audio/io/ffmpeg_audiowriter.py b/moviepy/audio/io/ffmpeg_audiowriter.py index 81bc88848..9154a460e 100644 --- a/moviepy/audio/io/ffmpeg_audiowriter.py +++ b/moviepy/audio/io/ffmpeg_audiowriter.py @@ -2,13 +2,12 @@ import numpy as np import subprocess as sp -import sys -PY3=sys.version_info.major >= 3 +from movie.compat import PY3 import os -try: +if PY3: from subprocess import DEVNULL # py3k -except ImportError: +else: DEVNULL = open(os.devnull, 'wb') from tqdm import tqdm diff --git a/moviepy/audio/io/readers.py b/moviepy/audio/io/readers.py index 378c3c891..f2e1901dc 100644 --- a/moviepy/audio/io/readers.py +++ b/moviepy/audio/io/readers.py @@ -6,11 +6,11 @@ from moviepy.video.io.ffmpeg_reader import ffmpeg_parse_infos from moviepy.config import get_setting - +from moviepy.compat import PY3 import os -try: +if PY3: from subprocess import DEVNULL # py3k -except ImportError: +else: DEVNULL = open(os.devnull, 'wb') diff --git a/moviepy/compat.py b/moviepy/compat.py new file mode 100644 index 000000000..9e94a810a --- /dev/null +++ b/moviepy/compat.py @@ -0,0 +1,2 @@ +import sys +PY3=sys.version_info.major >= 3 diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index 3d94aa255..86ea2cdf0 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -1,7 +1,6 @@ import numpy as np -import sys -PY3 = sys.version_info.major >= 3 +from moviepy.compat import PY3 if PY3: from functools import reduce @@ -11,7 +10,7 @@ from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip from moviepy.audio.AudioClip import CompositeAudioClip -from moviepy.video.compositing.on_color import on_color +from moviepy.video.compositing.on_color import on_color def concatenate_videoclips(clips, method="chain", transition=None, bg_color=None, ismask=False, padding = 0): diff --git a/moviepy/video/io/ffmpeg_reader.py b/moviepy/video/io/ffmpeg_reader.py index 420eed103..04b2f8250 100644 --- a/moviepy/video/io/ffmpeg_reader.py +++ b/moviepy/video/io/ffmpeg_reader.py @@ -15,11 +15,12 @@ import numpy as np from moviepy.config import get_setting # ffmpeg, ffmpeg.exe, etc... from moviepy.tools import cvsecs +from moviepy.compat import PY3 import os -try: +if PY3: from subprocess import DEVNULL # py3k -except ImportError: +else: DEVNULL = open(os.devnull, 'wb') diff --git a/moviepy/video/io/ffmpeg_writer.py b/moviepy/video/io/ffmpeg_writer.py index edf1b9fd9..2756b0a85 100644 --- a/moviepy/video/io/ffmpeg_writer.py +++ b/moviepy/video/io/ffmpeg_writer.py @@ -7,13 +7,11 @@ import os import numpy as np -import sys +from moviepy.compat import PY3 -PY3 = sys.version_info.major >=3 - -try: +if PY3: from subprocess import DEVNULL # py3k -except ImportError: +else: DEVNULL = open(os.devnull, 'wb') from moviepy.config import get_setting From 8c1aaa524e16b600c5244b1f472c8a7759bd2fbf Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 12:41:55 -0600 Subject: [PATCH 20/55] fix movie => moviepy typo --- moviepy/audio/io/ffmpeg_audiowriter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/audio/io/ffmpeg_audiowriter.py b/moviepy/audio/io/ffmpeg_audiowriter.py index 9154a460e..206ae705c 100644 --- a/moviepy/audio/io/ffmpeg_audiowriter.py +++ b/moviepy/audio/io/ffmpeg_audiowriter.py @@ -2,7 +2,7 @@ import numpy as np import subprocess as sp -from movie.compat import PY3 +from moviepy.compat import PY3 import os if PY3: From cec45112ef559fecd3c4853530f66fd780fca422 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 12:42:49 -0600 Subject: [PATCH 21/55] fix issue #341 --- moviepy/Clip.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/moviepy/Clip.py b/moviepy/Clip.py index 8655d56bb..fade174a2 100644 --- a/moviepy/Clip.py +++ b/moviepy/Clip.py @@ -378,6 +378,10 @@ def subclip(self, t_start=0, t_end=None): they exist. """ + if t_start < 0: #make this more python like a negative value + #means to move backward from the end of the clip + t_start = self.duration + t_start #remeber t_start is negative + if (self.duration is not None) and (t_start>self.duration): raise ValueError("t_start (%.02f) "%t_start + From e3480c6df3f4eebbda5e677a0e86fbb5f2912b73 Mon Sep 17 00:00:00 2001 From: Gloin1313 Date: Wed, 15 Feb 2017 19:30:21 +0000 Subject: [PATCH 22/55] Fixed typo #375 https://github.com/Zulko/moviepy/issues/375 fixed --- moviepy/video/io/VideoFileClip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moviepy/video/io/VideoFileClip.py b/moviepy/video/io/VideoFileClip.py index 4ebd02758..92b89c09a 100644 --- a/moviepy/video/io/VideoFileClip.py +++ b/moviepy/video/io/VideoFileClip.py @@ -11,8 +11,8 @@ class VideoFileClip(VideoClip): A video clip originating from a movie file. For instance: :: - >>> clip = VideofileClip("myHolidays.mp4") - >>> clip2 = VideofileClip("myMaskVideo.avi") + >>> clip = VideoFileClip("myHolidays.mp4") + >>> clip2 = VideoFileClip("myMaskVideo.avi") Parameters From f4a460646f87b63781ad32b8ef6a0b9c0d8a6290 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 15 Feb 2017 14:21:53 -0600 Subject: [PATCH 23/55] fix issue #357, which makes real problem more obvious (media file does not exist --- moviepy/video/io/VideoFileClip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moviepy/video/io/VideoFileClip.py b/moviepy/video/io/VideoFileClip.py index 92b89c09a..77dc26d16 100644 --- a/moviepy/video/io/VideoFileClip.py +++ b/moviepy/video/io/VideoFileClip.py @@ -54,8 +54,8 @@ def __init__(self, filename, has_mask=False, # Make a reader pix_fmt= "rgba" if has_mask else "rgb24" - reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt) - self.reader = reader + self.reader = None #need this just in case FFMPEG has issues (__del__ complains) + self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt) # Make some of the reader's attributes accessible from the clip self.duration = self.reader.duration self.end = self.reader.duration From f7ad6be3b2740d2d855b11753749c1bd030f1fde Mon Sep 17 00:00:00 2001 From: Zulko Date: Wed, 15 Feb 2017 20:27:29 +0000 Subject: [PATCH 24/55] Revert "small recipe (mirroring a video)" --- docs/examples/quick_recipes.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/examples/quick_recipes.rst b/docs/examples/quick_recipes.rst index 736d29ce9..ec92577da 100644 --- a/docs/examples/quick_recipes.rst +++ b/docs/examples/quick_recipes.rst @@ -63,12 +63,3 @@ Getting the average frame of a video average_image = ImageClip(total_image/ nframes) average_image.save_frame("average_test.png") -Mirroring a video -"""""""""""""""""" - :: - import sys - from moviepy.editor import * - - clip = VideoFileClip(sys.argv[1]) - clip = clip.fx(vfx.mirror_x) - clip.write_videofile(sys.argv[2] From 58f9022f18af3aae8172fe76e5f594aeb1c54b63 Mon Sep 17 00:00:00 2001 From: Gloin1313 Date: Sat, 18 Feb 2017 17:18:09 +0000 Subject: [PATCH 25/55] Fixed indentation --- moviepy/video/io/VideoFileClip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/io/VideoFileClip.py b/moviepy/video/io/VideoFileClip.py index 8a2b704f5..1d0ea2a44 100644 --- a/moviepy/video/io/VideoFileClip.py +++ b/moviepy/video/io/VideoFileClip.py @@ -86,7 +86,7 @@ def __init__(self, filename, has_mask=False, nbytes = audio_nbytes) def __del__(self): - """ Close/delete the internal reader. """ + """ Close/delete the internal reader. """ try: del self.reader except AttributeError: From 2b9b14b27867307fa3631c1dbe7ac18ed73d282e Mon Sep 17 00:00:00 2001 From: Kerstin Kollmann Date: Sun, 19 Feb 2017 12:53:14 +0100 Subject: [PATCH 26/55] .gitignore ignore Mac-specific files, Jetbrains settings dir --- .gitignore | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 91ae4ba50..5b352189b 100644 --- a/.gitignore +++ b/.gitignore @@ -40,9 +40,13 @@ nosetests.xml .pydevproject # Temp files - *~ # Pipy codes - .pypirc + +# Mac +.DS_Store + +# JetBrains +.idea From 0360aeecd369c4c8cca0360d425b6d9c6aa3c1a0 Mon Sep 17 00:00:00 2001 From: Kerstin Kollmann Date: Sun, 19 Feb 2017 14:28:32 +0100 Subject: [PATCH 27/55] README.rst make mention of Gitter, add PyPI and Gitter badge --- README.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1db9411a2..012e02222 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,13 @@ MoviePy ======== +.. image:: https://badge.fury.io/py/moviepy.svg + :target: PyPI_ + :alt: MoviePy page on the Python Package Index +.. image:: https://badges.gitter.im/movie-py/gitter.png + :target: Gitter_ + :alt: Discuss MoviePy on Gitter + MoviePy (full documentation here_) is a Python module for video editing: cuts, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery_ for some examples of use. MoviePy can read and write all the most common audio and video formats, including GIF, and runs on Windows/Mac/Linux, with Python 2.7+ and 3. Here it is in action in an IPython notebook: @@ -35,7 +42,7 @@ Contribute ! MoviePy is an open-source software originally written by Zulko_ and released under the MIT licence. The project is hosted on Github_ , where everyone is welcome to contribute, ask for help or simply give feedback. -You can also discuss about the project on Reddit_ or on the mailing list moviepy@librelist.com . +You can also discuss the project on Reddit_ (preferred over GitHub issues for usage/examples), Gitter_ or the mailing list moviepy@librelist.com. Maintainers @@ -103,3 +110,4 @@ For advanced image processing you will need one or several of these packages. Fo .. _ffmpeg: http://www.ffmpeg.org/download.html .. _ImageMagick: http://www.imagemagick.org/script/index.php +.. _Gitter: https://gitter.im/movie-py/Lobby From 24c538a9570754840af65ec1dc0386117818d283 Mon Sep 17 00:00:00 2001 From: Kerstin Kollmann Date: Sun, 19 Feb 2017 20:21:08 +0100 Subject: [PATCH 28/55] README.rst wording, formatting --- README.rst | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/README.rst b/README.rst index 012e02222..25ae2116c 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ MoviePy -======== +======= .. image:: https://badge.fury.io/py/moviepy.svg :target: PyPI_ @@ -8,7 +8,7 @@ MoviePy :target: Gitter_ :alt: Discuss MoviePy on Gitter -MoviePy (full documentation here_) is a Python module for video editing: cuts, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery_ for some examples of use. +MoviePy (full documentation here_) is a Python module for video editing: cutting, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery_ for some examples of use. MoviePy can read and write all the most common audio and video formats, including GIF, and runs on Windows/Mac/Linux, with Python 2.7+ and 3. Here it is in action in an IPython notebook: @@ -17,7 +17,7 @@ MoviePy can read and write all the most common audio and video formats, includin :align: center Example --------- +------- In this example we open a video file, select the subclip between t=50s and t=60s, add a title at the center of the screen, and write the result to a new file: @@ -37,64 +37,65 @@ In this example we open a video file, select the subclip between t=50s and t=60s -Contribute ! -------------- +Contribute! +----------- -MoviePy is an open-source software originally written by Zulko_ and released under the MIT licence. The project is hosted on Github_ , where everyone is welcome to contribute, ask for help or simply give feedback. +MoviePy is open-source software originally written by Zulko_ and released under the MIT licence. The project is hosted on Github_, where everyone is welcome to contribute, ask for help or simply give feedback. You can also discuss the project on Reddit_ (preferred over GitHub issues for usage/examples), Gitter_ or the mailing list moviepy@librelist.com. Maintainers --------------- +----------- - Zulko_ - Owner - mbeacom_ Installation ---------------- +------------ -MoviePy depends on the Python modules Numpy_, imageio_, Decorator_, and tqdm_, which will be automatically installed during MoviePy's installation. The software FFMPEG should be automatically downloaded/installed (by imageio) during your first use of MoviePy (it takes a few seconds). If you want to use a specific version of FFMPEG, follow the instructions in file ``config_defaults.py``. In case of trouble, provide feedback. +MoviePy depends on the Python modules Numpy_, imageio_, Decorator_, and tqdm_, which will be automatically installed during MoviePy's installation. The software FFMPEG should be automatically downloaded/installed (by imageio) during your first use of MoviePy (installation will take a few seconds). If you want to use a specific version of FFMPEG, follow the instructions in ``config_defaults.py``. In case of trouble, provide feedback. -**Installation by hand:** download the sources, either on PyPI_ or (if you want the development version) on Github_, unzip everything in one folder, open a terminal and type :: +**Installation by hand:** download the sources, either from PyPI_ or, if you want the development version, from Github_, unzip everything into one folder, open a terminal and type: :: - (sudo) python setup.py install + $ (sudo) python setup.py install **Installation with pip:** if you have ``pip`` installed, just type this in a terminal: :: - (sudo) pip install moviepy + $ (sudo) pip install moviepy -If you have neither ``setuptools`` nor ``ez_setup`` installed the command above will fail, is this case type this before installing: :: +If you have neither ``setuptools`` nor ``ez_setup`` installed, the command above will fail. In this case type this before installing: :: - (sudo) pip install ez_setup + $ (sudo) pip install ez_setup -Other optional but useful dependencies -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Optional but useful dependencies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -ImageMagick_ is not strictly required, only if you want to write texts. It can also be used as a backend for GIFs but you can do GIFs with MoviePy without ImageMagick. +ImageMagick_ is not strictly required, but needed if you want to incorporate texts. It can also be used as a backend for GIFs, though you can also create GIFs with MoviePy without ImageMagick. -Once you have installed it, ImageMagick will be automatically detected by MoviePy, **except on Windows !**. Windows user, before installing MoviePy by hand, go into the ``moviepy/config_defaults.py`` file and provide the path to the ImageMagick binary called `convert`. It should look like this :: +Once you have installed ImageMagick, it will be automatically detected by MoviePy, **except on Windows!**. Windows user, before installing MoviePy by hand, need to edit ``moviepy/config_defaults.py`` to provide the path to the ImageMagick binary, which is called `convert`. It should look like this :: IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\convert.exe" -PyGame_ is needed for video and sound previews (useless if you intend to work with MoviePy on a server but really essential for advanced video editing *by hand*). +PyGame_ is needed for video and sound previews (not relevant if you intend to work with MoviePy on a server but essential for advanced video editing by hand). -For advanced image processing you will need one or several of these packages. For instance using the method ``clip.resize`` requires that at least one of Scipy, PIL, Pillow or OpenCV are installed. +For advanced image processing, you will need one or several of the following packages: -- The Python Imaging Library (PIL) or, better, its branch Pillow_ . -- Scipy_ (for tracking, segmenting, etc.), and can be used for resizing video clips if PIL and OpenCV aren't installed on your computer. +- The Python Imaging Library (PIL) or, even better, its branch Pillow_. +- Scipy_ (for tracking, segmenting, etc.) can be used to resize video clips if PIL and OpenCV are not installed. - `Scikit Image`_ may be needed for some advanced image manipulation. -- `OpenCV 2.4.6`_ or more recent (which provides the package ``cv2``) may be needed for some advanced image manipulation. +- `OpenCV 2.4.6`_ or a more recent version (one that provides the package ``cv2``) may be needed for some advanced image manipulation. +For instance, using the method ``clip.resize`` requires that at least one of Scipy, PIL, Pillow or OpenCV is installed. .. _gallery: http://zulko.github.io/moviepy/gallery.html .. _Reddit: http://www.reddit.com/r/moviepy/ .. _PyPI: https://pypi.python.org/pypi/moviepy .. _Pillow: http://pillow.readthedocs.org/en/latest/ -.. _Zulko : https://github.com/Zulko -.. _mbeacom : https://github.com/mbeacom +.. _Zulko: https://github.com/Zulko +.. _mbeacom: https://github.com/mbeacom .. _Github: https://github.com/Zulko/moviepy .. _here: http://zulko.github.io/moviepy/ .. _Scipy: http://www.scipy.org/ From 8ab44eadf49224a7766b2ce5f31f17b4e73eecf4 Mon Sep 17 00:00:00 2001 From: Kerstin Kollmann Date: Sun, 19 Feb 2017 20:36:02 +0100 Subject: [PATCH 29/55] README.rst structure link targets, add co-maintainers (with @username) --- README.rst | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 25ae2116c..1613b9ba7 100644 --- a/README.rst +++ b/README.rst @@ -49,7 +49,7 @@ Maintainers ----------- - Zulko_ - Owner -- mbeacom_ +- `@mbeacom`_ Installation @@ -90,16 +90,20 @@ For advanced image processing, you will need one or several of the following pac For instance, using the method ``clip.resize`` requires that at least one of Scipy, PIL, Pillow or OpenCV is installed. +.. MoviePy links .. _gallery: http://zulko.github.io/moviepy/gallery.html +.. _here: http://zulko.github.io/moviepy/ +.. _`download MoviePy`: https://github.com/Zulko/moviepy + +.. Websites, Platforms .. _Reddit: http://www.reddit.com/r/moviepy/ .. _PyPI: https://pypi.python.org/pypi/moviepy -.. _Pillow: http://pillow.readthedocs.org/en/latest/ -.. _Zulko: https://github.com/Zulko -.. _mbeacom: https://github.com/mbeacom .. _Github: https://github.com/Zulko/moviepy -.. _here: http://zulko.github.io/moviepy/ +.. _Gitter: https://gitter.im/movie-py/Lobby + +.. Software, Tools, Libraries +.. _Pillow: http://pillow.readthedocs.org/en/latest/ .. _Scipy: http://www.scipy.org/ -.. _`download MoviePy`: https://github.com/Zulko/moviepy .. _`OpenCV 2.4.6`: http://sourceforge.net/projects/opencvlibrary/files/ .. _Pygame: http://www.pygame.org/download.shtml .. _Numpy: http://www.scipy.org/install.html @@ -107,8 +111,13 @@ For instance, using the method ``clip.resize`` requires that at least one of Sci .. _`Scikit Image`: http://scikit-image.org/download.html .. _Decorator: https://pypi.python.org/pypi/decorator .. _tqdm: https://github.com/noamraph/tqdm - - .. _ffmpeg: http://www.ffmpeg.org/download.html .. _ImageMagick: http://www.imagemagick.org/script/index.php -.. _Gitter: https://gitter.im/movie-py/Lobby + +.. People +.. _Zulko: https://github.com/Zulko + +.. _`@Gloin1313`: https://github.com/Gloin1313 +.. _`@earney`: https://github.com/earney +.. _`@kerstin`: https://github.com/kerstin +.. _`@mbeacom`: https://github.com/mbeacom From 11cc67d9f42a667de05946be43464422912bc32b Mon Sep 17 00:00:00 2001 From: Kerstin Kollmann Date: Sun, 19 Feb 2017 20:46:55 +0100 Subject: [PATCH 30/55] README.rst move maintainers, contributing sections; change docs x-reference name --- README.rst | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/README.rst b/README.rst index 1613b9ba7..82d71db7f 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ MoviePy :target: Gitter_ :alt: Discuss MoviePy on Gitter -MoviePy (full documentation here_) is a Python module for video editing: cutting, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery_ for some examples of use. +MoviePy (full documentation_) is a Python module for video editing: cutting, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery_ for some examples of use. MoviePy can read and write all the most common audio and video formats, including GIF, and runs on Windows/Mac/Linux, with Python 2.7+ and 3. Here it is in action in an IPython notebook: @@ -36,22 +36,6 @@ In this example we open a video file, select the subclip between t=50s and t=60s result.write_videofile("myHolidays_edited.webm",fps=25) # Many options... - -Contribute! ------------ - -MoviePy is open-source software originally written by Zulko_ and released under the MIT licence. The project is hosted on Github_, where everyone is welcome to contribute, ask for help or simply give feedback. - -You can also discuss the project on Reddit_ (preferred over GitHub issues for usage/examples), Gitter_ or the mailing list moviepy@librelist.com. - - -Maintainers ------------ - -- Zulko_ - Owner -- `@mbeacom`_ - - Installation ------------ @@ -90,9 +74,29 @@ For advanced image processing, you will need one or several of the following pac For instance, using the method ``clip.resize`` requires that at least one of Scipy, PIL, Pillow or OpenCV is installed. + +Contribute +---------- + +MoviePy is open-source software originally written by Zulko_ and released under the MIT licence. The project is hosted on Github_, where everyone is welcome to contribute, ask for help or simply give feedback. + +You can also discuss the project on Reddit_ (preferred over GitHub issues for usage/examples), Gitter_ or the mailing list moviepy@librelist.com. + + +Maintainers +----------- + +- Zulko_ (owner) + +- `@Gloin1313`_ +- `@earney`_ +- Kay `@kerstin`_ +- `@mbeacom`_ + + .. MoviePy links .. _gallery: http://zulko.github.io/moviepy/gallery.html -.. _here: http://zulko.github.io/moviepy/ +.. _documentation: http://zulko.github.io/moviepy/ .. _`download MoviePy`: https://github.com/Zulko/moviepy .. Websites, Platforms @@ -116,7 +120,6 @@ For instance, using the method ``clip.resize`` requires that at least one of Sci .. People .. _Zulko: https://github.com/Zulko - .. _`@Gloin1313`: https://github.com/Gloin1313 .. _`@earney`: https://github.com/earney .. _`@kerstin`: https://github.com/kerstin From fdd941336bc70f2b71ce94fa45107d2cc98e8d37 Mon Sep 17 00:00:00 2001 From: Kerstin Kollmann Date: Sun, 19 Feb 2017 21:00:46 +0100 Subject: [PATCH 31/55] README.rst fix grammar --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 82d71db7f..10349fe0d 100644 --- a/README.rst +++ b/README.rst @@ -59,7 +59,7 @@ Optional but useful dependencies ImageMagick_ is not strictly required, but needed if you want to incorporate texts. It can also be used as a backend for GIFs, though you can also create GIFs with MoviePy without ImageMagick. -Once you have installed ImageMagick, it will be automatically detected by MoviePy, **except on Windows!**. Windows user, before installing MoviePy by hand, need to edit ``moviepy/config_defaults.py`` to provide the path to the ImageMagick binary, which is called `convert`. It should look like this :: +Once you have installed ImageMagick, it will be automatically detected by MoviePy, **except on Windows!**. Windows users, before installing MoviePy by hand, need to edit ``moviepy/config_defaults.py`` to provide the path to the ImageMagick binary, which is called `convert`. It should look like this :: IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\convert.exe" From b4cf52fc3edbde71611c7cb1842bdd348e0b935a Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Mon, 20 Feb 2017 07:51:25 -0600 Subject: [PATCH 32/55] fix issue 145. raise Exception when concatenate method != chain or compose --- moviepy/video/compositing/concatenate.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index a812b85d4..aee3d7f07 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -102,6 +102,12 @@ def make_frame(t): result = CompositeVideoClip( [c.set_start(t).set_pos('center') for (c, t) in zip(clips, tt)], size = (w, h), bg_color=bg_color, ismask=ismask) + else: + #get name of this function + import sys + _name = sys._getframe().f_code.co_name + + raise Exception("Moviepy Error: The 'method' argument of `{0}` must be 'chain' or 'compose'".format(_name)) result.tt = tt From 1bb1e3c09e1a54779816852f3df567b369d83e64 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Mon, 20 Feb 2017 08:46:10 -0600 Subject: [PATCH 33/55] make PEP8 compatible --- moviepy/video/compositing/concatenate.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index aee3d7f07..9de94e5bd 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -103,11 +103,8 @@ def make_frame(t): for (c, t) in zip(clips, tt)], size = (w, h), bg_color=bg_color, ismask=ismask) else: - #get name of this function - import sys - _name = sys._getframe().f_code.co_name - - raise Exception("Moviepy Error: The 'method' argument of `{0}` must be 'chain' or 'compose'".format(_name)) + raise Exception("Moviepy Error: The 'method' argument of " + "concatenate_videoclips must be 'chain' or 'compose'") result.tt = tt From 639e44916fea4bf34443a956f902476c87f66429 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Mon, 20 Feb 2017 12:43:02 -0600 Subject: [PATCH 34/55] fix PR #413 . (issue #357) --- moviepy/video/io/VideoFileClip.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/moviepy/video/io/VideoFileClip.py b/moviepy/video/io/VideoFileClip.py index a21bc0500..9b18fa105 100644 --- a/moviepy/video/io/VideoFileClip.py +++ b/moviepy/video/io/VideoFileClip.py @@ -67,15 +67,15 @@ def __init__(self, filename, has_mask=False, if has_mask: - self.make_frame = lambda t: reader.get_frame(t)[:,:,:3] - mask_mf = lambda t: reader.get_frame(t)[:,:,3]/255.0 + self.make_frame = lambda t: self.reader.get_frame(t)[:,:,:3] + mask_mf = lambda t: self.reader.get_frame(t)[:,:,3]/255.0 self.mask = (VideoClip(ismask = True, make_frame = mask_mf) .set_duration(self.duration)) self.mask.fps = self.fps else: - self.make_frame = lambda t: reader.get_frame(t) + self.make_frame = lambda t: self.reader.get_frame(t) # Make a reader for the audio, if any. if audio and self.reader.infos['audio_found']: From ed4adbeb4047758f1944a7cfbedccad5489a1fba Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Mon, 20 Feb 2017 14:47:10 -0600 Subject: [PATCH 35/55] create test for issue #145 --- tests/test_install.py | 10 ---------- tests/test_issues.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 10 deletions(-) delete mode 100644 tests/test_install.py create mode 100644 tests/test_issues.py diff --git a/tests/test_install.py b/tests/test_install.py deleted file mode 100644 index f98f93450..000000000 --- a/tests/test_install.py +++ /dev/null @@ -1,10 +0,0 @@ - - -from moviepy.editor import * - -W,H = (150,180) -color_clips_props = [{ 'color':[0,0,255], - 'init_pos':[] -[0,0,255],[0,255,0],[255,0,0] -red_clip, green_clip, blue_clip = [ColorClip((W,H),color=c) - for c in RED, GREEN, BLUE] diff --git a/tests/test_issues.py b/tests/test_issues.py new file mode 100644 index 000000000..f3b4e4dfe --- /dev/null +++ b/tests/test_issues.py @@ -0,0 +1,36 @@ +""" +Tests meant to be run with pytest +""" + +import sys +import os +import pytest + +from moviepy.editor import * + + +#@pytest.fixture +#def example_video1(): +# pass + +global knights, knights10 + +def download_youtube_video(url, filename): + if not os.path.exists(filename): + print("\nDownloading %s\n" % filename) + download_webfile(url, filename) + print("Downloading complete...\n") + + +def test_download_media(capsys): + with capsys.disabled(): + download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") + + knights=VideoFileClip("media/knights.mp4") + knights10 = knights.subclip(60,70) + + + +def test_issue_145(): + with pytest.raises(Exception, message="Expecting Exception"): + _final = concatenation([knights10], method = 'composite') From 19d4f035038ffd9e415cdc328c757ddec6fb462d Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Tue, 21 Feb 2017 06:54:36 -0600 Subject: [PATCH 36/55] add tests/media to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5b352189b..5342d3994 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ nosetests.xml # JetBrains .idea + +tests/media From fca17275b61a264ad98b5dfef23c53e155ce2fc7 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Tue, 21 Feb 2017 14:39:47 -0600 Subject: [PATCH 37/55] fix Issue #385 , no DirectoryClip class (#434) * fix issue #385 , no DirectoryClip class * replace DirectoryClip with ImageSequenceClip --- moviepy/video/VideoClip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index 54490d206..ab52bccc1 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -1,7 +1,7 @@ """ This module implements VideoClip (base class for video clips) and its main subclasses: -- Animated clips: VideofileClip, DirectoryClip +- Animated clips: VideofileClip, ImageSequenceClip - Static image clips: ImageClip, ColorClip, TextClip, """ @@ -382,7 +382,7 @@ def write_images_sequence(self, nameformat, fps=None, verbose=True, ------ The resulting image sequence can be read using e.g. the class - ``DirectoryClip``. + ``ImageSequenceClip``. """ From 3870506eb297609abe4a62588c7ea0e529559242 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 22 Feb 2017 07:56:02 -0600 Subject: [PATCH 38/55] fix issue 417, unicode has no attribute 'shape' error. --- moviepy/video/VideoClip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index 06f3047fa..4cbab379c 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -919,7 +919,7 @@ def __init__(self, img, ismask=False, transparent=True, VideoClip.__init__(self, ismask=ismask, duration=duration) - if isinstance(img, str): + if isinstance(img, (str, unicode)): img = imread(img) if len(img.shape) == 3: # img is (now) a RGB(a) numpy array From 3ec5106687689a1b97e23bfa896ca5da55051b13 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 22 Feb 2017 07:56:17 -0600 Subject: [PATCH 39/55] add test for issue 417 --- tests/test_issues.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_issues.py b/tests/test_issues.py index f3b4e4dfe..e889d7113 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -34,3 +34,12 @@ def test_download_media(capsys): def test_issue_145(): with pytest.raises(Exception, message="Expecting Exception"): _final = concatenation([knights10], method = 'composite') + +def test_issue_417(): + # failed in python2 + + cad = u'media/python_logo.png' + myclip = ImageClip(cad).fx(vfx.resize, newsize=[1280, 660]) + final = CompositeVideoClip([myclip], size=(1280, 720)) + #final.set_duration(7).write_videofile("test.mp4", fps=30) + From 3d877cb4b1e78d4eb6479ccaf84b7de724af4f7c Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 22 Feb 2017 08:06:10 -0600 Subject: [PATCH 40/55] add test for issue 417 --- moviepy/video/VideoClip.py | 9 +++++++-- tests/test_issues.py | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index 4cbab379c..e52b593ee 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -40,6 +40,7 @@ convert_masks_to_RGB, use_clip_fps_by_default) +from ..compat import PY3 try: from subprocess import DEVNULL # py3k except ImportError: @@ -919,8 +920,12 @@ def __init__(self, img, ismask=False, transparent=True, VideoClip.__init__(self, ismask=ismask, duration=duration) - if isinstance(img, (str, unicode)): - img = imread(img) + if PY3: + if isinstance(img, str): + img = imread(img) + else: + if isinstance(img, (str, unicode)): + img = imread(img) if len(img.shape) == 3: # img is (now) a RGB(a) numpy array diff --git a/tests/test_issues.py b/tests/test_issues.py index e889d7113..7886e221b 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -43,3 +43,5 @@ def test_issue_417(): final = CompositeVideoClip([myclip], size=(1280, 720)) #final.set_duration(7).write_videofile("test.mp4", fps=30) +if __name__ == '__main__': + pytest.main() From 32b700726508bf26d1d6d8f81f7820df958ce1dc Mon Sep 17 00:00:00 2001 From: JM Date: Wed, 22 Feb 2017 09:28:45 -0800 Subject: [PATCH 41/55] Fixed resize documentation issue #319 (#346) --- moviepy/video/fx/resize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moviepy/video/fx/resize.py b/moviepy/video/fx/resize.py index 8ea7c3e89..deed05b8e 100644 --- a/moviepy/video/fx/resize.py +++ b/moviepy/video/fx/resize.py @@ -67,7 +67,7 @@ def resize(clip, newsize=None, height=None, width=None, apply_to_mask=True): newsize: Can be either - - ``(height,width)`` in pixels or a float representing + - ``(width,height)`` in pixels or a float representing - A scaling factor, like 0.5 - A function of time returning one of these. From df31c030865a03dc3514148f108c5e9443352b96 Mon Sep 17 00:00:00 2001 From: Zowie Date: Wed, 22 Feb 2017 19:30:12 +0100 Subject: [PATCH 42/55] Handle bytes when listing fonts in VideoClip.py (#306) Handle bytes when listing fonts in VideoClip.py --- moviepy/video/VideoClip.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index ab52bccc1..7e1c1b9e4 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -1202,9 +1202,12 @@ def list(arg): lines = result.splitlines() if arg == 'font': - return [l[8:] for l in lines if l.startswith(" Font:")] + return [l.decode('UTF-8')[8:] for l in lines if l.startswith(b" Font:")] elif arg == 'color': - return [l.split(" ")[1] for l in lines[2:]] + return [l.split(b" ")[0] for l in lines[2:]] + else: + raise Exception("Moviepy:Error! Argument must equal " + "'font' or 'color'") @staticmethod def search(string, arg): From f07e6a3538c22f5b88b9ca20ad5bb6dc216ead80 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 22 Feb 2017 12:36:07 -0600 Subject: [PATCH 43/55] add test for PR306 --- tests/test_issues.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_issues.py b/tests/test_issues.py index f3b4e4dfe..c00f3388b 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -34,3 +34,13 @@ def test_download_media(capsys): def test_issue_145(): with pytest.raises(Exception, message="Expecting Exception"): _final = concatenation([knights10], method = 'composite') + +def test_PR_306(): + assert TextClip.list('font') != [] + assert TextClip.list('color') != [] + + with pytest.raises(Exception, message="Expecting Exception"): + TextClip.list('blah') + +if __name__ == '__main__': + pytest.main() From ba1dd25a717a593906613ec9811c7576bc5a102d Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Wed, 22 Feb 2017 12:38:29 -0600 Subject: [PATCH 44/55] add test for PR306 (#440) --- tests/test_issues.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_issues.py b/tests/test_issues.py index f3b4e4dfe..c00f3388b 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -34,3 +34,13 @@ def test_download_media(capsys): def test_issue_145(): with pytest.raises(Exception, message="Expecting Exception"): _final = concatenation([knights10], method = 'composite') + +def test_PR_306(): + assert TextClip.list('font') != [] + assert TextClip.list('color') != [] + + with pytest.raises(Exception, message="Expecting Exception"): + TextClip.list('blah') + +if __name__ == '__main__': + pytest.main() From 372177a3baccac2790997d8dee340d44755c4974 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Thu, 23 Feb 2017 09:07:07 -0600 Subject: [PATCH 45/55] create test file for pull requests (#433) --- tests/test_PR.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/test_PR.py diff --git a/tests/test_PR.py b/tests/test_PR.py new file mode 100644 index 000000000..d9c3392b3 --- /dev/null +++ b/tests/test_PR.py @@ -0,0 +1,29 @@ +""" +Tests meant to be run with pytest +""" + +import sys +import os +import pytest + +from moviepy.editor import * + + +def download_youtube_video(url, filename): + if not os.path.exists(filename): + print("\nDownloading %s\n" % filename) + download_webfile(url, filename) + print("Downloading complete...\n") + + +def test_PR_339(): + #in caption mode + overlay = TextClip(txt='foo', + color='white', + size=(640, 480), + method='caption', + align='center', + fontsize=25) + + #in_label_mode + overlay = TextClip(txt='foo', method='label') From 09d35726b6cb02cf8e5cdf9e33d02714e83eaa42 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Thu, 23 Feb 2017 09:10:42 -0600 Subject: [PATCH 46/55] Test issue 407 (video has a valid fps after concatenate function) (#443) --- tests/test_issues.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_issues.py b/tests/test_issues.py index c00f3388b..3a0be9359 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -23,6 +23,8 @@ def download_youtube_video(url, filename): def test_download_media(capsys): + global knights, knights10 + with capsys.disabled(): download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") @@ -30,11 +32,24 @@ def test_download_media(capsys): knights10 = knights.subclip(60,70) - def test_issue_145(): with pytest.raises(Exception, message="Expecting Exception"): _final = concatenation([knights10], method = 'composite') +def test_issue_407(): + assert round(knights.fps) == 30 + assert knights10.fps == knights.fps + + _text=TextClip("blah").set_duration(2) #TextClip has no fps attribute + + _video=concatenate_videoclips([_text, knights10, knights10]) + assert _video.fps == knights10.fps + + # uncomment when PR 416 is merged. + #_video=concatenate_videoclips([_text]) + #assert _video.fps == None + + def test_PR_306(): assert TextClip.list('font') != [] assert TextClip.list('color') != [] From fd36a54f28163e7f8df0959c2c5b8be3ee24a8bf Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Thu, 23 Feb 2017 09:34:09 -0600 Subject: [PATCH 47/55] Move PR test to test_PR.py file (#444) * move PR test from test_issues.py to test_PR.py --- tests/test_PR.py | 23 +++++++++++++++++++++++ tests/test_issues.py | 13 ------------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tests/test_PR.py b/tests/test_PR.py index d9c3392b3..3212543ef 100644 --- a/tests/test_PR.py +++ b/tests/test_PR.py @@ -8,6 +8,7 @@ from moviepy.editor import * +global knights, knights10 def download_youtube_video(url, filename): if not os.path.exists(filename): @@ -16,6 +17,25 @@ def download_youtube_video(url, filename): print("Downloading complete...\n") +def test_download_media(capsys): + global knights, knights10 + + with capsys.disabled(): + download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") + + knights=VideoFileClip("media/knights.mp4") + knights10 = knights.subclip(60,70) + + + +def test_PR_306(): + assert TextClip.list('font') != [] + assert TextClip.list('color') != [] + + with pytest.raises(Exception, message="Expecting Exception"): + TextClip.list('blah') + + def test_PR_339(): #in caption mode overlay = TextClip(txt='foo', @@ -27,3 +47,6 @@ def test_PR_339(): #in_label_mode overlay = TextClip(txt='foo', method='label') + +if __name__ == '__main__': + pytest.main() diff --git a/tests/test_issues.py b/tests/test_issues.py index 3a0be9359..d02257744 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -2,17 +2,11 @@ Tests meant to be run with pytest """ -import sys import os import pytest from moviepy.editor import * - -#@pytest.fixture -#def example_video1(): -# pass - global knights, knights10 def download_youtube_video(url, filename): @@ -50,12 +44,5 @@ def test_issue_407(): #assert _video.fps == None -def test_PR_306(): - assert TextClip.list('font') != [] - assert TextClip.list('color') != [] - - with pytest.raises(Exception, message="Expecting Exception"): - TextClip.list('blah') - if __name__ == '__main__': pytest.main() From 9e6b9c825d444ec29e22f714ac92a33d968cfc17 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Thu, 23 Feb 2017 09:58:30 -0600 Subject: [PATCH 48/55] add code to download python_logo.png --- tests/test_issues.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/test_issues.py b/tests/test_issues.py index 7886e221b..36c45a198 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -2,29 +2,30 @@ Tests meant to be run with pytest """ -import sys import os import pytest from moviepy.editor import * -#@pytest.fixture -#def example_video1(): -# pass - global knights, knights10 -def download_youtube_video(url, filename): +def download_url(url, filename): if not os.path.exists(filename): print("\nDownloading %s\n" % filename) download_webfile(url, filename) print("Downloading complete...\n") +def download_youtube_video(youtube_id, filename): + download_url(youtube_id, filename) def test_download_media(capsys): + global knights, knights10 + with capsys.disabled(): download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") + download_url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Python_logo_and_wordmark.svg/260px-Python_logo_and_wordmark.svg.png", + "media/python_logo.png") knights=VideoFileClip("media/knights.mp4") knights10 = knights.subclip(60,70) From b1016cb5ab67ed2455f2f3b016ca3b18a922ac4f Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Fri, 24 Feb 2017 07:03:14 -0600 Subject: [PATCH 49/55] remove duplicate test_issue_417 function --- tests/test_issues.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_issues.py b/tests/test_issues.py index 03916dcb5..1c391c863 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -33,14 +33,6 @@ def test_download_media(capsys): def test_issue_145(): with pytest.raises(Exception, message="Expecting Exception"): _final = concatenation([knights10], method = 'composite') - -def test_issue_417(): - # failed in python2 - - cad = u'media/python_logo.png' - myclip = ImageClip(cad).fx(vfx.resize, newsize=[1280, 660]) - final = CompositeVideoClip([myclip], size=(1280, 720)) - #final.set_duration(7).write_videofile("test.mp4", fps=30) def test_issue_407(): assert round(knights.fps) == 30 From ff82fe8377663bcee5d380168dc50458fc5baa63 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Sat, 25 Feb 2017 19:03:28 -0600 Subject: [PATCH 50/55] add testing with travis-ci (#447) added testing via travis-ci --- .travis.yml | 16 ++++++++++++++++ tests/test_PR.py | 44 ++++++++++++++------------------------------ tests/test_issues.py | 31 +++++++++++++++---------------- 3 files changed, 45 insertions(+), 46 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..445e9f41c --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: python +python: + - "2.7" + - "3.3" + - "3.4" + - "3.5" + - "3.6" +# command to install dependencies +before_install: + - sudo apt-get -qq update + - sudo apt-get install -y ffmpeg + - mkdir media +install: + - python setup.py install +# command to run tests +script: py.test diff --git a/tests/test_PR.py b/tests/test_PR.py index 3212543ef..cbb4f2d6f 100644 --- a/tests/test_PR.py +++ b/tests/test_PR.py @@ -8,45 +8,29 @@ from moviepy.editor import * -global knights, knights10 - -def download_youtube_video(url, filename): - if not os.path.exists(filename): - print("\nDownloading %s\n" % filename) - download_webfile(url, filename) - print("Downloading complete...\n") - - -def test_download_media(capsys): - global knights, knights10 - - with capsys.disabled(): - download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") - - knights=VideoFileClip("media/knights.mp4") - knights10 = knights.subclip(60,70) - - def test_PR_306(): - assert TextClip.list('font') != [] - assert TextClip.list('color') != [] + #put this back in once we get ImageMagick working on travis-ci + #assert TextClip.list('font') != [] + #assert TextClip.list('color') != [] - with pytest.raises(Exception, message="Expecting Exception"): - TextClip.list('blah') + #with pytest.raises(Exception, message="Expecting Exception"): + # TextClip.list('blah') + pass def test_PR_339(): #in caption mode - overlay = TextClip(txt='foo', - color='white', - size=(640, 480), - method='caption', - align='center', - fontsize=25) + #overlay = TextClip(txt='foo', + # color='white', + # size=(640, 480), + # method='caption', + # align='center', + # fontsize=25) #in_label_mode - overlay = TextClip(txt='foo', method='label') + #overlay = TextClip(txt='foo', method='label') + pass if __name__ == '__main__': pytest.main() diff --git a/tests/test_issues.py b/tests/test_issues.py index 1c391c863..6106e5bb7 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -7,8 +7,6 @@ from moviepy.editor import * -global knights, knights10 - def download_url(url, filename): if not os.path.exists(filename): print("\nDownloading %s\n" % filename) @@ -16,37 +14,38 @@ def download_url(url, filename): print("Downloading complete...\n") def download_youtube_video(youtube_id, filename): + # FYI.. travis-ci doesn't like youtube-dl download_url(youtube_id, filename) def test_download_media(capsys): - global knights, knights10 - with capsys.disabled(): - download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") + #download_youtube_video("zvCvOC2VwDc", "media/knights.mp4") download_url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Python_logo_and_wordmark.svg/260px-Python_logo_and_wordmark.svg.png", "media/python_logo.png") - knights=VideoFileClip("media/knights.mp4") - knights10 = knights.subclip(60,70) + #knights=VideoFileClip("media/knights.mp4") + #knights10 = knights.subclip(60,70) def test_issue_145(): + _video = ColorClip((800, 600), col=(255,0,0)).set_duration(5) with pytest.raises(Exception, message="Expecting Exception"): - _final = concatenation([knights10], method = 'composite') + _final = concatenation([_video], method = 'composite') def test_issue_407(): - assert round(knights.fps) == 30 - assert knights10.fps == knights.fps + _red = ColorClip((800, 600), col=(255,0,0)).set_duration(5) + _red.fps=30 + assert round(_red.fps) == 30 - _text=TextClip("blah").set_duration(2) #TextClip has no fps attribute + _green=ColorClip((640, 480), col=(0,255,0)).set_duration(2) #ColorClip has no fps attribute + _blue=ColorClip((640, 480), col=(0,0,255)).set_duration(2) #ColorClip has no fps attribute - _video=concatenate_videoclips([_text, knights10, knights10]) - assert _video.fps == knights10.fps + _video=concatenate_videoclips([_red, _green, _blue]) + assert _video.fps == _red.fps # uncomment when PR 416 is merged. - #_video=concatenate_videoclips([_text]) - #assert _video.fps == None - + #_video1=concatenate_videoclips([_text]) + #assert _video1.fps == None def test_issue_417(): # failed in python2 From ec57a19479a5ada8e73c093cbe02fa0e4aa50a6a Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Sat, 25 Feb 2017 19:15:29 -0600 Subject: [PATCH 51/55] put DEVNULL into compat.py (#432) --- moviepy/audio/io/ffmpeg_audiowriter.py | 6 +----- moviepy/audio/io/readers.py | 6 +----- moviepy/compat.py | 6 ++++++ moviepy/config.py | 7 +------ moviepy/tools.py | 7 ++----- moviepy/video/VideoClip.py | 6 +----- moviepy/video/io/ffmpeg_reader.py | 6 +----- moviepy/video/io/ffmpeg_writer.py | 8 +------- moviepy/video/io/gif_writers.py | 5 +---- 9 files changed, 15 insertions(+), 42 deletions(-) diff --git a/moviepy/audio/io/ffmpeg_audiowriter.py b/moviepy/audio/io/ffmpeg_audiowriter.py index 206ae705c..6183fd058 100644 --- a/moviepy/audio/io/ffmpeg_audiowriter.py +++ b/moviepy/audio/io/ffmpeg_audiowriter.py @@ -2,13 +2,9 @@ import numpy as np import subprocess as sp -from moviepy.compat import PY3 +from moviepy.compat import PY3, DEVNULL import os -if PY3: - from subprocess import DEVNULL # py3k -else: - DEVNULL = open(os.devnull, 'wb') from tqdm import tqdm from moviepy.config import get_setting diff --git a/moviepy/audio/io/readers.py b/moviepy/audio/io/readers.py index f2e1901dc..910000d92 100644 --- a/moviepy/audio/io/readers.py +++ b/moviepy/audio/io/readers.py @@ -6,12 +6,8 @@ from moviepy.video.io.ffmpeg_reader import ffmpeg_parse_infos from moviepy.config import get_setting -from moviepy.compat import PY3 +from moviepy.compat import PY3, DEVNULL import os -if PY3: - from subprocess import DEVNULL # py3k -else: - DEVNULL = open(os.devnull, 'wb') class FFMPEG_AudioReader: diff --git a/moviepy/compat.py b/moviepy/compat.py index 9e94a810a..ceac4d312 100644 --- a/moviepy/compat.py +++ b/moviepy/compat.py @@ -1,2 +1,8 @@ +import os import sys PY3=sys.version_info.major >= 3 + +if PY3: + from subprocess import DEVNULL # py3k +else: + DEVNULL = open(os.devnull, 'wb') diff --git a/moviepy/config.py b/moviepy/config.py index fd40384fa..307abf901 100644 --- a/moviepy/config.py +++ b/moviepy/config.py @@ -1,9 +1,6 @@ import os import subprocess as sp -try: - from subprocess import DEVNULL # py3k -except ImportError: - DEVNULL = open(os.devnull, 'wb') +from .compat import DEVNULL if os.name == 'nt': try: @@ -103,5 +100,3 @@ def change_settings(new_settings={}, file=None): print( "MoviePy : ImageMagick successfully found." ) else: print( "MoviePy : can't find or access ImageMagick." ) - - diff --git a/moviepy/tools.py b/moviepy/tools.py index 686fdf636..4255e9d08 100644 --- a/moviepy/tools.py +++ b/moviepy/tools.py @@ -8,10 +8,7 @@ import re import os -try: - from subprocess import DEVNULL # py3k -except ImportError: - DEVNULL = open(os.devnull, 'wb') +from .compat import DEVNULL def sys_write_flush(s): @@ -156,4 +153,4 @@ def find_extension(codec): for ext,infos in extensions_dict.items(): if ('codec' in infos) and codec in infos['codec']: return ext - raise ValueError \ No newline at end of file + raise ValueError diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index a6990060a..6a7a6c8ec 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -40,11 +40,7 @@ convert_masks_to_RGB, use_clip_fps_by_default) -from ..compat import PY3 -try: - from subprocess import DEVNULL # py3k -except ImportError: - DEVNULL = open(os.devnull, 'wb') +from ..compat import PY3, DEVNULL class VideoClip(Clip): diff --git a/moviepy/video/io/ffmpeg_reader.py b/moviepy/video/io/ffmpeg_reader.py index 04b2f8250..836fb6a8f 100644 --- a/moviepy/video/io/ffmpeg_reader.py +++ b/moviepy/video/io/ffmpeg_reader.py @@ -15,13 +15,9 @@ import numpy as np from moviepy.config import get_setting # ffmpeg, ffmpeg.exe, etc... from moviepy.tools import cvsecs -from moviepy.compat import PY3 +from moviepy.compat import PY3, DEVNULL import os -if PY3: - from subprocess import DEVNULL # py3k -else: - DEVNULL = open(os.devnull, 'wb') class FFMPEG_VideoReader: diff --git a/moviepy/video/io/ffmpeg_writer.py b/moviepy/video/io/ffmpeg_writer.py index 2756b0a85..e19cd7bd2 100644 --- a/moviepy/video/io/ffmpeg_writer.py +++ b/moviepy/video/io/ffmpeg_writer.py @@ -7,13 +7,7 @@ import os import numpy as np -from moviepy.compat import PY3 - -if PY3: - from subprocess import DEVNULL # py3k -else: - DEVNULL = open(os.devnull, 'wb') - +from moviepy.compat import PY3, DEVNULL from moviepy.config import get_setting from moviepy.tools import verbose_print diff --git a/moviepy/video/io/gif_writers.py b/moviepy/video/io/gif_writers.py index b82a1d3c6..aeb6d9533 100644 --- a/moviepy/video/io/gif_writers.py +++ b/moviepy/video/io/gif_writers.py @@ -6,10 +6,7 @@ from moviepy.tools import verbose_print, subprocess_call import numpy as np -try: - from subprocess import DEVNULL # py3k -except ImportError: - DEVNULL = open(os.devnull, 'wb') +from moviepy.compat import DEVNULL try: import imageio From e8d124ab10ca8b8ac8d92e11d69fbee2215ecdce Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Sun, 26 Feb 2017 16:23:00 -0600 Subject: [PATCH 52/55] add travis-ci badge to readme file --- README.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 10349fe0d..c87074830 100644 --- a/README.rst +++ b/README.rst @@ -7,7 +7,10 @@ MoviePy .. image:: https://badges.gitter.im/movie-py/gitter.png :target: Gitter_ :alt: Discuss MoviePy on Gitter - +.. image:: https://travis-ci.org/Zulko/moviepy.svg?branch=master + :target: https://travis-ci.org/Zulko/moviepy + :alt: Build status on travis-ci + MoviePy (full documentation_) is a Python module for video editing: cutting, concatenations, title insertions, video compositing (a.k.a. non-linear editing), video processing, and creation of custom effects. See the gallery_ for some examples of use. MoviePy can read and write all the most common audio and video formats, including GIF, and runs on Windows/Mac/Linux, with Python 2.7+ and 3. Here it is in action in an IPython notebook: From c0f692585a489e117d3e3593913856db1d7321f5 Mon Sep 17 00:00:00 2001 From: Brian Lee Date: Mon, 27 Feb 2017 08:05:24 -0500 Subject: [PATCH 53/55] pick highest fps when concatenating (#416) * readers.py cast chunksize from float to int * choose highest fps of clips when concatenating * pick highest fps when concatenating * pick highest fps when concatenating * fps either max or none * remove resolve markers removed resolve markers such as HEAD, etc so that the file will compile correctly. Remove some double blank lines, etc * update concatenate.py; add c.fps is not None --- moviepy/audio/io/readers.py | 5 ++-- moviepy/video/compositing/concatenate.py | 36 ++++++++++-------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/moviepy/audio/io/readers.py b/moviepy/audio/io/readers.py index 910000d92..bfc6e597c 100644 --- a/moviepy/audio/io/readers.py +++ b/moviepy/audio/io/readers.py @@ -110,6 +110,8 @@ def skip_chunk(self,chunksize): def read_chunk(self,chunksize): + # chunksize is not being autoconverted from float to int + chunksize = int(round(chunksize)) L = self.nchannels*chunksize*self.nbytes s = self.proc.stdout.read(L) dt = {1: 'int8',2:'int16',4:'int32'}[self.nbytes] @@ -234,6 +236,3 @@ def buffer_around(self,framenumber): def __del__(self): self.close_proc() - - - diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index 9de94e5bd..94358d208 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -15,10 +15,10 @@ def concatenate_videoclips(clips, method="chain", transition=None, bg_color=None, ismask=False, padding = 0): """ Concatenates several video clips - + Returns a video clip made by clip by concatenating several video clips. (Concatenated means that they will be played one after another). - + There are two methods: - method="chain": will produce a clip that simply outputs @@ -38,33 +38,29 @@ def concatenate_videoclips(clips, method="chain", transition=None, will be transparent if mask=True, else it will be of the color specified by ``bg_color``. - If all clips with a fps attribute have the same fps, it becomes the fps of - the result. + The clip with the highest FPS will be the FPS of the result clip. Parameters ----------- - clips A list of video clips which must all have their ``duration`` attributes set. - method "chain" or "compose": see above. - transition A clip that will be played between each two clips of the list. - + bg_color Only for method='compose'. Color of the background. Set to None for a transparent clip - + padding Only for method='compose'. Duration during two consecutive clips. Note that for negative padding, a clip will partly play at the same time as the clip it follows (negative padding is cool for clips who fade in on one another). A non-null padding automatically sets the method to `compose`. - + """ if transition is not None: @@ -72,22 +68,20 @@ def concatenate_videoclips(clips, method="chain", transition=None, clips = reduce(lambda x, y: x + y, l) + [clips[-1]] transition = None - tt = np.cumsum([0] + [c.duration for c in clips]) sizes = [v.size for v in clips] - w = max([r[0] for r in sizes]) h = max([r[1] for r in sizes]) tt = np.maximum(0, tt + padding*np.arange(len(tt))) - + if method == "chain": def make_frame(t): i = max([i for i, e in enumerate(tt) if e <= t]) return clips[i].get_frame(t - tt[i]) - + result = VideoClip(ismask = ismask, make_frame = make_frame) if any([c.mask is not None for c in clips]): masks = [c.mask if (c.mask is not None) else @@ -96,8 +90,6 @@ def make_frame(t): for c in clips] result.mask = concatenate_videoclips(masks, method="chain", ismask=True) result.clips = clips - - elif method == "compose": result = CompositeVideoClip( [c.set_start(t).set_pos('center') for (c, t) in zip(clips, tt)], @@ -107,18 +99,20 @@ def make_frame(t): "concatenate_videoclips must be 'chain' or 'compose'") result.tt = tt - + result.start_times = tt[:-1] result.start, result.duration, result.end = 0, tt[-1] , tt[-1] - + audio_t = [(c.audio,t) for c,t in zip(clips,tt) if c.audio is not None] if len(audio_t)>0: result.audio = CompositeAudioClip([a.set_start(t) for a,t in audio_t]) - fps_list = list(set([c.fps for c in clips if hasattr(c,'fps')])) - if len(fps_list)==1: - result.fps= fps_list[0] + 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) return result From 5eb43c9ec325e2cb7f3e99d21943722251a2ba72 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Mon, 27 Feb 2017 07:21:35 -0600 Subject: [PATCH 54/55] add test for issue 416 --- tests/test_issues.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_issues.py b/tests/test_issues.py index 6106e5bb7..92edf83f5 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -43,9 +43,9 @@ def test_issue_407(): _video=concatenate_videoclips([_red, _green, _blue]) assert _video.fps == _red.fps - # uncomment when PR 416 is merged. - #_video1=concatenate_videoclips([_text]) - #assert _video1.fps == None +def test_issue_416(): + _video1=concatenate_videoclips([_green]) + assert _video1.fps == None def test_issue_417(): # failed in python2 From 04bb711e0906fe668738a2259bbf394e3a319993 Mon Sep 17 00:00:00 2001 From: Billy Earney Date: Mon, 27 Feb 2017 07:29:42 -0600 Subject: [PATCH 55/55] fix test_issue_416 --- tests/test_issues.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_issues.py b/tests/test_issues.py index 92edf83f5..9b932fb69 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -44,6 +44,7 @@ def test_issue_407(): assert _video.fps == _red.fps def test_issue_416(): + _green=ColorClip((640, 480), col=(0,255,0)).set_duration(2) #ColorClip has no fps attribute _video1=concatenate_videoclips([_green]) assert _video1.fps == None