diff --git a/.gitignore b/.gitignore index afe46e523..dfdcd4cbe 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,6 @@ nosetests.xml # Tests tests/media -media/ # Documentation docs/build/ diff --git a/.travis.yml b/.travis.yml index 11473a107..21ebbdd65 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,6 @@ language: python cache: pip python: - "2.7" - - "3.4" - "3.5" - "3.6" @@ -12,7 +11,6 @@ before_install: - sudo add-apt-repository -y ppa:kirillshkrogalev/ffmpeg-next - sudo apt-get -y -qq update - sudo apt-get install -y -qq ffmpeg - - mkdir media # Ensure PIP is up-to-date to avoid warnings. - python -m pip install --upgrade pip @@ -20,7 +18,7 @@ before_install: - pip install --upgrade setuptools # The default py that is installed is too old on some platforms, leading to version conflicts - pip install --upgrade py pytest - + # modify ImageMagick policy file so that Textclips work correctly. # `| sudo tee` replaces `>` so that it can have root permissions - cat /etc/ImageMagick/policy.xml | sed 's/none/read,write/g' | sudo tee /etc/ImageMagick/policy.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d8c475b..dc1a4be17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,103 @@ # Change Log -## [v2.3.5](https://github.com/Zulko/moviepy/tree/v2.3.5) (2018-05-31) -[Full Changelog](https://github.com/Zulko/moviepy/compare/v0.2.3.4...v2.3.5) +## [v1.0.1](https://github.com/Zulko/moviepy/tree/v1.0.1) (2019-10-01) +[Full Changelog](https://github.com/Zulko/moviepy/compare/v1.0.0...v1.0.1) + +**Closed issues:** + +- Thoughts on re-routing tqdm progress bar for external use? [\#412](https://github.com/Zulko/moviepy/issues/412) +- Progress bar [\#128](https://github.com/Zulko/moviepy/issues/128) +- website video examples broken videos [\#1019](https://github.com/Zulko/moviepy/issues/1019) +- Audio glitches when using concatenate\_videoclips. [\#1005](https://github.com/Zulko/moviepy/issues/1005) +- txt\_clip = TextClip\(filename='learn.srt'\) --bug:TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType [\#984](https://github.com/Zulko/moviepy/issues/984) +- txt\_clip = TextClip\(filename='learn.srt'\) --bug:TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType [\#983](https://github.com/Zulko/moviepy/issues/983) +- txt\_clip = TextClip\(filename='learn.srt'\)path should be string, bytes, os.PathLike or integer, not NoneType [\#982](https://github.com/Zulko/moviepy/issues/982) +- write\_videofile writes blank black when writing grayscale [\#973](https://github.com/Zulko/moviepy/issues/973) +- i dont understand this question [\#967](https://github.com/Zulko/moviepy/issues/967) +- Thank you guys! [\#957](https://github.com/Zulko/moviepy/issues/957) +- Saving an opencv stream [\#953](https://github.com/Zulko/moviepy/issues/953) +- Issue with reader not being defined [\#950](https://github.com/Zulko/moviepy/issues/950) +- On Windows, ImageMagick needs to be installed with Utility mode for the convert.exe file to exist [\#937](https://github.com/Zulko/moviepy/issues/937) +- extract subtitles [\#932](https://github.com/Zulko/moviepy/issues/932) +- ffmpeg\_parse\_infos silently hangs on Windows when MP4 file contains enough metadata [\#926](https://github.com/Zulko/moviepy/issues/926) +- crop missing from moviepy.video.fx.all [\#914](https://github.com/Zulko/moviepy/issues/914) +- Segmentation Error on VPS [\#912](https://github.com/Zulko/moviepy/issues/912) +- Error when installing with imageio [\#911](https://github.com/Zulko/moviepy/issues/911) +- Backwards compatibility [\#889](https://github.com/Zulko/moviepy/issues/889) +- frozen seconds in beginning of subclip using ffmpeg\_extract\_subclip\(\) [\#847](https://github.com/Zulko/moviepy/issues/847) +- \[Errno 3\] No such process : on Windows Sub Linux \(ubuntu 16.x\) [\#765](https://github.com/Zulko/moviepy/issues/765) +- Progress bar newline error in Jupyter [\#740](https://github.com/Zulko/moviepy/issues/740) +- Refer to magick on https://zulko.github.io/moviepy/install.html [\#689](https://github.com/Zulko/moviepy/issues/689) +- Configure Appveyor support [\#628](https://github.com/Zulko/moviepy/issues/628) +- tqdm progress bar write\_videofile send to iterator [\#568](https://github.com/Zulko/moviepy/issues/568) +- ffmpeg\_extract\_subclip returns black frames [\#508](https://github.com/Zulko/moviepy/issues/508) +- Windows: specifying path to ImageMagick in config\_defaults.py [\#378](https://github.com/Zulko/moviepy/issues/378) +- AttributeError: 'NoneType' object has no attribute 'start' [\#191](https://github.com/Zulko/moviepy/issues/191) +- ImageMagick write gif success but no file found [\#113](https://github.com/Zulko/moviepy/issues/113) + +**Merged pull requests:** + +- Update maintainer list in the README [\#1022](https://github.com/Zulko/moviepy/pull/1022) ([tburrows13](https://github.com/tburrows13)) +- fixed small error in 'Clip' documentation [\#1002](https://github.com/Zulko/moviepy/pull/1002) ([thomasmatt88](https://github.com/thomasmatt88)) +- Specify Coverage version explicitly. [\#987](https://github.com/Zulko/moviepy/pull/987) ([Julian-O](https://github.com/Julian-O)) +- Updating Docs for ImageMagick Installing Guide [\#980](https://github.com/Zulko/moviepy/pull/980) ([ABODFTW](https://github.com/ABODFTW)) +- Several ImageMagick related bug fixes [\#972](https://github.com/Zulko/moviepy/pull/972) ([KiLLAAA](https://github.com/KiLLAAA)) +- More resilient Windows CI regarding fetching ImageMagick binaries [\#941](https://github.com/Zulko/moviepy/pull/941) ([Overdrivr](https://github.com/Overdrivr)) +- WIP: Auto-detect image magick latest 6.9.X-Y version [\#936](https://github.com/Zulko/moviepy/pull/936) ([Overdrivr](https://github.com/Overdrivr)) +- Windows-based testing [\#931](https://github.com/Zulko/moviepy/pull/931) ([Overdrivr](https://github.com/Overdrivr)) +- Fix formatting in logger [\#929](https://github.com/Zulko/moviepy/pull/929) ([tnoff](https://github.com/tnoff)) +- Fix for \#926 [\#927](https://github.com/Zulko/moviepy/pull/927) ([Overdrivr](https://github.com/Overdrivr)) +- Invalid video URL in docs/getting\_started/compositing [\#921](https://github.com/Zulko/moviepy/pull/921) ([gepcel](https://github.com/gepcel)) +- Do not install tests in site-packages [\#880](https://github.com/Zulko/moviepy/pull/880) ([cgohlke](https://github.com/cgohlke)) +- FIX changed order of specifications -ss befor -i for ffmpeg\_extract\_subclip\(\) [\#848](https://github.com/Zulko/moviepy/pull/848) ([grszkthfr](https://github.com/grszkthfr)) + +## [v1.0.0](https://github.com/Zulko/moviepy/tree/v1.0.0) (2019-02-17) +[Full Changelog](https://github.com/Zulko/moviepy/compare/v0.2.3.5...v1.0.0) + +**Closed issues:** + +- Can't overlay gizeh animation onto video with transparency/mask [\#898](https://github.com/Zulko/moviepy/issues/898) +- \[0.2.4.0\] Garbled audio when exporting mp3 from mp4? [\#891](https://github.com/Zulko/moviepy/issues/891) +- Error with VideoFileClip\(filePath\) [\#868](https://github.com/Zulko/moviepy/issues/868) +- I am trying to run this code [\#867](https://github.com/Zulko/moviepy/issues/867) +- Out of memory exception [\#862](https://github.com/Zulko/moviepy/issues/862) +- simple problem on the first step: importing moviepy.editor [\#852](https://github.com/Zulko/moviepy/issues/852) +- MoviePy insert multiple images in a video [\#840](https://github.com/Zulko/moviepy/issues/840) +- Videogrep can't works with Moviepy in Windows [\#834](https://github.com/Zulko/moviepy/issues/834) +- File "\", line 1 error [\#832](https://github.com/Zulko/moviepy/issues/832) +- ImageMagick error - Ubuntu 16.04 [\#831](https://github.com/Zulko/moviepy/issues/831) +- Combining thousands of small clips into one file [\#827](https://github.com/Zulko/moviepy/issues/827) +- TypeError: 'ImageClip' object is not iterable [\#824](https://github.com/Zulko/moviepy/issues/824) +- OSError: \[WinError 6\] The handle is invalid... concatenating clips [\#823](https://github.com/Zulko/moviepy/issues/823) +- How to add audio tracks. not to replace it. [\#822](https://github.com/Zulko/moviepy/issues/822) +- Missing 'ffmpeg-win32-v3.2.4.exe' [\#821](https://github.com/Zulko/moviepy/issues/821) +- No sound with an audio clip add to an video in quicktime [\#820](https://github.com/Zulko/moviepy/issues/820) +- Pip fails when trying to install [\#812](https://github.com/Zulko/moviepy/issues/812) +- PermissionError after trying to delete a file after it's purpose is done [\#810](https://github.com/Zulko/moviepy/issues/810) +- video clip from URI [\#780](https://github.com/Zulko/moviepy/issues/780) +- Fails on FreeBSD [\#756](https://github.com/Zulko/moviepy/issues/756) +- inconsistent behaviour of clip.get\_frame\(\) [\#751](https://github.com/Zulko/moviepy/issues/751) +- Error with write\_videofile [\#727](https://github.com/Zulko/moviepy/issues/727) +- Trying to use moviepy on lambda, but has problem with ffmpeg [\#642](https://github.com/Zulko/moviepy/issues/642) +- Unexpected Behavior With negative t\_start in Subclip [\#341](https://github.com/Zulko/moviepy/issues/341) +- Could not find a format to read the specified file in mode 'i' [\#219](https://github.com/Zulko/moviepy/issues/219) +- WindowsError\[5\] and AttributeError Exception [\#170](https://github.com/Zulko/moviepy/issues/170) +- Can't make VideoFileClip 'utf8' [\#169](https://github.com/Zulko/moviepy/issues/169) +- Rendered output missing first frame [\#155](https://github.com/Zulko/moviepy/issues/155) +- Incorrect output when concatenate\_videoclips two quicktime videos [\#144](https://github.com/Zulko/moviepy/issues/144) +- a bytes object is recognised as a string [\#120](https://github.com/Zulko/moviepy/issues/120) + +**Merged pull requests:** + +- New version of imageio with imageio\_ffmpeg for python 3.4+ [\#907](https://github.com/Zulko/moviepy/pull/907) ([Zulko](https://github.com/Zulko)) +- fix typo that introduces audio regression [\#894](https://github.com/Zulko/moviepy/pull/894) ([chrox](https://github.com/chrox)) +- fixing the git remote syntax in documentions [\#887](https://github.com/Zulko/moviepy/pull/887) ([ishandutta2007](https://github.com/ishandutta2007)) +- modified max duration error for better understanding [\#875](https://github.com/Zulko/moviepy/pull/875) ([kapilkd13](https://github.com/kapilkd13)) +- Fixed typo in docstring for VideoClip class [\#871](https://github.com/Zulko/moviepy/pull/871) ([Armcollector](https://github.com/Armcollector)) +- Fix a small typing error [\#845](https://github.com/Zulko/moviepy/pull/845) ([yuvallanger](https://github.com/yuvallanger)) + +## [v0.2.3.5](https://github.com/Zulko/moviepy/tree/v0.2.3.5) (2018-05-31) +[Full Changelog](https://github.com/Zulko/moviepy/compare/v0.2.3.4...v0.2.3.5) **Fixed bugs:** @@ -313,16 +409,16 @@ - Fix class name in AudioClip doc strings [\#488](https://github.com/Zulko/moviepy/pull/488) ([withpower](https://github.com/withpower)) - convert POpen stderr.read to communicate [\#487](https://github.com/Zulko/moviepy/pull/487) ([earney](https://github.com/earney)) - add tests for find\_video\_period [\#486](https://github.com/Zulko/moviepy/pull/486) ([earney](https://github.com/earney)) -- refer to MoviePy as library \(was: module\) [\#484](https://github.com/Zulko/moviepy/pull/484) ([kerstin](https://github.com/kerstin)) -- include requirements file for docs [\#483](https://github.com/Zulko/moviepy/pull/483) ([kerstin](https://github.com/kerstin)) +- refer to MoviePy as library \(was: module\) [\#484](https://github.com/Zulko/moviepy/pull/484) ([keikoro](https://github.com/keikoro)) +- include requirements file for docs [\#483](https://github.com/Zulko/moviepy/pull/483) ([keikoro](https://github.com/keikoro)) - add test for issue 354; duration not set [\#478](https://github.com/Zulko/moviepy/pull/478) ([earney](https://github.com/earney)) - Issue 470, reading past audio file EOF [\#476](https://github.com/Zulko/moviepy/pull/476) ([earney](https://github.com/earney)) - Issue 285, error adding durations \(int and None\). [\#472](https://github.com/Zulko/moviepy/pull/472) ([earney](https://github.com/earney)) - Issue 359, fix default opt argument to work with imageio and ImageMagick [\#471](https://github.com/Zulko/moviepy/pull/471) ([earney](https://github.com/earney)) - Add tests for TextClip [\#469](https://github.com/Zulko/moviepy/pull/469) ([earney](https://github.com/earney)) - Issue 467; fix Nameerror with copy function. Added issue to tests.. [\#468](https://github.com/Zulko/moviepy/pull/468) ([earney](https://github.com/earney)) -- Small improvements to docs pages, docs usage [\#463](https://github.com/Zulko/moviepy/pull/463) ([kerstin](https://github.com/kerstin)) -- Fix mixed content [\#462](https://github.com/Zulko/moviepy/pull/462) ([kerstin](https://github.com/kerstin)) +- Small improvements to docs pages, docs usage [\#463](https://github.com/Zulko/moviepy/pull/463) ([keikoro](https://github.com/keikoro)) +- Fix mixed content [\#462](https://github.com/Zulko/moviepy/pull/462) ([keikoro](https://github.com/keikoro)) - fix Issue 368.. ValueError: Invalid value for quantizer: 'wu' [\#460](https://github.com/Zulko/moviepy/pull/460) ([earney](https://github.com/earney)) - add testing to verify the width,height \(size\) are correct. [\#459](https://github.com/Zulko/moviepy/pull/459) ([earney](https://github.com/earney)) - Adds `progress\_bar` option to `write\_audiofile\(\)` to complement \#380 [\#458](https://github.com/Zulko/moviepy/pull/458) ([tburrows13](https://github.com/tburrows13)) @@ -333,7 +429,7 @@ - add test for tools [\#450](https://github.com/Zulko/moviepy/pull/450) ([earney](https://github.com/earney)) - fix issue 448; AudioFileClip 90k tbr error [\#449](https://github.com/Zulko/moviepy/pull/449) ([earney](https://github.com/earney)) - add testing with travis-ci [\#447](https://github.com/Zulko/moviepy/pull/447) ([earney](https://github.com/earney)) -- fix YouTube embeds in docs [\#446](https://github.com/Zulko/moviepy/pull/446) ([kerstin](https://github.com/kerstin)) +- fix YouTube embeds in docs [\#446](https://github.com/Zulko/moviepy/pull/446) ([keikoro](https://github.com/keikoro)) - Move PR test to test\_PR.py file [\#444](https://github.com/Zulko/moviepy/pull/444) ([earney](https://github.com/earney)) - Test issue 407 \(video has a valid fps after concatenate function\) [\#443](https://github.com/Zulko/moviepy/pull/443) ([earney](https://github.com/earney)) - add test for PR306. [\#440](https://github.com/Zulko/moviepy/pull/440) ([earney](https://github.com/earney)) @@ -344,7 +440,7 @@ - test for issue \#145 [\#431](https://github.com/Zulko/moviepy/pull/431) ([earney](https://github.com/earney)) - fix PR \#413 . \(issue \#357\) [\#429](https://github.com/Zulko/moviepy/pull/429) ([earney](https://github.com/earney)) - fix issue 145. raise Exception when concatenate method != chain or c… [\#428](https://github.com/Zulko/moviepy/pull/428) ([earney](https://github.com/earney)) -- Readme improvements [\#425](https://github.com/Zulko/moviepy/pull/425) ([kerstin](https://github.com/kerstin)) +- Readme improvements [\#425](https://github.com/Zulko/moviepy/pull/425) ([keikoro](https://github.com/keikoro)) - `Colorclip` changed `col`\>`color` [\#424](https://github.com/Zulko/moviepy/pull/424) ([tburrows13](https://github.com/tburrows13)) - Revert "small recipe \(mirroring a video\)" [\#414](https://github.com/Zulko/moviepy/pull/414) ([Zulko](https://github.com/Zulko)) - fixes \#357. confusing error about coreader, when media file does not exist [\#413](https://github.com/Zulko/moviepy/pull/413) ([earney](https://github.com/earney)) diff --git a/Pipfile b/Pipfile new file mode 100644 index 000000000..b9a5a69ce --- /dev/null +++ b/Pipfile @@ -0,0 +1,14 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +moviepy = {editable = true, path = "."} + +[dev-packages] +pytest = "*" +"pathlib2" = "*" +scandir = "*" + +[requires] diff --git a/README.rst b/README.rst index 9d78b7fc6..45231467a 100644 --- a/README.rst +++ b/README.rst @@ -16,7 +16,7 @@ MoviePy MoviePy (full documentation_) is a Python library 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: +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 (or only Python 3.4+ from v.1.0). Here it is in action in an IPython notebook: .. image:: https://raw.githubusercontent.com/Zulko/moviepy/master/docs/demo_preview.jpeg :alt: [logo] @@ -42,6 +42,11 @@ 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... +Maintainers wanted! +------------------- + +As there are more and more people seeking support (320 open issues as of Sept. 2019!) and all the MoviePy maintainers seem busy, we'd love to hear about developers interested in giving a hand and solving some of the issues (especially the ones that affect you) or reviewing pull requests. Open an issue or contact us directly if you are interested. Thanks! + Installation ------------ @@ -100,7 +105,7 @@ For Windows users, before installing MoviePy by hand, go into the ``moviepy/conf .. code:: python IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\magick.exe" - + If you are using an older version of ImageMagick, keep in mind the name of the executable is not ``magick.exe`` but ``convert.exe``. In that case, the IMAGEMAGICK_BINARY property should be ``C:\\Program Files\\ImageMagick_VERSION\\convert.exe`` For Ubuntu 16.04LTS users, after installing MoviePy on the terminal, IMAGEMAGICK will not be detected by moviepy. This bug can be fixed. Modify the file in this directory: /etc/ImageMagick-6/policy.xml, comment out the statement . @@ -133,7 +138,7 @@ You can pass additional arguments to the documentation build, such as clean buil More information is available from the `Sphinx`_ documentation. -New in 0.2.4.0: Progress bars and messages with Proglog +New in 1.0.0: Progress bars and messages with Proglog ------------------------------------------------------- Non-backwards-compatible changes were introduced in 0.2.3.6 to @@ -182,18 +187,17 @@ MoviePy is open-source software originally written by Zulko_ and released under You can also discuss the project on Reddit_ or Gitter_. These are preferred over GitHub issues for usage questions and examples. -We have a list of labels used in our `Label Wiki`_. The 'Pull Requests' labels are well defined, and all PRs should fall under exactly one of these. The 'Issues' labels are less precise, and may not be a complete list. - Maintainers ----------- - Zulko_ (owner) - - `@tburrows13`_ - `@earney`_ -- Kay `@kerstin`_ - `@mbeacom`_ +- `@overdrivr`_ +- `@keikoro`_ +- `@ryanfox`_ .. MoviePy links @@ -228,5 +232,7 @@ Maintainers .. _Zulko: https://github.com/Zulko .. _`@tburrows13`: https://github.com/tburrows13 .. _`@earney`: https://github.com/earney -.. _`@kerstin`: https://github.com/kerstin .. _`@mbeacom`: https://github.com/mbeacom +.. _`@overdrivr`: https://github.com/overdrivr +.. _`@keikoro`: https://github.com/keikoro +.. _`@ryanfox`: https://github.com/ryanfox diff --git a/appveyor.yml b/appveyor.yml index d662ecef1..fa19fbdc5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,61 +1,20 @@ -# This file is used to configure the AppVeyor CI system, for testing on Windows machines. -# -# Code loosely based on https://github.com/ogrisel/python-appveyor-demo -# -# To test with AppVeyor: -# Register on appveyor.com with your GitHub account. -# Create a new appveyor project, using the GitHub details. -# Ideally, configure notifications to post back to GitHub. (Untested) +image: Visual Studio 2017 environment: global: - # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the - # /E:ON and /V:ON options are not enabled in the batch script interpreter - # See: http://stackoverflow.com/a/13751649/163740 - CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" - + IMAGE_MAGICK_INSTALL_DIR: c://ImageMagick matrix: - - # MoviePy supports Python 2.7 and 3.4 onwards. - # Strategy: - # Test the latest known patch in each version - # Test the oldest and the newest 32 bit release. 64-bit otherwise. - - - PYTHON: "C:\\Python27-x64" - PYTHON_VERSION: "2.7.13" - PYTHON_ARCH: "64" - MINICONDA: C:\Miniconda - CONDA_INSTALL: "numpy" - - - PYTHON: "C:\\Python34-x64" - PYTHON_VERSION: "3.4.5" - PYTHON_ARCH: "64" - MINICONDA: C:\Miniconda3-x64 - CONDA_INSTALL: "numpy" - - PYTHON: "C:\\Python35-x64" - PYTHON_VERSION: "3.5.3" PYTHON_ARCH: "64" - MINICONDA: C:\Miniconda35-x64 - CONDA_INSTALL: "numpy" + ARCH: x64 - PYTHON: "C:\\Python36-x64" - PYTHON_VERSION: "3.6.2" PYTHON_ARCH: "64" - MINICONDA: C:\Miniconda36-x64 - CONDA_INSTALL: "numpy" + ARCH: x64 - - PYTHON: "C:\\Python27" - PYTHON_VERSION: "2.7.13" - PYTHON_ARCH: "32" - MINICONDA: C:\Miniconda - CONDA_INSTALL: "numpy" - - - PYTHON: "C:\\Python34" - PYTHON_VERSION: "3.6.2" - PYTHON_ARCH: "32" - MINICONDA: C:\Miniconda36 - CONDA_INSTALL: "numpy" + - PYTHON: "C:\\Python37-x64" + PYTHON_ARCH: "64" + ARCH: x64 install: # If there is a newer build queued for the same PR, cancel this one. @@ -67,75 +26,46 @@ install: https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` throw "There are newer queued builds for this pull request, failing early." } - - # Dump some debugging information about the machine. - # - ECHO "Filesystem root:" - # - ps: "ls \"C:/\"" - # - # - ECHO "Installed SDKs:" - # - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" - # - # - ECHO "Installed projects:" - # - ps: "ls \"C:\\projects\"" - # - ps: "ls \"C:\\projects\\moviepy\"" - - # - ECHO "Environment Variables" - # - set - # Prepend desired Python to the PATH of this build (this cannot be # done from inside the powershell script as it would require to restart # the parent CMD process). - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - # Prepare Miniconda. - - "ECHO Miniconda is installed in %MINICONDA%, and will be used to install %CONDA_INSTALL%" + - pip install --upgrade pip --user + - pip install pipenv - - "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%PATH%" - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda + # Find latest image magick version by parsing website - # Avoid warning from conda info. - - conda install -q -n root _license - # Dump the setup for debugging. - - conda info -a + - python find_latest_imagemagick_version.py > temp.txt + - set /p IMAGE_MAGICK_VERSION==7.0 have problems - executables changed names. + # Assume 64-bit. Need to change to x86 for 32-bit. + - curl https://imagemagick.org/download/binaries/ImageMagick-%IMAGE_MAGICK_VERSION%-%ARCH%-static.exe -o ImageMagick.exe - # Upgrade to the latest version of pip to avoid it displaying warnings - # about it being out of date. - - pip install --disable-pip-version-check --user --upgrade pip - - pip install --user --upgrade setuptools + # Install ImageMagick, telling InnoSetup to not open a window and change default install dir + - ImageMagick.exe /SILENT /SP /DIR="%IMAGE_MAGICK_INSTALL_DIR%" - - # Install ImageMagick (which also installs ffmpeg.) - # This installation process is a big fragile, as new releases are issued, but no Conda package exists yet. - - "ECHO Downloading ImageMagick" - # Versions >=7.0 have problems - executables changed names. - # Assume 64-bit. Need to change to x86 for 32-bit. - # The available version at this site changes - each time it needs to be corrected in four places - # in the next few lines. - - curl -fskLO ftp://ftp.fifi.org/pub/ImageMagick/binaries/ImageMagick-6.9.9-5-Q16-x64-static.exe - - "ECHO Installing ImageMagick" - - "ImageMagick-6.9.9-5-Q16-x64-static.exe /verySILENT /SP" - - set IMAGEMAGICK_BINARY=c:\\Program Files\\ImageMagick-6.9.9-Q16\\convert.exe - - set FFMPEG_BINARY=c:\\Program Files\\ImageMagick-6.9.9-Q16\\ffmpeg.exe - - # Check that we have the expected set-up. - - "ECHO We specified %PYTHON_VERSION% win%PYTHON_ARCH%" - - "python --version" - - "python -c \"import struct; print('Architecture is win'+str(struct.calcsize('P') * 8))\"" + # Inspect contents and set env vars + - dir "%IMAGE_MAGICK_INSTALL_DIR%" + - set IMAGEMAGICK_BINARY=%IMAGE_MAGICK_INSTALL_DIR%//convert.exe + - echo %IMAGEMAGICK_BINARY% + - set FMPEG_BINARY="%IMAGE_MAGICK_INSTALL_DIR%//ffmpeg.exe" + - echo %FMPEG_BINARY% build_script: - + # Install all dependencies, including dev dependencies + - pipenv install --dev # Build the compiled extension - - "%CMD_IN_ENV% python c:\\projects\\moviepy\\setup.py build" + #- "%CMD_IN_ENV% python c:\\projects\\moviepy\\setup.py build" test_script: - # Run the project tests - - "%CMD_IN_ENV% python c:\\projects\\moviepy\\setup.py test" + - pipenv run pytest # TODO: Support the post-test generation of binaries - Pending a version number that is supported (e.g. 0.3.0) # diff --git a/docs/getting_started/compositing.rst b/docs/getting_started/compositing.rst index 736cf8a2b..082b576bb 100644 --- a/docs/getting_started/compositing.rst +++ b/docs/getting_started/compositing.rst @@ -8,7 +8,7 @@ Video composition, also known as non-linear editing, is the fact of playing seve .. raw:: html
-
diff --git a/docs/install.rst b/docs/install.rst index 70f6bef4d..ebd99be03 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -29,12 +29,14 @@ Other 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. -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 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 `magick`. It should look like this :: - IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\convert.exe" + IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\magick.exe" You can also set the IMAGEMAGICK_BINARY environment variable See ``moviepy/config_defaults.py`` for details. +If you are using an older version of ImageMagick, keep in mind the name of the executable is not ``magick.exe`` but ``convert.exe``. In that case, the IMAGEMAGICK_BINARY property should be ``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*). 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. diff --git a/find_latest_imagemagick_version.py b/find_latest_imagemagick_version.py new file mode 100644 index 000000000..00cde14ef --- /dev/null +++ b/find_latest_imagemagick_version.py @@ -0,0 +1,21 @@ +from urllib import request +import re + +url = "https://legacy.imagemagick.org/script/index.php" + +'''This little script parses url above to extract latest image magick version +(major version 6.9), to feed it into CI system. Not the best way for reproducible +builds, but it's preferred for now over storing imagemagick installer into the +git repository +''' + +response = request.urlopen(url) +html = response.read().decode('utf-8') +r = re.compile("6\.9\.[0-9]+\-[0-9]+") +version = r.findall(html) +if len(version) == 0: + raise ValueError("Could not find latest legacy 6.9.X-Y ImageMagick version from {}".format(url)) +version = version[0] +# Append Q16 build +version += '-Q16' +print(version) diff --git a/media/afterimage.png b/media/afterimage.png new file mode 100644 index 000000000..238302534 Binary files /dev/null and b/media/afterimage.png differ diff --git a/media/big_buck_bunny_0_30.webm b/media/big_buck_bunny_0_30.webm new file mode 100644 index 000000000..94e323709 Binary files /dev/null and b/media/big_buck_bunny_0_30.webm differ diff --git a/media/big_buck_bunny_432_433.webm b/media/big_buck_bunny_432_433.webm new file mode 100644 index 000000000..580efdc32 Binary files /dev/null and b/media/big_buck_bunny_432_433.webm differ diff --git a/media/crunching.mp3 b/media/crunching.mp3 new file mode 100644 index 000000000..66fb8c253 Binary files /dev/null and b/media/crunching.mp3 differ diff --git a/media/fire2.mp4 b/media/fire2.mp4 new file mode 100644 index 000000000..80a8d99c0 Binary files /dev/null and b/media/fire2.mp4 differ diff --git a/media/matplotlib_demo1.png b/media/matplotlib_demo1.png new file mode 100644 index 000000000..1d282197f Binary files /dev/null and b/media/matplotlib_demo1.png differ diff --git a/media/pigs_in_a_polka.gif b/media/pigs_in_a_polka.gif new file mode 100644 index 000000000..0005ebfc1 Binary files /dev/null and b/media/pigs_in_a_polka.gif differ diff --git a/media/python_logo.png b/media/python_logo.png new file mode 100644 index 000000000..4687ffc5b Binary files /dev/null and b/media/python_logo.png differ diff --git a/media/python_logo_upside_down.png b/media/python_logo_upside_down.png new file mode 100644 index 000000000..609d680d7 Binary files /dev/null and b/media/python_logo_upside_down.png differ diff --git a/media/subtitles1.srt b/media/subtitles1.srt new file mode 100644 index 000000000..fe57e4332 --- /dev/null +++ b/media/subtitles1.srt @@ -0,0 +1,24 @@ +0 +00:00:00,000 --> 00:00:04,000 +Red! + +1 +00:00:05,000 --> 00:00:09,000 +More Red! + +2 +00:00:10,000 --> 00:00:14,000 +Green! + +3 +00:00:15,000 --> 00:00:19,000 +More Green! + +4 +00:00:20,000 --> 00:00:24,000 +Blue + +5 +00:00:25,000 --> 00:00:29,000 +More Blue! + diff --git a/media/traj.txt b/media/traj.txt new file mode 100644 index 000000000..144190fc4 --- /dev/null +++ b/media/traj.txt @@ -0,0 +1,11 @@ +# t(ms) x y +0 547 104 +1000 210 78 +2000 280 85 +3000 337 93 +4000 354 78 +5000 381 68 +6000 382 67 +7000 382 67 +8000 372 64 +9000 372 65 diff --git a/media/vacation_2017.jpg b/media/vacation_2017.jpg new file mode 100644 index 000000000..b28686c2a Binary files /dev/null and b/media/vacation_2017.jpg differ diff --git a/media/video_with_failing_audio.mp4 b/media/video_with_failing_audio.mp4 new file mode 100644 index 000000000..0c9c20d4a Binary files /dev/null and b/media/video_with_failing_audio.mp4 differ diff --git a/moviepy/Clip.py b/moviepy/Clip.py index da1ddd4f4..007e6c3a6 100644 --- a/moviepy/Clip.py +++ b/moviepy/Clip.py @@ -33,7 +33,7 @@ class Clip: end: When the clip is included in a composition, time of the - composition at which the clip starts playing (in seconds). + composition at which the clip stops playing (in seconds). duration: Duration of the clip (in seconds). Some clips are infinite, in diff --git a/moviepy/audio/io/AudioFileClip.py b/moviepy/audio/io/AudioFileClip.py index 74410c551..8ab3ad81b 100644 --- a/moviepy/audio/io/AudioFileClip.py +++ b/moviepy/audio/io/AudioFileClip.py @@ -13,45 +13,45 @@ class AudioFileClip(AudioClip): read and stored in memory. this portion includes frames before and after the last frames read, so that it is fast to read the sound backward and forward. - + Parameters ------------ - + filename Either a soundfile name (of any extension supported by ffmpeg) or an array representing a sound. If the soundfile is not a .wav, it will be converted to .wav first, using the ``fps`` and - ``bitrate`` arguments. - + ``bitrate`` arguments. + buffersize: Size to load in memory (in number of frames) - + Attributes ------------ - + nbytes Number of bits per frame of the original audio file. - + fps Number of frames per second in the audio file - + buffersize See Parameters. - + 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. + However, coreaders must be closed separately. - + Examples ---------- - + >>> snd = AudioFileClip("song.wav") >>> snd.close() >>> snd = AudioFileClip("song.mp3", fps = 44100) @@ -60,13 +60,13 @@ class AudioFileClip(AudioClip): >>> snd.close() >>> with AudioFileClip(mySoundArray, fps=44100) as snd: # from a numeric array >>> pass # Close is implicitly performed by context manager. - + """ def __init__(self, filename, buffersize=200000, nbytes=2, fps=44100): AudioClip.__init__(self) - + self.filename = filename self.reader = FFMPEG_AudioReader(filename, fps=fps, nbytes=nbytes, buffersize=buffersize) @@ -89,3 +89,6 @@ def close(self): if self.reader: self.reader.close_proc() self.reader = None + + def __del__(self): + self.close() diff --git a/moviepy/audio/io/ffmpeg_audiowriter.py b/moviepy/audio/io/ffmpeg_audiowriter.py index 5f704250e..7e1538f1c 100644 --- a/moviepy/audio/io/ffmpeg_audiowriter.py +++ b/moviepy/audio/io/ffmpeg_audiowriter.py @@ -117,7 +117,7 @@ def write_frames(self, frames_array): raise IOError(error) def close(self): - if self.proc: + if hasattr(self, 'proc') and self.proc: self.proc.stdin.close() self.proc.stdin = None if self.proc.stderr is not None: @@ -157,7 +157,7 @@ def ffmpeg_audiowrite(clip, filename, fps, nbytes, buffersize, else: logfile = None logger = proglog.default_bar_logger(logger) - logger(message="MoviePy - Writing audio in %s") + logger(message="MoviePy - Writing audio in %s" % filename) writer = FFMPEG_AudioWriter(filename, fps, nbytes, clip.nchannels, codec=codec, bitrate=bitrate, logfile=logfile, @@ -173,4 +173,4 @@ def ffmpeg_audiowrite(clip, filename, fps, nbytes, buffersize, if write_logfile: logfile.close() - logger(message="MoviePy - Done.") \ No newline at end of file + logger(message="MoviePy - Done.") diff --git a/moviepy/audio/io/readers.py b/moviepy/audio/io/readers.py index de338fbfe..6225356c1 100644 --- a/moviepy/audio/io/readers.py +++ b/moviepy/audio/io/readers.py @@ -63,8 +63,6 @@ def __init__(self, filename, buffersize, print_infos=False, self.initialize() self.buffer_around(1) - - def initialize(self, starttime = 0): """ Opens the file, creates the pipe. """ diff --git a/moviepy/config.py b/moviepy/config.py index 4743ca571..0f1741031 100644 --- a/moviepy/config.py +++ b/moviepy/config.py @@ -1,9 +1,9 @@ import os import subprocess as sp from .compat import DEVNULL - + if os.name == 'nt': - try: + try: import winreg as wr # py3k except ImportError: import _winreg as wr # py2k @@ -11,24 +11,24 @@ from .config_defaults import (FFMPEG_BINARY, IMAGEMAGICK_BINARY) def try_cmd(cmd): - try: - popen_params = { "stdout": sp.PIPE, - "stderr": sp.PIPE, - "stdin": DEVNULL - } - - - # This was added so that no extra unwanted window opens on windows - # when the child process is created - if os.name == "nt": - popen_params["creationflags"] = 0x08000000 - - proc = sp.Popen(cmd, **popen_params) - proc.communicate() - except Exception as err: - return False, err - else: - return True, None + try: + popen_params = { + "stdout": sp.PIPE, + "stderr": sp.PIPE, + "stdin": DEVNULL + } + + # This was added so that no extra unwanted window opens on windows + # when the child process is created + if os.name == "nt": + popen_params["creationflags"] = 0x08000000 + + proc = sp.Popen(cmd, **popen_params) + proc.communicate() + except Exception as err: + return False, err + else: + return True, None if FFMPEG_BINARY=='ffmpeg-imageio': from imageio.plugins.ffmpeg import get_exe @@ -50,7 +50,7 @@ def try_cmd(cmd): " - The path specified for the ffmpeg binary might be wrong") if IMAGEMAGICK_BINARY=='auto-detect': - if os.name == 'nt': + if os.name == 'nt': try: key = wr.OpenKey(wr.HKEY_LOCAL_MACHINE, 'SOFTWARE\\ImageMagick\\Current') IMAGEMAGICK_BINARY = wr.QueryValueEx(key, 'BinPath')[0] + r"\convert.exe" @@ -62,6 +62,20 @@ def try_cmd(cmd): else: IMAGEMAGICK_BINARY = 'unset' else: + if not os.path.exists(IMAGEMAGICK_BINARY): + raise IOError( + "ImageMagick binary cannot be found at {}".format( + IMAGEMAGICK_BINARY + ) + ) + + if not os.path.isfile(IMAGEMAGICK_BINARY): + raise IOError( + "ImageMagick binary found at {} is not a file".format( + IMAGEMAGICK_BINARY + ) + ) + success, err = try_cmd([IMAGEMAGICK_BINARY]) if not success: raise IOError("%s - The path specified for the ImageMagick binary might " @@ -69,7 +83,7 @@ def try_cmd(cmd): def get_setting(varname): - """ Returns the value of a configuration variable. """ + """ Returns the value of a configuration variable. """ gl = globals() if varname not in gl.keys(): raise ValueError("Unknown setting %s"%varname) diff --git a/moviepy/config_defaults.py b/moviepy/config_defaults.py index a412071b0..d88e1f7cb 100644 --- a/moviepy/config_defaults.py +++ b/moviepy/config_defaults.py @@ -42,13 +42,13 @@ IMAGEMAGICK_BINARY For linux users, 'convert' should be fine. For Windows users, you must specify the path to the ImageMagick - 'convert' binary. For instance: + 'magick' binary. For instance: - IMAGEMAGICK_BINARY = r"C:\Program Files\ImageMagick-6.8.8-Q16\convert.exe" + IMAGEMAGICK_BINARY = r"C:\Program Files\ImageMagick-6.8.8-Q16\magick.exe" """ import os FFMPEG_BINARY = os.getenv('FFMPEG_BINARY', 'ffmpeg-imageio') -IMAGEMAGICK_BINARY = os.getenv('IMAGEMAGICK_BINARY', 'auto-detect') \ No newline at end of file +IMAGEMAGICK_BINARY = os.getenv('IMAGEMAGICK_BINARY', 'auto-detect') diff --git a/moviepy/editor.py b/moviepy/editor.py index c5362e430..f634f3d21 100644 --- a/moviepy/editor.py +++ b/moviepy/editor.py @@ -18,13 +18,16 @@ # file, but this would make the loading of moviepy slower. import os +import sys # Downloads ffmpeg if it isn't already installed import imageio # Checks to see if the user has set a place for their own version of ffmpeg -# Replaced with 'imageio-ffmpeg' package -# if os.getenv('FFMPEG_BINARY', 'ffmpeg-imageio') == 'ffmpeg-imageio': -# imageio.plugins.ffmpeg.download() + +if os.getenv('FFMPEG_BINARY', 'ffmpeg-imageio') == 'ffmpeg-imageio': + if sys.version_info < (3, 4): + #uses an old version of imageio with ffmpeg.download. + imageio.plugins.ffmpeg.download() # Clips from .video.io.VideoFileClip import VideoFileClip diff --git a/moviepy/version.py b/moviepy/version.py index dd386d742..5c4105cd3 100644 --- a/moviepy/version.py +++ b/moviepy/version.py @@ -1 +1 @@ -__version__ = "0.2.4.0" +__version__ = "1.0.1" diff --git a/moviepy/video/VideoClip.py b/moviepy/video/VideoClip.py index fd44d1d45..c50247123 100644 --- a/moviepy/video/VideoClip.py +++ b/moviepy/video/VideoClip.py @@ -465,8 +465,15 @@ def write_gif(self, filename, fps=None, program='imageio', dispose=dispose, colors=colors, logger=logger) else: + # convert imageio opt variable to something that can be used with + # ImageMagick + opt1 = opt + if opt1 == 'nq': + opt1 ='optimizeplus' + else: + opt1 ='OptimizeTransparency' write_gif(self, filename, fps=fps, program=program, - opt=opt, fuzz=fuzz, verbose=verbose, loop=loop, + opt=opt1, fuzz=fuzz, verbose=verbose, loop=loop, dispose=dispose, colors=colors, logger=logger) diff --git a/moviepy/video/io/ffmpeg_reader.py b/moviepy/video/io/ffmpeg_reader.py index 48c88464d..268d51b1e 100644 --- a/moviepy/video/io/ffmpeg_reader.py +++ b/moviepy/video/io/ffmpeg_reader.py @@ -196,6 +196,9 @@ def close(self): if hasattr(self, 'lastread'): del self.lastread + def __del__(self): + self.close() + def ffmpeg_read_image(filename, with_mask=True): """ Read an image file (PNG, BMP, JPEG...). @@ -256,10 +259,9 @@ def ffmpeg_parse_infos(filename, print_infos=False, check_duration=True, popen_params["creationflags"] = 0x08000000 proc = sp.Popen(cmd, **popen_params) + (output, error) = proc.communicate() + infos = error.decode('utf8') - proc.stdout.readline() - proc.terminate() - infos = proc.stderr.read().decode('utf8') del proc if print_infos: diff --git a/moviepy/video/io/ffmpeg_tools.py b/moviepy/video/io/ffmpeg_tools.py index 37611b14f..523172f16 100644 --- a/moviepy/video/io/ffmpeg_tools.py +++ b/moviepy/video/io/ffmpeg_tools.py @@ -33,8 +33,8 @@ def ffmpeg_extract_subclip(filename, t1, t2, targetname=None): targetname = "%sSUB%d_%d.%s" % (name, T1, T2, ext) cmd = [get_setting("FFMPEG_BINARY"),"-y", - "-i", filename, "-ss", "%0.2f"%t1, + "-i", filename, "-t", "%0.2f"%(t2-t1), "-vcodec", "copy", "-acodec", "copy", targetname] diff --git a/moviepy/video/io/gif_writers.py b/moviepy/video/io/gif_writers.py index 87beee7a9..40965f3a9 100644 --- a/moviepy/video/io/gif_writers.py +++ b/moviepy/video/io/gif_writers.py @@ -55,8 +55,8 @@ def write_gif_with_tempfiles(clip, filename, fps=None, program= 'ImageMagick', "-loop" , "%d"%loop, "%s_GIFTEMP*.png"%fileName, "-coalesce", - "-layers", "%s"%opt, "-fuzz", "%02d"%fuzz + "%", + "-layers", "%s"%opt, ]+(["-colors", "%d"%colors] if colors is not None else [])+[ filename] @@ -203,8 +203,8 @@ def write_gif(clip, filename, fps=None, program= 'ImageMagick', if opt: - cmd3 = [get_setting("IMAGEMAGICK_BINARY"), '-', '-layers', opt, - '-fuzz', '%d'%fuzz+'%' + cmd3 = [get_setting("IMAGEMAGICK_BINARY"), '-', + '-fuzz', '%d'%fuzz+'%', '-layers', opt ]+(["-colors", "%d"%colors] if colors is not None else [])+[ filename] diff --git a/pipfile.lock b/pipfile.lock new file mode 100644 index 000000000..11f24b07e --- /dev/null +++ b/pipfile.lock @@ -0,0 +1,243 @@ +{ + "_meta": { + "hash": { + "sha256": "0c9805a9f43b881b56d92beec72aca2653fd84d4a0fb5f74c0097e23e5d852e9" + }, + "pipfile-spec": 6, + "requires": {}, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "certifi": { + "hashes": [ + "sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5", + "sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae" + ], + "version": "==2019.3.9" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "decorator": { + "hashes": [ + "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", + "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" + ], + "version": "==4.4.0" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "imageio": { + "hashes": [ + "sha256:1a2bbbb7cd38161340fa3b14d806dfbf914abf3ee6fd4592af2afb87d049f209", + "sha256:42e65aadfc3d57a1043615c92bdf6319b67589e49a0aae2b985b82144aceacad" + ], + "version": "==2.5.0" + }, + "imageio-ffmpeg": { + "hashes": [ + "sha256:14efef5c82fdc3d314d56cbb4a9302e478afd9e1bdc3da7a1f0a67f42a5e3ec8", + "sha256:2beacb11b121440cfd0bc0caf80da54a3729956002707251ab8e26d3e03933a4", + "sha256:646cc63da4b6a955de5e30fbc63edb7c5692ac94fc100f4c71a7c122506122c6", + "sha256:d0eda59e2243375ca442e9428b299892425faf73e2e5f173d79de4362661dc50", + "sha256:dd3d4380d6e413819fef9f64f184cdc7e59cba88094383727bcf7ea5bb1bed99" + ], + "version": "==0.2.0" + }, + "moviepy": { + "editable": true, + "path": "." + }, + "numpy": { + "hashes": [ + "sha256:1980f8d84548d74921685f68096911585fee393975f53797614b34d4f409b6da", + "sha256:22752cd809272671b273bb86df0f505f505a12368a3a5fc0aa811c7ece4dfd5c", + "sha256:23cc40313036cffd5d1873ef3ce2e949bdee0646c5d6f375bf7ee4f368db2511", + "sha256:2b0b118ff547fecabc247a2668f48f48b3b1f7d63676ebc5be7352a5fd9e85a5", + "sha256:3a0bd1edf64f6a911427b608a894111f9fcdb25284f724016f34a84c9a3a6ea9", + "sha256:3f25f6c7b0d000017e5ac55977a3999b0b1a74491eacb3c1aa716f0e01f6dcd1", + "sha256:4061c79ac2230594a7419151028e808239450e676c39e58302ad296232e3c2e8", + "sha256:560ceaa24f971ab37dede7ba030fc5d8fa173305d94365f814d9523ffd5d5916", + "sha256:62be044cd58da2a947b7e7b2252a10b42920df9520fc3d39f5c4c70d5460b8ba", + "sha256:6c692e3879dde0b67a9dc78f9bfb6f61c666b4562fd8619632d7043fb5b691b0", + "sha256:6f65e37b5a331df950ef6ff03bd4136b3c0bbcf44d4b8e99135d68a537711b5a", + "sha256:7a78cc4ddb253a55971115f8320a7ce28fd23a065fc33166d601f51760eecfa9", + "sha256:80a41edf64a3626e729a62df7dd278474fc1726836552b67a8c6396fd7e86760", + "sha256:893f4d75255f25a7b8516feb5766c6b63c54780323b9bd4bc51cdd7efc943c73", + "sha256:972ea92f9c1b54cc1c1a3d8508e326c0114aaf0f34996772a30f3f52b73b942f", + "sha256:9f1d4865436f794accdabadc57a8395bd3faa755449b4f65b88b7df65ae05f89", + "sha256:9f4cd7832b35e736b739be03b55875706c8c3e5fe334a06210f1a61e5c2c8ca5", + "sha256:adab43bf657488300d3aeeb8030d7f024fcc86e3a9b8848741ea2ea903e56610", + "sha256:bd2834d496ba9b1bdda3a6cf3de4dc0d4a0e7be306335940402ec95132ad063d", + "sha256:d20c0360940f30003a23c0adae2fe50a0a04f3e48dc05c298493b51fd6280197", + "sha256:d3b3ed87061d2314ff3659bb73896e622252da52558f2380f12c421fbdee3d89", + "sha256:dc235bf29a406dfda5790d01b998a1c01d7d37f449128c0b1b7d1c89a84fae8b", + "sha256:fb3c83554f39f48f3fa3123b9c24aecf681b1c289f9334f8215c1d3c8e2f6e5b" + ], + "version": "==1.16.2" + }, + "pillow": { + "hashes": [ + "sha256:051de330a06c99d6f84bcf582960487835bcae3fc99365185dc2d4f65a390c0e", + "sha256:0ae5289948c5e0a16574750021bd8be921c27d4e3527800dc9c2c1d2abc81bf7", + "sha256:0b1efce03619cdbf8bcc61cfae81fcda59249a469f31c6735ea59badd4a6f58a", + "sha256:163136e09bd1d6c6c6026b0a662976e86c58b932b964f255ff384ecc8c3cefa3", + "sha256:18e912a6ccddf28defa196bd2021fe33600cbe5da1aa2f2e2c6df15f720b73d1", + "sha256:24ec3dea52339a610d34401d2d53d0fb3c7fd08e34b20c95d2ad3973193591f1", + "sha256:267f8e4c0a1d7e36e97c6a604f5b03ef58e2b81c1becb4fccecddcb37e063cc7", + "sha256:3273a28734175feebbe4d0a4cde04d4ed20f620b9b506d26f44379d3c72304e1", + "sha256:4c678e23006798fc8b6f4cef2eaad267d53ff4c1779bd1af8725cc11b72a63f3", + "sha256:4d4bc2e6bb6861103ea4655d6b6f67af8e5336e7216e20fff3e18ffa95d7a055", + "sha256:505738076350a337c1740a31646e1de09a164c62c07db3b996abdc0f9d2e50cf", + "sha256:5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f", + "sha256:5d95cb9f6cced2628f3e4de7e795e98b2659dfcc7176ab4a01a8b48c2c2f488f", + "sha256:7eda4c737637af74bac4b23aa82ea6fbb19002552be85f0b89bc27e3a762d239", + "sha256:801ddaa69659b36abf4694fed5aa9f61d1ecf2daaa6c92541bbbbb775d97b9fe", + "sha256:825aa6d222ce2c2b90d34a0ea31914e141a85edefc07e17342f1d2fdf121c07c", + "sha256:9c215442ff8249d41ff58700e91ef61d74f47dfd431a50253e1a1ca9436b0697", + "sha256:a3d90022f2202bbb14da991f26ca7a30b7e4c62bf0f8bf9825603b22d7e87494", + "sha256:a631fd36a9823638fe700d9225f9698fb59d049c942d322d4c09544dc2115356", + "sha256:a6523a23a205be0fe664b6b8747a5c86d55da960d9586db039eec9f5c269c0e6", + "sha256:a756ecf9f4b9b3ed49a680a649af45a8767ad038de39e6c030919c2f443eb000", + "sha256:b117287a5bdc81f1bac891187275ec7e829e961b8032c9e5ff38b70fd036c78f", + "sha256:ba04f57d1715ca5ff74bb7f8a818bf929a204b3b3c2c2826d1e1cc3b1c13398c", + "sha256:cd878195166723f30865e05d87cbaf9421614501a4bd48792c5ed28f90fd36ca", + "sha256:cee815cc62d136e96cf76771b9d3eb58e0777ec18ea50de5cfcede8a7c429aa8", + "sha256:d1722b7aa4b40cf93ac3c80d3edd48bf93b9208241d166a14ad8e7a20ee1d4f3", + "sha256:d7c1c06246b05529f9984435fc4fa5a545ea26606e7f450bdbe00c153f5aeaad", + "sha256:e9c8066249c040efdda84793a2a669076f92a301ceabe69202446abb4c5c5ef9", + "sha256:f227d7e574d050ff3996049e086e1f18c7bd2d067ef24131e50a1d3fe5831fbc", + "sha256:fc9a12aad714af36cf3ad0275a96a733526571e52710319855628f476dcb144e" + ], + "version": "==5.4.1" + }, + "proglog": { + "hashes": [ + "sha256:d8c4ccbf2138e0c5e3f3fc0d80dc51d7e69dcfe8bfde4cacb566725092a5b18d" + ], + "version": "==0.1.9" + }, + "requests": { + "hashes": [ + "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", + "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" + ], + "version": "==2.21.0" + }, + "tqdm": { + "hashes": [ + "sha256:d385c95361699e5cf7622485d9b9eae2d4864b21cd5a2374a9c381ffed701021", + "sha256:e22977e3ebe961f72362f6ddfb9197cc531c9737aaf5f607ef09740c849ecd05" + ], + "version": "==4.31.1" + }, + "urllib3": { + "hashes": [ + "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39", + "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22" + ], + "version": "==1.24.1" + } + }, + "develop": { + "atomicwrites": { + "hashes": [ + "sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4", + "sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6" + ], + "version": "==1.3.0" + }, + "attrs": { + "hashes": [ + "sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79", + "sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399" + ], + "version": "==19.1.0" + }, + "colorama": { + "hashes": [ + "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", + "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + ], + "markers": "sys_platform == 'win32'", + "version": "==0.4.1" + }, + "more-itertools": { + "hashes": [ + "sha256:0125e8f60e9e031347105eb1682cef932f5e97d7b9a1a28d9bf00c22a5daef40", + "sha256:590044e3942351a1bdb1de960b739ff4ce277960f2425ad4509446dbace8d9d1" + ], + "markers": "python_version > '2.7'", + "version": "==6.0.0" + }, + "pathlib2": { + "hashes": [ + "sha256:25199318e8cc3c25dcb45cbe084cc061051336d5a9ea2a12448d3d8cb748f742", + "sha256:5887121d7f7df3603bca2f710e7219f3eca0eb69e0b7cc6e0a022e155ac931a7" + ], + "index": "pypi", + "version": "==2.3.3" + }, + "pluggy": { + "hashes": [ + "sha256:19ecf9ce9db2fce065a7a0586e07cfb4ac8614fe96edf628a264b1c70116cf8f", + "sha256:84d306a647cc805219916e62aab89caa97a33a1dd8c342e87a37f91073cd4746" + ], + "version": "==0.9.0" + }, + "py": { + "hashes": [ + "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", + "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" + ], + "version": "==1.8.0" + }, + "pytest": { + "hashes": [ + "sha256:592eaa2c33fae68c7d75aacf042efc9f77b27c08a6224a4f59beab8d9a420523", + "sha256:ad3ad5c450284819ecde191a654c09b0ec72257a2c711b9633d677c71c9850c4" + ], + "index": "pypi", + "version": "==4.3.1" + }, + "scandir": { + "hashes": [ + "sha256:2586c94e907d99617887daed6c1d102b5ca28f1085f90446554abf1faf73123e", + "sha256:2ae41f43797ca0c11591c0c35f2f5875fa99f8797cb1a1fd440497ec0ae4b022", + "sha256:2b8e3888b11abb2217a32af0766bc06b65cc4a928d8727828ee68af5a967fa6f", + "sha256:2c712840c2e2ee8dfaf36034080108d30060d759c7b73a01a52251cc8989f11f", + "sha256:4d4631f6062e658e9007ab3149a9b914f3548cb38bfb021c64f39a025ce578ae", + "sha256:67f15b6f83e6507fdc6fca22fedf6ef8b334b399ca27c6b568cbfaa82a364173", + "sha256:7d2d7a06a252764061a020407b997dd036f7bd6a175a5ba2b345f0a357f0b3f4", + "sha256:8c5922863e44ffc00c5c693190648daa6d15e7c1207ed02d6f46a8dcc2869d32", + "sha256:92c85ac42f41ffdc35b6da57ed991575bdbe69db895507af88b9f499b701c188", + "sha256:b24086f2375c4a094a6b51e78b4cf7ca16c721dcee2eddd7aa6494b42d6d519d", + "sha256:cb925555f43060a1745d0a321cca94bcea927c50114b623d73179189a4e100ac" + ], + "index": "pypi", + "version": "==1.10.0" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + } + } +} diff --git a/setup.py b/setup.py index f04036626..ca7eef519 100644 --- a/setup.py +++ b/setup.py @@ -63,7 +63,9 @@ def run_tests(self): # Define the requirements for specific execution needs. requires = [ 'decorator>=4.0.2,<5.0', - 'imageio>=2.1.2,<3.0', + "imageio>=2.5,<3.0; python_version>='3.4'", + "imageio>=2.0,<2.5; python_version<'3.4'", + "imageio_ffmpeg>=0.2.0; python_version>='3.4'", 'tqdm>=4.11.2,<5.0', 'numpy', 'requests>=2.8.1,<3.0', @@ -90,6 +92,7 @@ def run_tests(self): ] test_reqs = [ + 'coverage<5.0', 'coveralls>=1.1,<2.0', 'pytest-cov>=2.5.1,<3.0', 'pytest>=3.0.0,<4.0', @@ -133,7 +136,7 @@ def run_tests(self): 'Topic :: Multimedia :: Video :: Conversion', ], keywords='video editing audio compositing ffmpeg', - packages=find_packages(exclude='docs'), + packages=find_packages(exclude=['docs', 'tests']), cmdclass=cmdclass, command_options={ 'build_docs': { diff --git a/tests/download_media.py b/tests/download_media.py deleted file mode 100644 index 89ef7cc19..000000000 --- a/tests/download_media.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -"""Handle retrieving media assets for testing.""" -import os - -from moviepy.video.io.downloader import download_webfile - - -def download_url(url, filename): - """Download a file.""" - if not os.path.exists(filename): - print('Downloading {} ...'.format(filename)) - download_webfile(url, filename) - print('Downloading complete.') - -def download_youtube_video(youtube_id, filename): - """Download a video from youtube.""" - # FYI.. travis-ci doesn't like youtube-dl - download_url(youtube_id, filename) - -def download(): - """Initiate the media asset downloads.""" - if not os.path.exists('media'): - os.mkdir('media') - - # Define url prefix and path for all media assets. - github_prefix = 'https://github.com/earney/moviepy_media/raw/master/tests/' - output = 'media/{}' - urls = ['/images/python_logo.png', '/images/matplotlib_demo1.png', - '/images/afterimage.png', '/videos/big_buck_bunny_432_433.webm', - '/sounds/crunching.mp3', '/images/pigs_in_a_polka.gif', - '/videos/fire2.mp4', '/videos/big_buck_bunny_0_30.webm', - '/subtitles/subtitles1.srt', '/misc/traj.txt', - '/images/vacation_2017.jpg', '/images/python_logo_upside_down.png'] - - # Loop through download url strings, build out path, and download the asset. - for url in urls: - _, tail = os.path.split(url) - download_url( - url='{}/{}'.format(github_prefix, url), - filename=output.format(tail)) - - # Download remaining asset. - download_url( - url='https://data.vision.ee.ethz.ch/cvl/video2gif/kAKZeIzs0Ag.mp4', - filename='media/video_with_failing_audio.mp4') - -if __name__ == "__main__": - download() \ No newline at end of file diff --git a/tests/resource/sintel_with_15_chapters.mp4 b/tests/resource/sintel_with_15_chapters.mp4 new file mode 100644 index 000000000..b7d123a1e Binary files /dev/null and b/tests/resource/sintel_with_15_chapters.mp4 differ diff --git a/tests/test_AudioClips.py b/tests/test_AudioClips.py index 2b50258d6..e7d160c37 100644 --- a/tests/test_AudioClips.py +++ b/tests/test_AudioClips.py @@ -9,30 +9,26 @@ from moviepy.audio.io.AudioFileClip import AudioFileClip from moviepy.audio.AudioClip import AudioClip, concatenate_audioclips, CompositeAudioClip -sys.path.append("tests") -from . import download_media from .test_helper import TMP_DIR - -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - - def test_audio_coreader(): + if sys.platform.startswith("win"): + pytest.skip("Temporarily skipping on windows because otherwise test suite fails with Invalid Handle Error") + sound = AudioFileClip("media/crunching.mp3") sound = sound.subclip(1, 4) - sound2 = sound.coreader() + sound2 = AudioFileClip("media/crunching.mp3") sound2.write_audiofile(os.path.join(TMP_DIR, "coreader.mp3")) - def test_audioclip(): make_frame = lambda t: [sin(440 * 2 * pi * t)] clip = AudioClip(make_frame, duration=2, fps=22050) clip.write_audiofile(os.path.join(TMP_DIR, "audioclip.mp3")) - def test_audioclip_concat(): + if sys.platform.startswith("win"): + pytest.skip("Temporarily skipping on windows because otherwise test suite fails with Invalid Handle Error") + make_frame_440 = lambda t: [sin(440 * 2 * pi * t)] make_frame_880 = lambda t: [sin(880 * 2 * pi * t)] @@ -51,6 +47,9 @@ def test_audioclip_concat(): def test_audioclip_with_file_concat(): + if sys.platform.startswith("win"): + pytest.skip("Temporarily skipping on windows because otherwise test suite fails with Invalid Handle Error") + make_frame_440 = lambda t: [sin(440 * 2 * pi * t)] clip1 = AudioClip(make_frame_440, duration=1, fps=44100) @@ -66,6 +65,9 @@ def test_audioclip_with_file_concat(): def test_audiofileclip_concat(): + if sys.platform.startswith("win"): + pytest.skip("Temporarily skipping on windows because otherwise test suite fails with Invalid Handle Error") + sound = AudioFileClip("media/crunching.mp3") sound = sound.subclip(1, 4) @@ -75,6 +77,5 @@ def test_audiofileclip_concat(): concat.write_audiofile(os.path.join(TMP_DIR, "concat_audio_file.mp3")) - if __name__ == "__main__": pytest.main() diff --git a/tests/test_ImageSequenceClip.py b/tests/test_ImageSequenceClip.py index c2531a00d..535260658 100644 --- a/tests/test_ImageSequenceClip.py +++ b/tests/test_ImageSequenceClip.py @@ -6,14 +6,8 @@ import pytest from moviepy.video.io.ImageSequenceClip import ImageSequenceClip -sys.path.append("tests") -from . import download_media from .test_helper import TMP_DIR -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - def test_1(): images=[] durations=[] @@ -38,7 +32,7 @@ def test_2(): images.append("media/matplotlib_demo1.png") #images are not the same size.. - with pytest.raises(Exception, message='Expecting Exception'): + with pytest.raises(Exception): ImageSequenceClip(images, durations=durations).close() diff --git a/tests/test_PR.py b/tests/test_PR.py index 41e89db26..246d2adef 100644 --- a/tests/test_PR.py +++ b/tests/test_PR.py @@ -11,24 +11,14 @@ from moviepy.video.compositing.CompositeVideoClip import CompositeVideoClip from moviepy.utils import close_all_clips - -sys.path.append("tests") from .test_helper import TMP_DIR, FONT - - -def test_download_media(capsys): - """Test downloading.""" - from . import download_media - with capsys.disabled(): - download_media.download() - def test_PR_306(): assert TextClip.list('font') != [] assert TextClip.list('color') != [] - with pytest.raises(Exception, message="Expecting Exception"): + with pytest.raises(Exception): TextClip.list('blah') close_all_clips(locals()) diff --git a/tests/test_TextClip.py b/tests/test_TextClip.py index 7cd30d568..4d4106dd4 100644 --- a/tests/test_TextClip.py +++ b/tests/test_TextClip.py @@ -5,7 +5,6 @@ from moviepy.video.fx.blink import blink from moviepy.video.VideoClip import TextClip -sys.path.append("tests") from .test_helper import TMP_DIR def test_duration(): diff --git a/tests/test_VideoClip.py b/tests/test_VideoClip.py index 35a220673..2305f5daa 100644 --- a/tests/test_VideoClip.py +++ b/tests/test_VideoClip.py @@ -11,16 +11,8 @@ from moviepy.video.fx.speedx import speedx from moviepy.utils import close_all_clips -sys.path.append("tests") -from . import download_media from .test_helper import TMP_DIR - -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - - def test_check_codec(): clip = VideoFileClip("media/big_buck_bunny_432_433.webm") location = os.path.join(TMP_DIR, "not_a_video.mas") diff --git a/tests/test_VideoFileClip.py b/tests/test_VideoFileClip.py index 8a0f1f89b..b2501224b 100644 --- a/tests/test_VideoFileClip.py +++ b/tests/test_VideoFileClip.py @@ -9,7 +9,6 @@ from moviepy.video.io.VideoFileClip import VideoFileClip from moviepy.utils import close_all_clips -sys.path.append("tests") from .test_helper import TMP_DIR def test_setup(): @@ -44,4 +43,4 @@ def test_ffmpeg_resizing(): if __name__ == '__main__': - pytest.main() \ No newline at end of file + pytest.main() diff --git a/tests/test_Videos.py b/tests/test_Videos.py index 0a912db21..8989ff3f4 100644 --- a/tests/test_Videos.py +++ b/tests/test_Videos.py @@ -8,15 +8,8 @@ from moviepy.video.fx.mask_color import mask_color from moviepy.video.VideoClip import ColorClip, ImageClip -from . import download_media - -sys.path.append("tests") from .test_helper import TMP_DIR -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - def test_afterimage(): ai = ImageClip("media/afterimage.png") masked_clip = mask_color(ai, color=[0,255,1]) # for green diff --git a/tests/test_compositing.py b/tests/test_compositing.py index bbe446e2c..c09d6999c 100644 --- a/tests/test_compositing.py +++ b/tests/test_compositing.py @@ -5,7 +5,6 @@ import pytest from moviepy.editor import * from moviepy.utils import close_all_clips -sys.path.append("tests") from .test_helper import TMP_DIR @@ -16,8 +15,7 @@ def test_clips_array(): video = clips_array([[red, green, blue]]) - with pytest.raises(ValueError, - message="Expecting ValueError (duration not set)"): + with pytest.raises(ValueError): # duration not set video.resize(width=480).write_videofile( join(TMP_DIR, "test_clips_array.mp4")) close_all_clips(locals()) @@ -31,8 +29,7 @@ def test_clips_array_duration(): blue = ColorClip((256, 200), color=(0, 0, 255)) video = clips_array([[red, green, blue]]).set_duration(5) - with pytest.raises(AttributeError, - message="Expecting ValueError (fps not set)"): + with pytest.raises(AttributeError): # fps not set video.write_videofile(join(TMP_DIR, "test_clips_array.mp4")) # this one should work correctly diff --git a/tests/test_examples.py b/tests/test_examples.py index c0e743918..ef877327e 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -9,15 +9,10 @@ # # import pytest # -# from . import download_media # from .test_helper import PYTHON_VERSION, TMP_DIR, TRAVIS # -# sys.path.append("tests") # # -# def test_download_media(capsys): -# with capsys.disabled(): -# download_media.download() # # def test_matplotlib(): # #for now, python 3.5 installs a version of matplotlib that complains diff --git a/tests/test_ffmpeg_reader.py b/tests/test_ffmpeg_reader.py index d9471a11c..86589d7bd 100644 --- a/tests/test_ffmpeg_reader.py +++ b/tests/test_ffmpeg_reader.py @@ -1,18 +1,9 @@ # -*- coding: utf-8 -*- """FFmpeg reader tests meant to be run with pytest.""" import sys - import pytest -from moviepy.video.io.ffmpeg_reader import ffmpeg_parse_infos - -from . import download_media - -sys.path.append("tests") - -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() +from moviepy.video.io.ffmpeg_reader import ffmpeg_parse_infos def test_ffmpeg_parse_infos(): d=ffmpeg_parse_infos("media/big_buck_bunny_432_433.webm") @@ -31,6 +22,9 @@ def test_ffmpeg_parse_infos(): assert d['audio_found'] assert d['audio_fps'] == 48000 +def test_ffmpeg_parse_infos_for_i926(): + d = ffmpeg_parse_infos("tests/resource/sintel_with_15_chapters.mp4") + assert d['audio_found'] if __name__ == '__main__': pytest.main() diff --git a/tests/test_fx.py b/tests/test_fx.py index 3492b25d2..4fd4d80bd 100644 --- a/tests/test_fx.py +++ b/tests/test_fx.py @@ -25,17 +25,8 @@ from moviepy.audio.io.AudioFileClip import AudioFileClip from moviepy.video.io.VideoFileClip import VideoFileClip -sys.path.append("tests") - -from . import download_media from .test_helper import TMP_DIR - -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - - def get_test_video(): return VideoFileClip("media/big_buck_bunny_432_433.webm").subclip(0, 1) @@ -86,7 +77,7 @@ def test_fadein(): clip1 = fadein(clip, 0.5) clip1.write_videofile(os.path.join(TMP_DIR, "fadein1.webm")) close_all_clips(locals()) - + def test_fadeout(): clip = get_test_video() diff --git a/tests/test_issues.py b/tests/test_issues.py index 677c2a963..4bf0c0224 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -7,22 +7,14 @@ from moviepy.editor import * from moviepy.utils import close_all_clips -sys.path.append("tests") -from . import download_media from .test_helper import PYTHON_VERSION, TMP_DIR, TRAVIS from moviepy.video.fx.blink import blink from moviepy.video.fx.resize import resize - -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - - def test_issue_145(): video = ColorClip((800, 600), color=(255, 0, 0)).set_duration(5) - with pytest.raises(Exception, message='Expecting Exception'): + with pytest.raises(Exception): concatenate_videoclips([video], method='composite') @@ -231,10 +223,10 @@ def test_issue_407(): assert green.h == blue.h == 480 assert green.size == blue.size == (640, 480) - with pytest.raises(AttributeError, message="Expecting ValueError Exception"): + with pytest.raises(AttributeError): green.fps - with pytest.raises(AttributeError, message="Expecting ValueError Exception"): + with pytest.raises(AttributeError): blue.fps video = concatenate_videoclips([red, green, blue]) @@ -270,7 +262,7 @@ def test_issue_470(): # t_end is out of bounds subclip = audio_clip.subclip(t_start=6, t_end=9) - with pytest.raises(IOError, message="Expecting IOError"): + with pytest.raises(IOError): subclip.write_audiofile(os.path.join( TMP_DIR, 'issue_470.wav'), write_logfile=True) diff --git a/tests/test_misc.py b/tests/test_misc.py index 64c0530ca..143e77318 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -10,17 +10,8 @@ from moviepy.video.VideoClip import ColorClip, TextClip from moviepy.video.io.VideoFileClip import VideoFileClip -from . import download_media from .test_helper import TMP_DIR, FONT -sys.path.append("tests") - - -def test_download_media(capsys): - with capsys.disabled(): - download_media.download() - - def test_cuts1(): clip = VideoFileClip("media/big_buck_bunny_432_433.webm").resize(0.2) cuts.find_video_period(clip) == pytest.approx(0.966666666667, 0.0001) diff --git a/tests/test_tools.py b/tests/test_tools.py index 2c276b4a4..3711f16ee 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -19,8 +19,8 @@ def test_ext(): def test_2(): """Test for raising erre if codec not in dictionaries.""" - message = "asking for a silly video format did not Raise a Value Error" - with pytest.raises(ValueError, message=message): + + with pytest.raises(ValueError): # asking for a silly video format tools.find_extension('flashvideo') def test_3(): diff --git a/tests/test_videotools.py b/tests/test_videotools.py index fd8161b15..076dcdeeb 100644 --- a/tests/test_videotools.py +++ b/tests/test_videotools.py @@ -5,10 +5,8 @@ from moviepy.video.tools.credits import credits1 -sys.path.append("tests") from .test_helper import TMP_DIR - def test_credits(): credit_file = "# This is a comment\n" \ "# The next line says : leave 4 blank lines\n" \