{ "info": { "author": "Timothy Moore", "author_email": "mtimothy984@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Utilities" ], "description": "# Multiprocessed Animations\n\n## Summary\n\nThis library helps building movies in python from images. Specifically, it\nintends to allow multiple threads to produce images which are stiched together\ninto movies with ffmpeg.\n\n## Use-cases\n\nThis can be used to multithread the image creation process when using\nmatplotlib animations. FFMpeg will use multithreading to encode the images into\na video, however producing the images themselves is a bottleneck if you have\nmany cores available. Hence, this will vastly reduce the time it takes to\ngenerate matplotlib animations.\n\nThis can also be used for generating scenes with\n[PIL](https://pillow.readthedocs.io/en/stable/).\n\nThis library's goal is to make generating videos as simple as possible first,\nthen to go as fast as possible within those simple techniques. This gives fast\nenough performance for many projects, and has the enormous benefit that you\ncan throw more hardware at the problem. Using ffmpeg directly without\nmultithreading image generation will not scale to more hardware.\n\n## Performance\n\nWith ideal settings, the images should be generated at a rate that just barely\ndoes not fill the ffmpeg process input pipe. This will ensure that images are\nbeing generated as quickly as they can be encoded.\n\nBy default, this library will attempt to find the settings that accomplish this\ntask. This takes a bit of time to accomplish, so the final settings are exposed\nand it can be helpful to use those when re-running roughly the same task. The\ncorrect settings will depend on how long it takes to generate images and how\nlong it takes to encode them which varies based on the image statistics.\n\n## Installation\n\n`pip install pympanim`\n\n## Dependencies\n\nThis depends on ffmpeg being installed. It can be installed\n[here](https://ffmpeg.org/download.html). Other python dependencies will be\nautomatically installed by pip.\n\n## Usage - Acts\n\n### Motivation\n\nMany times you have something which is capable of rendering some underlying\nstate in a consistent way, and the video you want to produce is made up of\nparts that manipulate the state that is sent to the renderer. This use case\nis handled specifically by `pympanim/acts.py`.\n\n### Summary\n\nDefine the state that completely describes how to render things in a class that\nsubclasses `pympanim.acts.ActState`. Then create the thing which can render\nthe given state to an image (described via rgba bytes or a Pillow Image).\n\nWith these ready, create (one or more) `Scene`s, which are things that\nmanipulate the state you just created. A scene has some duration, and must be\nable to set the state to correspond to a particular time within the scene.\n\nThis library will provide common manipulations of scenes - nonlinear time\nmanipulations, cropping, reversing, and sequencing. To make the most use of\nthese manipulations, Scenes should be as simple as possible.\n\nMultiple Acts can be combined in much the same way. See Usage - Frame\nGenerators for details below.\n\nTo produce the video, use `pympanim.worker.produce`, creating a frame generator\nout of the scenes using `pympanim.acts.Act`\n\n### Boilerplate\n\n```py\nimport PIL.Image\nimport pympanim.worker as pmaw\nimport pympanim.acts as acts\nimport pympanim.frame_gen as fg\nimport os\n\nclass MyActState(acts.ActState):\n pass\n\nclass MyActRenderer(acts.ActRenderer):\n @property\n def frame_size(self):\n return (1920, 1080) # in pixels\n\n def render(self, act_state: MyActState) -> bytes:\n return fg.img_to_bytes(self.render_pil(act_state))\n\n def render_pil(self, act_state: MyActState) -> PIL.Image:\n # By default, render_pil delegates to render. It is shown reversed\n # here for completeness.\n return PIL.Image.new('RGBA', self.frame_size, 'white')\n\nclass Scene1(acts.Scene):\n @property\n def duration(self):\n return 1 # 1 millisecond; allows you to treat time_ms as % progress\n\n def apply(self, act_state: MyActState, time_ms: float, dbg: bool = False):\n # dbg is passed across the scene heirarchy and will be false when\n # rendering the video. you may find it helpful to print some debug\n # information when it is true\n pass\n\ndef _scene():\n scene = Scene1()\n return (acts.FluentScene(scene)\n .dilate(lambda x: x**2) # any easing works here. see\n # pympanim.easing and pytweening\n .time_rescale(1 / 10000) # 10s of real time corresponds to\n # 1ms of scene time\n .build()\n )\n\ndef _main():\n os.makedirs('out', exist_ok=True)\n act_state = MyActState()\n act_renderer = MyActRenderer()\n\n pmaw.produce(\n acts.Act(act_state, renderer, [_scene()]),\n fps=60,\n dpi=100,\n bitrate=-1,\n outfile='out/video.mp4'\n )\n\nif __name__ == '__main__':\n _main()\n\n```\n\nFor method-level documentation, use the built-in `help` command, i.e.,\n```\n>python3\n>>> import pympanim.acts\n>>> help(pympanim.acts)\nHelp on module pympanim.acts in pympanim:\n.. (omitted for readme brevity) ..\n```\n\n## Usage - Frame Generators\n\n### Motivation\n\nThe most novel part of this library is the boilerplate to generate videos where\nthe image generation itself is multithreaded. This is exposed in as raw a manner\nas possible using `pympanim/frame_gen.py` which is merely wrapped by\n`pympanim/acts.py`. This section discusses how to use this library with minimal\nabstraction.\n\n### Summary\n\nCreate a subclass of `pympanim.frame_gen.FrameGenerator`, which requires\ndefining a duration, frame size in pixels, and a `generate_at` function which\ncan generate an image given just the time within the video.\n\nThis library provides common manipulations of vidoes that you can wrap your\nvideo with, such as cropping, time dilations, reversing time, and combinations\nof frame generators.\n\nTo produce the video, use `pympanim.worker.produce`. Everything else is handled\nfor you, including reasonable guesses for performance settings and runtime\nperformance tuning.\n\n### Boilerplate\n\n```py\nimport PIL.Image\nimport pympanim.frame_gen as fg\nimport pympanim.worker as pmaw\nimport os\n\nclass MyFrameGenerator(fg.FrameGenerator):\n @property\n def duration(self):\n return 1 # 1 ms, allows you to treat time_ms as % progress\n\n @property\n def frame_size(self):\n return (1920, 1080) # in pixels\n\n def generate_at(self, time_ms):\n # by default generate_at_pil delegates to generate_at. we show the\n # reverse for completeness\n return fg.img_to_bytes(self.generate_at_pil(time_ms))\n\n def generate_at_pil(self, time_ms):\n # this from white to red, you can do whatever\n return PIL.Image.new('RGBA', self.frame_size, f'#{int(time_ms*255):02x}0000')\n\ndef _fg():\n base = MyFrameGenerator()\n\n # random example of the stuff you can do\n return (fg.FluentFG(base)\n .time_rescale(1 / 10000) # 10s long\n .then( # after current\n fg.FluentFG(base) # play again\n .time_rescale(1 / 10000) # also 10s long\n .reverse() # but this time in reverse\n .build()\n )\n .build())\n\ndef _main():\n os.makedirs('out', exist_ok=True)\n\n pmaw.produce(\n _fg(),\n fps=60,\n dps=100,\n bitrate=-1,\n outfile='out/video.mp4'\n )\n\nif __name__ == '__main__':\n _main()\n\n```\n\n\n## Examples\n\nThe examples/ folder has the sourcecode for the following examples:\n\n```\npython3 -m examples.redsquare\n```\n\nProduces https://gfycat.com/digitalmaleflyingfish\n\n```\npython3 -m examples.mpl_line\n```\n\nProduces https://gfycat.com/wickedpracticalattwatersprairiechicken\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/tjstretchalot/pympanim", "keywords": "pympanim animations video mp4", "license": "CC0", "maintainer": "", "maintainer_email": "", "name": "pympanim", "package_url": "https://pypi.org/project/pympanim/", "platform": "", "project_url": "https://pypi.org/project/pympanim/", "project_urls": { "Homepage": "https://github.com/tjstretchalot/pympanim" }, "release_url": "https://pypi.org/project/pympanim/0.0.7/", "requires_dist": [ "pyzmq", "pytypeutils", "Pillow" ], "requires_python": ">=3.6", "summary": "Multiprocessing-friendly animations", "version": "0.0.7" }, "last_serial": 5609408, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "2072b4dcda643d76ca11f8b0533992f4", "sha256": "ec4f596ba5d3f623dac247c54101e0e57f0bae14eba9a6cd9b3ecc23c29e0fe3" }, "downloads": -1, "filename": "pympanim-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "2072b4dcda643d76ca11f8b0533992f4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 31764, "upload_time": "2019-07-26T18:00:52", "url": "https://files.pythonhosted.org/packages/ab/9e/50f51e4ebd6581b7ddfd18c3e0b73f3de46df153976b7a0bfeff4bc961af/pympanim-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "beddf0f190c330050a8e5e57b56a1370", "sha256": "140cafaedc7f6612a538df894048a40e69bbeaaeba128cce56218d444c391701" }, "downloads": -1, "filename": "pympanim-0.0.1.tar.gz", "has_sig": false, "md5_digest": "beddf0f190c330050a8e5e57b56a1370", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 28359, "upload_time": "2019-07-26T18:00:54", "url": "https://files.pythonhosted.org/packages/12/57/ecac74b727740a367b0548da6c295a7157988c087779aab5cb687b6ab32f/pympanim-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "37756b51f4a2151e1746b626093e8ab9", "sha256": "303424583348646b3e02f7ee6b52e28754a797cd0308087c3d359e443d608667" }, "downloads": -1, "filename": "pympanim-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "37756b51f4a2151e1746b626093e8ab9", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 31696, "upload_time": "2019-07-26T18:03:39", "url": "https://files.pythonhosted.org/packages/d8/97/fd22033d5fb1dad3df15dcda44dbbd4d1f2c3370d970e6458c2410e1e4c3/pympanim-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "7b2f44545ac98c8ed7cf4c2f52483963", "sha256": "f3ce4b2c8f8da8d5e5460ea012a9dfab91efe28c751ac48e56291e8b42360de7" }, "downloads": -1, "filename": "pympanim-0.0.2.tar.gz", "has_sig": false, "md5_digest": "7b2f44545ac98c8ed7cf4c2f52483963", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 28208, "upload_time": "2019-07-26T18:03:41", "url": "https://files.pythonhosted.org/packages/b5/ee/1a144245d54a8ea2a0db1e65efa520cd5a3a9be0c30fc0e8461ed54d1823/pympanim-0.0.2.tar.gz" } ], "0.0.2b0": [ { "comment_text": "", "digests": { "md5": "9c807b8798f4bde754b984944344937d", "sha256": "8056d09ee00f82e5e555ba0736aa12c8be11048e66941a04d8d633744ae2d0aa" }, "downloads": -1, "filename": "pympanim-0.0.2b0-py3-none-any.whl", "has_sig": false, "md5_digest": "9c807b8798f4bde754b984944344937d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 31723, "upload_time": "2019-07-26T18:11:19", "url": "https://files.pythonhosted.org/packages/f6/dd/1122c6c7c86cab11304d2ced3645ff21f954a377d80829df4cc100f4f768/pympanim-0.0.2b0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2f07497a399d1bb8675dd25401ac0ded", "sha256": "2b4792312243fa2be5c3cb0277e1a5995e0c3e13c66d79acf54390a4bc75a434" }, "downloads": -1, "filename": "pympanim-0.0.2b0.tar.gz", "has_sig": false, "md5_digest": "2f07497a399d1bb8675dd25401ac0ded", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 28217, "upload_time": "2019-07-26T18:11:21", "url": "https://files.pythonhosted.org/packages/7d/7b/f767832eec5658cc5afc2c5f761f62d8d5eb27491320e41c01641e1d4557/pympanim-0.0.2b0.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "9450c0e0b71cc10d43a99c1ffbf3e8c5", "sha256": "0371a5ac86e7a965d7f499838fea0742a9789c6896b0a1e45e8cba9504c23a60" }, "downloads": -1, "filename": "pympanim-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "9450c0e0b71cc10d43a99c1ffbf3e8c5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 31704, "upload_time": "2019-07-26T18:12:39", "url": "https://files.pythonhosted.org/packages/b9/39/d369f3e3643e44193fc45fa4bde33dc4eb607e731b0191e0153f0d180f95/pympanim-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cb3799d716a7242304d2cd6f34394e1a", "sha256": "bd2597feb46ce92d1532d5914e2bec075165a6cf3d45c9a54fa85ebd01ddbfa0" }, "downloads": -1, "filename": "pympanim-0.0.3.tar.gz", "has_sig": false, "md5_digest": "cb3799d716a7242304d2cd6f34394e1a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 28229, "upload_time": "2019-07-26T18:12:40", "url": "https://files.pythonhosted.org/packages/9b/73/8d469bbbbc0af27822224358ddff05b36ad4501235301bed0b940ed7f183/pympanim-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "c994d98e02832bed8253e3e940fcc1c5", "sha256": "582ec7b10c82d928624732588e8fb264d7ca2200977648f3e16bc6fec7a80b9c" }, "downloads": -1, "filename": "pympanim-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "c994d98e02832bed8253e3e940fcc1c5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 32173, "upload_time": "2019-07-29T15:18:32", "url": "https://files.pythonhosted.org/packages/55/3f/3489b71f91dc3a625b41c2b4d923023c78535a795f78a65872e424eb1989/pympanim-0.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "93b19ae4130999e97228944561377ebc", "sha256": "79a66129b45e8ea37d7a0a347a7d97e1ff1faf66f14ac85f68aff40624d586ea" }, "downloads": -1, "filename": "pympanim-0.0.4.tar.gz", "has_sig": false, "md5_digest": "93b19ae4130999e97228944561377ebc", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 28698, "upload_time": "2019-07-29T15:18:34", "url": "https://files.pythonhosted.org/packages/09/7d/2919ec5463c0a0793c1afe923bcecc509d0679a587923eafad933810f607/pympanim-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "19f141e5120f7acb2edf7d8e9081c4ab", "sha256": "1e53c962ee2b01f31f4a7f210e64aaf6b5e41dea67c4da37e6be4d1bc64ded5b" }, "downloads": -1, "filename": "pympanim-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "19f141e5120f7acb2edf7d8e9081c4ab", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 34040, "upload_time": "2019-07-30T17:03:13", "url": "https://files.pythonhosted.org/packages/14/cc/53e101205340dd09ed2de0f166de0ca817ad27c7425f1b6ce8bfe980a96a/pympanim-0.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c2d086308d98ca6d76e611d8ee462654", "sha256": "a2e85fa06515f12bba8e2b9cc31ef4859cb20e71481b65e28112a3df3ab69614" }, "downloads": -1, "filename": "pympanim-0.0.5.tar.gz", "has_sig": false, "md5_digest": "c2d086308d98ca6d76e611d8ee462654", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30277, "upload_time": "2019-07-30T17:03:14", "url": "https://files.pythonhosted.org/packages/17/54/924d95746f7a341b089fb6dae988e5339dc5acd77e3f8671f7dcdb166d21/pympanim-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "84b093ea0c559ab09c7ed095483d6c65", "sha256": "d7cafaa1de65e82fa1588d6b5aae314424e94e19f0680dd96b0008d755789070" }, "downloads": -1, "filename": "pympanim-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "84b093ea0c559ab09c7ed095483d6c65", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 34036, "upload_time": "2019-07-30T18:15:27", "url": "https://files.pythonhosted.org/packages/90/77/8862578d1140a867e8d4de8b5f5c29776f8a647010193492d04c13a7bc60/pympanim-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "09fef652cf38ee3dbd0cf860f1da91c5", "sha256": "8e7629c3f9a980cbfc13f8b124d09219bacc82925fd3b00d85ca748835f0b10a" }, "downloads": -1, "filename": "pympanim-0.0.6.tar.gz", "has_sig": false, "md5_digest": "09fef652cf38ee3dbd0cf860f1da91c5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30275, "upload_time": "2019-07-30T18:15:28", "url": "https://files.pythonhosted.org/packages/38/5a/5d9a32e31874456cf4e7a50eb5bfde790197c373e8f3d4a6f36cda195c03/pympanim-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "75a40d5b61f26de5b49c8eca52942e36", "sha256": "d8d3d0e11b537b8dcf9a2101a10b7f16a97bf689c1d54947e9310f5769b90806" }, "downloads": -1, "filename": "pympanim-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "75a40d5b61f26de5b49c8eca52942e36", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 34081, "upload_time": "2019-07-30T18:25:30", "url": "https://files.pythonhosted.org/packages/00/25/f29baf1f744f0a2ce24132edc51b763cafe8b35531b63e7a7e1027f6e2f3/pympanim-0.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e2f4b7856b50cef19f75e96eaacf0ac9", "sha256": "06a3b69a0cea9584dea72d07dbaffc298188f536cbe9f59c3c41999260ee8984" }, "downloads": -1, "filename": "pympanim-0.0.7.tar.gz", "has_sig": false, "md5_digest": "e2f4b7856b50cef19f75e96eaacf0ac9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30306, "upload_time": "2019-07-30T18:25:32", "url": "https://files.pythonhosted.org/packages/74/38/179fc92fd90fcefe3de2693be63ff9ab1fcb54f5b77402e48c8315fb6f9e/pympanim-0.0.7.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "75a40d5b61f26de5b49c8eca52942e36", "sha256": "d8d3d0e11b537b8dcf9a2101a10b7f16a97bf689c1d54947e9310f5769b90806" }, "downloads": -1, "filename": "pympanim-0.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "75a40d5b61f26de5b49c8eca52942e36", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 34081, "upload_time": "2019-07-30T18:25:30", "url": "https://files.pythonhosted.org/packages/00/25/f29baf1f744f0a2ce24132edc51b763cafe8b35531b63e7a7e1027f6e2f3/pympanim-0.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e2f4b7856b50cef19f75e96eaacf0ac9", "sha256": "06a3b69a0cea9584dea72d07dbaffc298188f536cbe9f59c3c41999260ee8984" }, "downloads": -1, "filename": "pympanim-0.0.7.tar.gz", "has_sig": false, "md5_digest": "e2f4b7856b50cef19f75e96eaacf0ac9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 30306, "upload_time": "2019-07-30T18:25:32", "url": "https://files.pythonhosted.org/packages/74/38/179fc92fd90fcefe3de2693be63ff9ab1fcb54f5b77402e48c8315fb6f9e/pympanim-0.0.7.tar.gz" } ] }