{ "info": { "author": "andyguo", "author_email": "andyguo@phenom-films.com", "bugtrack_url": null, "classifiers": [ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: Implementation" ], "description": "dayu_ffmpeg\n===========\n\n|pypi| |python| |build status| |github license|\n\ndayu_ffmpeg \u662f\u9488\u5bf9ffmpeg \u547d\u4ee4\u884c\u7684python \u5c01\u88c5\u3002 ffmpeg\n\u7684\u529f\u80fd\u76f8\u5f53\u5f3a\u5927\uff0c\u4f46\u662f\u590d\u6742\u7684\u7ec8\u7aef\u6307\u4ee4\u5f80\u5f80\u8ba9\u4eba\u65e0\u6cd5\u4f7f\u7528\u3002dayu_ffmpeg\n\u6b63\u597d\u89e3\u51b3\u4e86\u8fd9\u4e2a\u95ee\u9898\u3002 \u7528\u6237\u53ef\u4ee5\u4f7f\u7528\u7b80\u5355\u7684 \u201c\u6d41\u201d\n\u7684\u6982\u5ff5\u642d\u5efa\u81ea\u5df1\u7684\u5904\u7406\u65b9\u5f0f\uff0c\u540c\u65f6\u5177\u6709\u4e0b\u9762\u7684\u7279\u70b9\uff1a\n\n- \u901a\u8fc7 >> \u8fd0\u7b97\u7b26\uff0c\u8868\u793astream \u7684\u64cd\u4f5c\n- \u62e5\u6709ad-hoc \u548cnetwork \u4e24\u79cd\u64cd\u4f5c\u6a21\u5f0f\n- \u652f\u6301ffmpeg complex filter\n- \u5982\u679c\u7528\u6237\u9700\u8981\u4f7f\u7528\u7684filter \u4e0d\u5728\u9ed8\u8ba4\u7684filter class \u4e2d\uff0c\u53ef\u4ee5\u81ea\u884c\u6269\u5c55\n- \u53ef\u4ee5\u5c06Root Node \u4fdd\u5b58\u4e3affscipt \u7684json\n \u683c\u5f0f\uff0c\u65b9\u4fbf\u4fdd\u5b58\u786c\u76d8\u6587\u4ef6\u6216\u8005\u662f\u7f51\u7edc\u901a\u4fe1\n\nad-hoc \u6a21\u5f0f\n===========\n\n\u5728ad-hoc \u6a21\u5f0f\u4e0b\uff0c\u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u8282\u70b9\u8fdb\u884c\u4e32\u884c\u64cd\u4f5c\u3002\n\u4f8b\u5982\uff0c\u7528\u6237\u5e0c\u671b\u5bf9\u4e00\u4e2amov \u7d20\u6750\u8fdb\u884c\u4e0b\u9762\u7684\u64cd\u4f5c\uff1a\n\n- \u7ed8\u52362.39 \u7684\u906e\u5e45\n- \u7f29\u653e\u52301920x1080 \u7684\u5c3a\u5bf8\n- \u5199\u5165\u5185\u5d4creel\n- \u5199\u5165\u5185\u5d4ctimecode\n- \u6e32\u67d3\u8f93\u51fa\u5230prores 422 \u7684mov\n\n\u5982\u679c\u76f4\u63a5\u4f7f\u7528ffmpeg\uff0c\u90a3\u4e48\u7ec8\u7aef\u6307\u4ee4\u4f1a\u662f\uff1a\n\n.. code:: shell\n\n \"ffmpeg\" -y -i \"/some/input/file.mov\" -filter_complex \"[0]drawbox=x=-t:y=0:w=iw+t*2:h=ih:c=black:t=(ih-(iw/2.39))/2[v0],[v0]scale=w=1920:h=1080[v1]\" -map [v1] -metadata:s:v:0 reel_name=reelname -timecode 11:22:11:22 -codec:v prores_ks \"/some/output/file.mov\"\n\n\u5982\u679c\u4f7f\u7528\u4e86dayu_ffmpeg\uff0c\u5c31\u4f1a\u975e\u5e38\u7684\u76f4\u89c2\u3002\u7528\u6237\u5c06\u81ea\u5df1\u7684\u9700\u8981\u7684\u64cd\u4f5c\u4e00\u4e00\u5199\u5165\u7686\u53ef\uff1a\n\n.. code:: python\n\n from dayu_ffmpeg input *\n\n result = Input('/some/input/file.mov') >> \\\n Drawmask(2.39) >> \\\n Scale(1920, 1080) >> \\\n Writereel('reelname') >> \\\n Writetimecode('11:22:11:22') >> \\\n Codec(video='prores_ks') >> \\\n Output('/some/output/file.mov')\n\n\u9700\u8981\u6ce8\u610f\u7684\u662f\uff0c\u5728ad-hoc \u6a21\u5f0f\u4e0b\uff0c\u53ea\u80fd\u591f\u652f\u6301\u4e32\u884c\u7684\u64cd\u4f5c\u3002\n\u4e5f\u5c31\u662f\u8bf4\u6240\u6709\u7684\u8282\u70b9\u90fd\u53ea\u80fd\u62e5\u6709\u4e00\u4e2a\u8f93\u5165\u548c\u4e00\u4e2a\u8f93\u51fa\u3002\n\u5982\u679c\u60f3\u8981\u4f7f\u7528\u66f4\u52a0\u590d\u6742\u7684\u8f6c\u7801\uff0c\u8bf7\u4f7f\u7528network \u6a21\u5f0f\n\nnetwork \u6a21\u5f0f\n============\n\nnetowrk \u6a21\u5f0f\u4f1a\u6bd4ad-hoc\n\u590d\u6742\u4e00\u70b9\uff0c\u4f46\u662f\u53ef\u4ee5\u5b9e\u73b0\u66f4\u52a0\u590d\u6742\u7684\u8f6c\u7801\u7ed3\u6784\u3002\u5e76\u4e14\u4e00\u65e6TD \u5199\u597d\u4e86\u4e00\u4e2anetwork\uff0c\n\u90a3\u4e48\u540e\u7eed\u7684\u7528\u6237\u5728\u4f7f\u7528\u4e0a\u5c31\u975e\u5e38\u7684\u7b80\u5355\uff0c\u76f8\u5f53\u4e8e\u63d0\u4f9b\u4e86\u4e00\u4e2a \u201c\u8f6c\u7801\u6a21\u677f\u201d\u3002\n\n.. code:: python\n\n from dayu_ffmpeg import *\n\n class TranscodeTemplate(RootNode):\n def prepare(self):\n # \u7528\u6237\u53ea\u9700\u8981\u91cd\u8f7dprepare() \u51fd\u6570\uff0c\u5728\u8fd9\u91cc\u7ec4\u7ec7\u597d\u7f51\u7edc\u7ed3\u6784\n # \u7559\u597dInputHolder \u6216\u8005OutputHolder \u4f5c\u4e3a \"\u63a5\u53e3\"\n ih1 = self.create_node(InputHolder)\n i2 = self.create_node(Input('some_logo.png'))\n\n cf = self.create_node(ComplexFilterGroup)\n ih2 = cf.create_node(InputHolder)\n ih3 = cf.create_node(InputHolder)\n cf.set_input(ih1, 0)\n cf.set_input(i2, 1)\n over = cf.create_node(Overlay)\n over.set_input(ih2, 0)\n over.set_input(ih3, 1)\n fit = cf.create_node(Fit())\n fit.set_input(over)\n oh1 = cf.create_node(OutputHolder)\n oh1.set_input(fit)\n\n oh2 = self.create_node(OutputHolder)\n oh2.set_input(cf)\n\n\n if __name__ == '__main__':\n # \u5b9e\u4f8b\u5316\u8f6c\u7801\u7684\u7f51\u7edc\n template_root = TranscodeTemplate(name='overlay logo, then fit in HD, finally export to mov')\n\n # \u521b\u5efa\u8f93\u5165\u3001\u8f93\u51fa\n input1 = Input('some_input_file.mov')\n output1 = Output('some_output_file.mov')\n\n # \u7528\u6237\u76f4\u63a5\u8c03\u7528\uff0c\u5c31\u5b8c\u6210\u4e86\u6574\u4e2a\u8f6c\u7801\uff0c\u76f8\u5f53\u4e8e\u8c03\u7528\"\u6a21\u677f\"\n network_mode_cmd = template_root(input_list=[input1], output_list=[output1])\n print network_mode_cmd.cmd()\n\n\u4f7f\u7528\u81ea\u5b9a\u4e49filter\n================\n\n\u5982\u679c\u9ed8\u8ba4\u7684filter\n\u4e2d\u4e0d\u5b58\u5728\u9700\u8981\u4f7f\u7528\u7684filter\u3002\u7528\u6237\u53ef\u4ee5\u6709\u4e0b\u9762\u7684\u51e0\u79cd\u65b9\u6cd5\u81ea\u884c\u6269\u5c55:\n\n- \u8c03\u7528GeneralUnaryFilter\n- \u7ee7\u627fBaseFilterNode class\uff0c\u81ea\u884c\u5b9e\u73b0\n- \u7ee7\u627fBasePackedFilterNode, \u5c06\u591a\u79cdfilter \u8fdb\u884c\u6253\u5305\uff0c\u5f62\u6210\u65b0\u7684\u4e00\u4e2afilter\n\n\u8c03\u7528GeneralUnaryFilter\uff1a\n\n.. code:: python\n\n command = Input('/some/input/file.mov') >> \\\n GeneralUnaryFilter('drawgrid', x=0, y=0, w=100, h=50) >> \\\n Output('/custom/filter/output.mov')\n\n\u7ee7\u627fBaseFilterNode class\uff0c\u81ea\u884c\u5b9e\u73b0\uff1a\n\n.. code:: python\n\n class Null(BaseFilterNode):\n # \u8bbe\u7f6e\u7279\u5b9a\u7684type\uff0c\u8981\u4fdd\u8bc1\u552f\u4e00\u6027\n type = 'some_ffmpeg_filter_name'\n\n # \u91cd\u8f7dinit\uff0c\u5b9e\u73b0\u81ea\u5df1\u7684\u53c2\u6570\n def __init__(self, **kwargs):\n super(Null, self).__init__(**kwargs)\n\n # \u91cd\u8f7d simple_cmd_string\uff0c\u8fd4\u56de\u5bf9\u5e94\u7684ffmpeg \u6307\u4ee4string\n def simple_cmd_string(self):\n self._cmd = u'null'\n return self._cmd\n\n\u7ee7\u627fBasePackedFilterNode, \u5c06\u591a\u79cdfilter \u8fdb\u884c\u6253\u5305\uff0c\u5f62\u6210\u65b0\u7684\u4e00\u4e2afilter\u3002\n\u53ef\u4ee5\u53c2\u770b Fit \u8fd9\u4e2aclass \u7684\u5b9e\u73b0\u65b9\u5f0f\u3002\n\n\u67e5\u770bshell \u6307\u4ee4 \u4ee5\u53ca\u8fd0\u884c\n=======================\n\n\u7528\u6237\u53ef\u4ee5\u67e5\u770b\u751f\u6210\u7684shell \u6307\u4ee4\uff0c\u6216\u8005\u76f4\u63a5\u8fd0\u884c\uff1a\n\n.. code:: python\n\n # \u67e5\u770b\u5c06\u8981\u8fd0\u884c\u7684\u7ec8\u7aef\u6307\u4ee4\n print command.cmd()\n\n # \u7ec4\u88c5filter \u4e4b\u540e\uff0c\u5373\u53ef\u8fd0\u884c\u547d\u4ee4\n for progress in command.run():\n try:\n print progress # \u901a\u8fc7yield \u8fd4\u56de\u6e32\u67d3\u8fdb\u5ea6\u7684dict\uff0c\u7528\u6237\u53ef\u4ee5\u81ea\u884c\u5b9e\u73b0\u975e\u963b\u585e\u8fdb\u5ea6\u6761\n except Exception as e:\n raise # \u5982\u679c\u6307\u4ee4\u9519\u8bef\uff0c\u4f1a\u629b\u51fa\u5f02\u5e38\n\nffscript \u7684\u4fdd\u5b58\u548c\u8bfb\u53d6\n=====================\n\nffscript \u662fdayu_ffmpeg \u5bf9\u4e8enetwork \u7ed3\u6784\u7684\u4e00\u79cdjson\n\u8868\u73b0\u5f62\u5f0f\uff0c\u53ef\u4ee5\u8ba4\u4e3a\u662f\u201c\u5de5\u7a0b\u6587\u4ef6\u201d\u3002 \u5982\u679c\u60f3\u8981\u628a\u7ec4\u6210\u7684network\n\u4fdd\u5b58\u5230\u786c\u76d8\u4e0a\uff0c\u6216\u662f\u901a\u8fc7\u7f51\u7edc\u901a\u4fe1\u8fdb\u884c\u4f20\u9012\uff0c\u5c31\u4f1a\u4f7f\u7528\u5230\u3002\n\n\u4fdd\u5b58ffscript\uff1a\n\n.. code:: python\n\n from dayu_ffmpeg.ffscript import save_script, open_script\n\n # \u4fdd\u5b58\n save_script(netowrk_node_instance, '/some/script/path.json')\n\n # \u8bfb\u53d6\n transcode_template = open_script('/some/script/path.json')\n\n.. |pypi| image:: https://img.shields.io/badge/pypi-0.5-blue.svg\n :target: https://pypi.org/project/dayu-ffmpeg/\n.. |python| image:: https://img.shields.io/badge/python-2.7-blue.svg\n :target: \n.. |build status| image:: https://travis-ci.org/phenom-films/dayu_ffmpeg.svg?branch=master\n :target: https://travis-ci.org/phenom-films/dayu_ffmpeg\n.. |github license| image:: https://img.shields.io/github/license/mashape/apistatus.svg\n :target: https://github.com/phenom-films/dayu_ffmpeg/blob/master/license", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/phenom-films/dayu_ffmpeg", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "dayu-ffmpeg", "package_url": "https://pypi.org/project/dayu-ffmpeg/", "platform": "", "project_url": "https://pypi.org/project/dayu-ffmpeg/", "project_urls": { "Homepage": "https://github.com/phenom-films/dayu_ffmpeg" }, "release_url": "https://pypi.org/project/dayu-ffmpeg/0.5.1/", "requires_dist": null, "requires_python": "", "summary": "FFmpeg python wrapper for human, with common filters built in.", "version": "0.5.1" }, "last_serial": 4980754, "releases": { "0.3": [ { "comment_text": "", "digests": { "md5": "73b74182ac2332e7935ab4f826d71efe", "sha256": "7c2c9f2a8dbf9ab56a131e3e40049a9d9c672677a51c517d1f71ee9b3126f51f" }, "downloads": -1, "filename": "dayu_ffmpeg-0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "73b74182ac2332e7935ab4f826d71efe", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 12418, "upload_time": "2018-09-24T12:00:04", "url": "https://files.pythonhosted.org/packages/59/7f/a732c8d656126ea2f0cc8defd8a05d85f9565d10a6e119d5c893bd8c404a/dayu_ffmpeg-0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "53dc95750e732f0471c15740ac97a0e0", "sha256": "f61b160fe1c3dfcdce4e9bc4044487cdc57c007aa128abd08f155ba6d28e176b" }, "downloads": -1, "filename": "dayu_ffmpeg-0.3.tar.gz", "has_sig": false, "md5_digest": "53dc95750e732f0471c15740ac97a0e0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12894, "upload_time": "2018-09-24T12:00:06", "url": "https://files.pythonhosted.org/packages/d8/bb/3f5240ef7962329a33f7d32f23588923929828736c541c5f3d575cf3200c/dayu_ffmpeg-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "e3edee9d34308c507118fc75fd026109", "sha256": "c8a691d102c24eae9f26c97a4bc8727afa49c448385b1786161d00117994ee4b" }, "downloads": -1, "filename": "dayu_ffmpeg-0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e3edee9d34308c507118fc75fd026109", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 13252, "upload_time": "2018-09-25T03:43:17", "url": "https://files.pythonhosted.org/packages/6e/39/8ede6ad35136e819bd098d7a3f6deb53bb66f9c652436d248fb36a5afe14/dayu_ffmpeg-0.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "99e4fef999201b735fb74528bbe68a61", "sha256": "e55387bdbb01424804e70d1216eb325e06b52dfb28cd5ee6ba00bc43107fafc9" }, "downloads": -1, "filename": "dayu_ffmpeg-0.4.tar.gz", "has_sig": false, "md5_digest": "99e4fef999201b735fb74528bbe68a61", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13512, "upload_time": "2018-09-25T03:43:19", "url": "https://files.pythonhosted.org/packages/69/ad/4ae2c04b3ce4150d19c1ece78fe665db5c2b1e9da5d15523a1c9dc94b322/dayu_ffmpeg-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "e4a83887a34ed774d1e4663eb77730ed", "sha256": "8de6d1420453071c9c5e42b69814f2d4c69cb69a3a4573734975d37e7d0c860f" }, "downloads": -1, "filename": "dayu_ffmpeg-0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e4a83887a34ed774d1e4663eb77730ed", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15492, "upload_time": "2019-01-08T04:51:38", "url": "https://files.pythonhosted.org/packages/6c/a2/fb354f8a24e97d6dace4d124417c61f04b16e1e34c8a05f908c2b2b27f57/dayu_ffmpeg-0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e1541a0753aa7d0aa0a987b1faca7265", "sha256": "4643891375f24bac1e222183d79a492a74cab522e66eb677b2289eefe7d7979b" }, "downloads": -1, "filename": "dayu_ffmpeg-0.5.tar.gz", "has_sig": false, "md5_digest": "e1541a0753aa7d0aa0a987b1faca7265", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16246, "upload_time": "2019-01-08T04:51:40", "url": "https://files.pythonhosted.org/packages/77/d9/0b840fcbd7aaf78eb7175646efa74758adfeee0e48f3e1e26460e12806f3/dayu_ffmpeg-0.5.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "c1011cfa2c0cf92c5858ed755bdea18c", "sha256": "46cbf299e851f869349290febcd06091210ad5dc368010274d1f080f9d5f92c7" }, "downloads": -1, "filename": "dayu_ffmpeg-0.5.1.tar.gz", "has_sig": false, "md5_digest": "c1011cfa2c0cf92c5858ed755bdea18c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 60794715, "upload_time": "2019-03-25T04:08:33", "url": "https://files.pythonhosted.org/packages/2d/1a/bef6867bd29a9c542381b65234a9955bb68fc5c0135d5cbc84146f43319e/dayu_ffmpeg-0.5.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c1011cfa2c0cf92c5858ed755bdea18c", "sha256": "46cbf299e851f869349290febcd06091210ad5dc368010274d1f080f9d5f92c7" }, "downloads": -1, "filename": "dayu_ffmpeg-0.5.1.tar.gz", "has_sig": false, "md5_digest": "c1011cfa2c0cf92c5858ed755bdea18c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 60794715, "upload_time": "2019-03-25T04:08:33", "url": "https://files.pythonhosted.org/packages/2d/1a/bef6867bd29a9c542381b65234a9955bb68fc5c0135d5cbc84146f43319e/dayu_ffmpeg-0.5.1.tar.gz" } ] }