diff --git a/CHANGELOG.md b/CHANGELOG.md index d7cf7f75a..d3f31bf63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Deprecated ### Removed -- Support removed for Python versions 2.7, 3.4 & 3.5 +- Support for Python versions 2.7, 3.4 & 3.5 +- All previously deprecated methods and parameters [#1115]: + - `AudioClip.to_audiofile()` -> use `AudioClip.write_audiofile()` + - `VideoClip.to_videofile()` -> use `VideoClip.write_videofile()` + - `VideoClip.to_images_sequence()` -> use `VideoClip.write_images_sequence()` + - `concatenate()` -> use `concatenate_videoclips()` + - `verbose` parameter in `AudioClip.write_audiofile()`, `ffmpeg_audiowriter()`, `VideoFileClip()`, `VideoClip.write_videofile()`, `VideoClip.write_images_sequence()`, `ffmpeg_write_video()`, `write_gif()`, `write_gif_with_tempfiles()`, `write_gif_with_image_io()` -> Instead of `verbose=False`, use `logger=None` + - `verbose_print()` -> no replacement + - `col` parameter in `ColorClip()` -> use `color` ### Fixed - When using `VideoClip.write_videofile()` with `write_logfile=True`, errors would not be properly reported [#890] diff --git a/moviepy/audio/AudioClip.py b/moviepy/audio/AudioClip.py index e722d4dd8..508ab7438 100644 --- a/moviepy/audio/AudioClip.py +++ b/moviepy/audio/AudioClip.py @@ -6,7 +6,7 @@ from moviepy.audio.io.ffmpeg_audiowriter import ffmpeg_audiowrite from moviepy.Clip import Clip from moviepy.decorators import requires_duration -from moviepy.tools import deprecated_version_of, extensions_dict +from moviepy.tools import extensions_dict class AudioClip(Clip): @@ -169,7 +169,6 @@ def write_audiofile( bitrate=None, ffmpeg_params=None, write_logfile=False, - verbose=True, logger="bar", ): """ Writes an audio file from the AudioClip. @@ -206,10 +205,7 @@ def write_audiofile( write_logfile If true, produces a detailed logfile named filename + '.log' when writing the file - - verbose - Boolean indicating whether to print infomation - + logger Either 'bar' or None or any Proglog logger @@ -240,19 +236,11 @@ def write_audiofile( codec=codec, bitrate=bitrate, write_logfile=write_logfile, - verbose=verbose, ffmpeg_params=ffmpeg_params, logger=logger, ) -# The to_audiofile method is replaced by the more explicit write_audiofile. -AudioClip.to_audiofile = deprecated_version_of( - AudioClip.write_audiofile, "to_audiofile" -) -### - - class AudioArrayClip(AudioClip): """ diff --git a/moviepy/audio/io/ffmpeg_audiowriter.py b/moviepy/audio/io/ffmpeg_audiowriter.py index 017955210..98425cde1 100644 --- a/moviepy/audio/io/ffmpeg_audiowriter.py +++ b/moviepy/audio/io/ffmpeg_audiowriter.py @@ -176,15 +176,12 @@ def ffmpeg_audiowrite( codec="libvorbis", bitrate=None, write_logfile=False, - verbose=True, ffmpeg_params=None, logger="bar", ): """ A function that wraps the FFMPEG_AudioWriter to write an AudioClip to a file. - - NOTE: verbose is deprecated. """ if write_logfile: diff --git a/moviepy/editor.py b/moviepy/editor.py index c9c2b602f..96f0eef8d 100644 --- a/moviepy/editor.py +++ b/moviepy/editor.py @@ -30,10 +30,7 @@ from .video.io.downloader import download_webfile from .video.VideoClip import VideoClip, ImageClip, ColorClip, TextClip from .video.compositing.CompositeVideoClip import CompositeVideoClip, clips_array -from .video.compositing.concatenate import ( - concatenate_videoclips, - concatenate, -) # concatenate=deprecated +from .video.compositing.concatenate import concatenate_videoclips from .audio.AudioClip import AudioClip, CompositeAudioClip, concatenate_audioclips from .audio.io.AudioFileClip import AudioFileClip diff --git a/moviepy/tools.py b/moviepy/tools.py index cc3498245..1091091b7 100644 --- a/moviepy/tools.py +++ b/moviepy/tools.py @@ -19,15 +19,9 @@ def sys_write_flush(s): sys.stdout.flush() -def verbose_print(verbose, s): - """ Only prints s (with sys_write_flush) if verbose is True.""" - if verbose: - sys_write_flush(s) - - def subprocess_call(cmd, logger="bar", errorprint=True): """ Executes the given subprocess command. - + Set logger to None or a custom Proglog logger to avoid printings. """ logger = proglog.default_bar_logger(logger) @@ -54,20 +48,20 @@ def subprocess_call(cmd, logger="bar", errorprint=True): def cvsecs(time): - """ Will convert any time into seconds. - - If the type of `time` is not valid, - it's returned as is. + """ 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') + >>> 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 diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index 7dc065a92..cce72c78a 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -25,7 +25,6 @@ use_clip_fps_by_default, ) from ..tools import ( - deprecated_version_of, extensions_dict, find_extension, subprocess_call, @@ -157,7 +156,6 @@ def write_videofile( rewrite_audio=True, remove_temp=True, write_logfile=False, - verbose=True, threads=None, ffmpeg_params=None, logger="bar", @@ -261,9 +259,6 @@ def write_videofile( logger Either "bar" for progress bar or None or any Proglog logger. - verbose (deprecated, kept for compatibility) - Formerly used for toggling messages on/off. Use logger=None now. - Examples ======== @@ -322,7 +317,6 @@ def write_videofile( audio_codec, bitrate=audio_bitrate, write_logfile=write_logfile, - verbose=verbose, logger=logger, ) @@ -335,7 +329,6 @@ def write_videofile( preset=preset, write_logfile=write_logfile, audiofile=audiofile, - verbose=verbose, threads=threads, ffmpeg_params=ffmpeg_params, logger=logger, @@ -349,9 +342,7 @@ def write_videofile( @requires_duration @use_clip_fps_by_default @convert_masks_to_RGB - def write_images_sequence( - self, nameformat, fps=None, verbose=True, withmask=True, logger="bar" - ): + def write_images_sequence(self, nameformat, fps=None, withmask=True, logger="bar"): """ Writes the videoclip to a sequence of image files. Parameters @@ -371,9 +362,6 @@ def write_images_sequence( withmask will save the clip's mask (if any) as an alpha canal (PNGs only). - verbose - Boolean indicating whether to print information. - logger Either 'bar' (progress bar) or None or any Proglog logger. @@ -414,7 +402,6 @@ def write_gif( program="imageio", opt="nq", fuzz=1, - verbose=True, loop=0, dispose=False, colors=None, @@ -481,7 +468,6 @@ def write_gif( fps=fps, opt=opt, loop=loop, - verbose=verbose, colors=colors, logger=logger, ) @@ -496,7 +482,6 @@ def write_gif( program=program, opt=opt, fuzz=fuzz, - verbose=verbose, loop=loop, dispose=dispose, colors=colors, @@ -513,7 +498,6 @@ def write_gif( program=program, opt=opt, fuzz=fuzz, - verbose=verbose, loop=loop, dispose=dispose, colors=colors, @@ -1041,21 +1025,6 @@ def fl_time(self, time_func, apply_to=None, keep_duration=False): setattr(self, attr, new_a) -# ## -# -# The old functions to_videofile, to_gif, to_images sequences have been -# replaced by the more explicite write_videofile, write_gif, etc. - -VideoClip.set_pos = deprecated_version_of(VideoClip.set_position, "set_pos") -VideoClip.to_videofile = deprecated_version_of( - VideoClip.write_videofile, "to_videofile" -) -VideoClip.to_gif = deprecated_version_of(VideoClip.write_gif, "to_gif") -VideoClip.to_images_sequence = deprecated_version_of( - VideoClip.write_images_sequence, "to_images_sequence" -) - - class ColorClip(ImageClip): """An ImageClip showing just one color. @@ -1073,29 +1042,13 @@ class ColorClip(ImageClip): ismask Set to true if the clip will be used as a mask. - col - Has been deprecated. Do not use. """ - def __init__(self, size, color=None, ismask=False, duration=None, col=None): - if col is not None: - warnings.warn( - "The `ColorClip` parameter `col` has been deprecated." - " Please use `color` instead.", - DeprecationWarning, - ) - if color is not None: - warnings.warn( - "The arguments `color` and `col` have both been " - "passed to `ColorClip` so `col` has been ignored.", - UserWarning, - ) - else: - color = col + def __init__(self, size, color=None, ismask=False, duration=None): w, h = size shape = (h, w) if np.isscalar(color) else (h, w, len(color)) - ImageClip.__init__( - self, np.tile(color, w * h).reshape(shape), ismask=ismask, duration=duration + super().__init__( + np.tile(color, w * h).reshape(shape), ismask=ismask, duration=duration ) diff --git a/moviepy/video/compositing/concatenate.py b/moviepy/video/compositing/concatenate.py index 0bc99b88e..e3c997364 100644 --- a/moviepy/video/compositing/concatenate.py +++ b/moviepy/video/compositing/concatenate.py @@ -2,9 +2,7 @@ from functools import reduce from moviepy.audio.AudioClip import CompositeAudioClip -from moviepy.tools import deprecated_version_of from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip -from moviepy.video.compositing.on_color import on_color from moviepy.video.VideoClip import ColorClip, VideoClip @@ -116,6 +114,3 @@ def get_mask(c): fpss = [c.fps for c in clips if getattr(c, "fps", None) is not None] result.fps = max(fpss) if fpss else None return result - - -concatenate = deprecated_version_of(concatenate_videoclips, oldname="concatenate") diff --git a/moviepy/video/compositing/transitions.py b/moviepy/video/compositing/transitions.py index 8b4ea356a..b80413b48 100644 --- a/moviepy/video/compositing/transitions.py +++ b/moviepy/video/compositing/transitions.py @@ -62,7 +62,7 @@ def slide_in(clip, duration, side): >>> slided_clips = [CompositeVideoClip([ clip.fx(transfx.slide_in, duration=1, side='left')]) for clip in clips] - >>> final_clip = concatenate( slided_clips, padding=-1) + >>> final_clip = concatenate_videoclips( slided_clips, padding=-1) """ w, h = clip.size diff --git a/moviepy/video/io/VideoFileClip.py b/moviepy/video/io/VideoFileClip.py index 9a6938da1..9fa30bc85 100644 --- a/moviepy/video/io/VideoFileClip.py +++ b/moviepy/video/io/VideoFileClip.py @@ -61,17 +61,17 @@ class VideoFileClip(VideoClip): fps: Frames per second in the original file. - - + + Read docs for Clip() and VideoClip() for other, more generic, attributes. - + Lifetime -------- - + Note that this creates subprocesses and locks files. If you construct one of these instances, you must call close() afterwards, or the subresources will not be cleaned up until the process ends. - - If copies are made, and close() is called on one, it may cause methods on the other copies to fail. + + If copies are made, and close() is called on one, it may cause methods on the other copies to fail. """ @@ -85,7 +85,6 @@ def __init__( resize_algorithm="bicubic", audio_fps=44100, audio_nbytes=2, - verbose=False, fps_source="tbr", ): diff --git a/moviepy/video/io/ffmpeg_writer.py b/moviepy/video/io/ffmpeg_writer.py index ff464a833..13ab5b20b 100644 --- a/moviepy/video/io/ffmpeg_writer.py +++ b/moviepy/video/io/ffmpeg_writer.py @@ -220,7 +220,6 @@ def ffmpeg_write_video( withmask=False, write_logfile=False, audiofile=None, - verbose=True, threads=None, ffmpeg_params=None, logger="bar", @@ -247,9 +246,6 @@ def ffmpeg_write_video( threads=threads, ffmpeg_params=ffmpeg_params, ) as writer: - - nframes = int(clip.duration * fps) - for t, frame in clip.iter_frames( logger=logger, with_times=True, fps=fps, dtype="uint8" ): diff --git a/moviepy/video/io/gif_writers.py b/moviepy/video/io/gif_writers.py index baa005e18..89fc767f9 100644 --- a/moviepy/video/io/gif_writers.py +++ b/moviepy/video/io/gif_writers.py @@ -25,7 +25,6 @@ def write_gif_with_tempfiles( program="ImageMagick", opt="OptimizeTransparency", fuzz=1, - verbose=True, loop=0, dispose=True, colors=None, @@ -129,7 +128,6 @@ def write_gif( program="ImageMagick", opt="OptimizeTransparency", fuzz=1, - verbose=True, withmask=True, loop=0, dispose=True, @@ -329,7 +327,7 @@ def write_gif( def write_gif_with_image_io( - clip, filename, fps=None, opt=0, loop=0, colors=None, verbose=True, logger="bar" + clip, filename, fps=None, opt=0, loop=0, colors=None, logger="bar" ): """ Writes the gif with the Python library ImageIO (calls FreeImage). diff --git a/moviepy/video/io/html_tools.py b/moviepy/video/io/html_tools.py index 5b42705d8..e8761578f 100644 --- a/moviepy/video/io/html_tools.py +++ b/moviepy/video/io/html_tools.py @@ -52,7 +52,7 @@ def html_embed( clip, filetype=None, maxduration=60, rd_kwargs=None, center=True, **html_kwargs ): """ Returns HTML5 code embedding the clip - + clip Either a file name, or a clip to preview. Either an image, a sound or a video. Clips will actually be @@ -62,10 +62,10 @@ def html_embed( filetype One of 'video','image','audio'. If None is given, it is determined based on the extension of ``filename``, but this can bug. - + rd_kwargs keyword arguments for the rendering, like {'fps':15, 'bitrate':'50k'} - + **html_kwargs Allow you to give some options, like width=260, autoplay=True, @@ -102,12 +102,12 @@ def html_embed( clip.save_frame(**kwargs) elif isinstance(clip, VideoClip): filename = TEMP_PREFIX + ".mp4" - kwargs = {"filename": filename, "verbose": False, "preset": "ultrafast"} + kwargs = {"filename": filename, "preset": "ultrafast"} kwargs.update(rd_kwargs) clip.write_videofile(**kwargs) elif isinstance(clip, AudioClip): filename = TEMP_PREFIX + ".mp3" - kwargs = {"filename": filename, "verbose": False} + kwargs = {"filename": filename} kwargs.update(rd_kwargs) clip.write_audiofile(**kwargs) else: @@ -206,11 +206,11 @@ def ipython_display( fps Enables to specify an fps, as required for clips whose fps is unknown. - + **kwargs: Allow you to give some options, like width=260, etc. When editing looping gifs, a good choice is loop=1, autoplay=1. - + Remarks: If your browser doesn't support HTML5, this should warn you. If nothing is displayed, maybe your file or filename is wrong. Important: The media will be physically embedded in the notebook. diff --git a/moviepy/video/tools/cuts.py b/moviepy/video/tools/cuts.py index d98adfb30..066d2e36f 100644 --- a/moviepy/video/tools/cuts.py +++ b/moviepy/video/tools/cuts.py @@ -21,7 +21,7 @@ def find_video_period(clip, fps=None, tmin=0.3): class FramesMatch: """ - + Parameters ----------- @@ -119,7 +119,7 @@ def from_clip(clip, dist_thr, max_d, fps=None): Examples --------- - + We find all matching frames in a given video and turn the best match with a duration of 1.5s or more into a GIF: @@ -135,16 +135,16 @@ def from_clip(clip, dist_thr, max_d, fps=None): clip A MoviePy video clip, possibly transformed/resized - + dist_thr Distance above which a match is rejected - + max_d Maximal duration (in seconds) between two matching frames - + fps Frames per second (default will be clip.fps) - + """ N_pixels = clip.w * clip.h * 3 @@ -278,49 +278,49 @@ def select_scenes( def write_gifs(self, clip, gif_dir): for (start, end, _, _) in self: name = "%s/%08d_%08d.gif" % (gif_dir, 100 * start, 100 * end) - clip.subclip(start, end).write_gif(name, verbose=False) + clip.subclip(start, end).write_gif(name) @use_clip_fps_by_default def detect_scenes(clip=None, luminosities=None, thr=10, logger="bar", fps=None): """ Detects scenes of a clip based on luminosity changes. - + Note that for large clip this may take some time - + Returns -------- cuts, luminosities cuts is a series of cuts [(0,t1), (t1,t2),...(...,tf)] luminosities are the luminosities computed for each frame of the clip. - + Parameters ----------- - + clip A video clip. Can be None if a list of luminosities is provided instead. If provided, the luminosity of each frame of the clip will be computed. If the clip has no 'fps' attribute, you must provide it. - + luminosities A list of luminosities, e.g. returned by detect_scenes in a previous run. - + thr Determines a threshold above which the 'luminosity jumps' will be considered as scene changes. A scene change is defined as a change between 2 consecutive frames that is larger than (avg * thr) where avg is the average of the absolute changes between consecutive frames. - + progress_bar We all love progress bars ! Here is one for you, in option. - + fps Must be provided if you provide no clip or a clip without fps attribute. - + """ if luminosities is None: diff --git a/tests/test_PR.py b/tests/test_PR.py index 4d18460f7..3cabb8882 100644 --- a/tests/test_PR.py +++ b/tests/test_PR.py @@ -61,39 +61,6 @@ def test_PR_373(): assert result[0].yy[i] == result1[0].yy[i] -def test_PR_424(): - """Ensure deprecation and user warnings are triggered.""" - import warnings - - warnings.simplefilter("always") # Alert us of deprecation warnings. - - # Recommended use - ColorClip([1000, 600], color=(60, 60, 60), duration=10).close() - - with pytest.warns(DeprecationWarning): - # Uses `col` so should work the same as above, but give warning. - ColorClip([1000, 600], col=(60, 60, 60), duration=10).close() - - # Catch all warnings as record. - with pytest.warns(None) as record: - # Should give 2 warnings and use `color`, not `col` - ColorClip([1000, 600], color=(60, 60, 60), duration=10, col=(2, 2, 2)).close() - - message1 = ( - "The `ColorClip` parameter `col` has been deprecated. " - + "Please use `color` instead." - ) - message2 = ( - "The arguments `color` and `col` have both been passed to " - + "`ColorClip` so `col` has been ignored." - ) - - # Assert that two warnings popped and validate the message text. - assert len(record) == 2 - assert str(record[0].message) == message1 - assert str(record[1].message) == message2 - - def test_PR_458(): clip = ColorClip([1000, 600], color=(60, 60, 60), duration=2) clip.write_videofile(os.path.join(TMP_DIR, "test.mp4"), logger=None, fps=30)