From abd400083f47ecf93cda6518f5fe764a44e593d3 Mon Sep 17 00:00:00 2001 From: lucemia Date: Tue, 9 Apr 2024 12:23:15 +0800 Subject: [PATCH] fix --- ...w_to_use-1.ipynb => basic-api-usage.ipynb} | 40 +-- docs/usage/complex-filtering.ipynb | 254 +++++++++++++++++ docs/usage/customizing-filters.ipynb | 257 ++++++++++++++++++ docs/usage/execute.ipynb | 210 ++++++++++++++ mkdocs.yml | 10 +- 5 files changed, 749 insertions(+), 22 deletions(-) rename docs/usage/{how_to_use-1.ipynb => basic-api-usage.ipynb} (70%) create mode 100644 docs/usage/complex-filtering.ipynb create mode 100644 docs/usage/customizing-filters.ipynb create mode 100644 docs/usage/execute.ipynb diff --git a/docs/usage/how_to_use-1.ipynb b/docs/usage/basic-api-usage.ipynb similarity index 70% rename from docs/usage/how_to_use-1.ipynb rename to docs/usage/basic-api-usage.ipynb index 044f41c2..8b19b72c 100644 --- a/docs/usage/how_to_use-1.ipynb +++ b/docs/usage/basic-api-usage.ipynb @@ -47,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -57,7 +57,7 @@ "AVStream(node=InputNode(kwargs=(('t', 20), ('ss', 10)), inputs=(), filename='input.mp4'), index=None)" ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -85,7 +85,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -95,7 +95,7 @@ "OutputStream(node=OutputNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input.mp4'), index=None),), filename='output.mp4'), index=None)" ] }, - "execution_count": 5, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -118,7 +118,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -128,7 +128,7 @@ "OutputStream(node=OutputNode(kwargs=(('t', 20), ('ss', 10)), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input.mp4'), index=None),), filename='output.mp4'), index=None)" ] }, - "execution_count": 7, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -149,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -159,7 +159,7 @@ "OutputStream(node=OutputNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input1.mp4'), index=None), AVStream(node=InputNode(kwargs=(), inputs=(), filename='input2.mp3'), index=None)), filename='output.mp4'), index=None)" ] }, - "execution_count": 9, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -184,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -194,7 +194,7 @@ "OutputStream(node=OutputNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input1.mp4'), index=None), AVStream(node=InputNode(kwargs=(), inputs=(), filename='input2.mp3'), index=None)), filename='output.mp4'), index=None)" ] }, - "execution_count": 11, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -221,19 +221,19 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name '_show' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[12], line 13\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[38;5;66;03m# Merge the outputs into a single operation\u001b[39;00m\n\u001b[1;32m 12\u001b[0m stream \u001b[38;5;241m=\u001b[39m ffmpeg\u001b[38;5;241m.\u001b[39mmerge_outputs(output1, output2)\n\u001b[0;32m---> 13\u001b[0m \u001b[43m_show\u001b[49m(stream)\n", - "\u001b[0;31mNameError\u001b[0m: name '_show' is not defined" - ] + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiQAAACDCAYAAAC9dQAPAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO3deVxU9f748dewDsoy5sKAmYikAmISXnMHrmJeQbuKokjLTU27ZmXo15uSpd7UvGG53VyQ660kxUh+mVHKdUlzK3BJAQP3lBCVzYWd+f0xDYqgDDAwCu/n43EewJlzzuf90Qczbz6rQqPRaBBCCCGEMCITYwcghBBCCCEJiRBCCCGMThISIYQQQhid2b0nLl26xIEDB4wRizCwPn368Pjjjxs7DFFLBw8e5LfffjN2GMIIgoKCjB2CEA1Oce+g1s2bNzNmzBhjxSMMKDo6Wt7YHmGjR48mJibG2GEII5C5BqIpqtRCorMmoSHDEIY2uYexIxCG8PTAUUxe/KWxwxANJCF+MxGz5A9C0TTJGBIhhBBCGJ0kJEIIIYQwOklIhBBCCGF0kpAIg+nYsSNRUVHGDsNgjh07hr+/PyqVChsbGwYNGsT+/fuNHZYQQjRKkpAIg1EqlVhaWho7DIM4fPgwffr0wcbGhpSUFM6dO4ezszM+Pj7s2LHD2OEJIUSjIwmJqLXo6GgGDx7ML7/8AoClpSWWlpYUFRXx0Ucf4evrS1FRkZGjrLmysjImTJiASqVi/fr1ODg40KpVK1atWkXHjh2ZOHEihYWFxg5TCCEaFUlIRK35+PjQv39/hg0bxsSJEykoKCA+Ph4PDw/27dvH7NmzMTc3r9cYPD09Wbx4MRcvXjTYM/fu3UtSUhKjRo3Cysqq/LypqSnBwcH89ttvbNu2zWDlCSGEkIRE1IG9vT1z5swhNTWV4uJiUlJS2LhxI+vWrSM2NhY/Pz8UCkW9xuDg4EBYWBhOTk74+PgQERFBTk5OnZ65a9cuAHr0qLyYi+7czp0761SGEEKIiiQhEbWWmZnJokWLcHNzw8zMDFdXV4KDgxk/fjzDhw9nx44d1a44aWZmhkKh0OtQq9WV7o+Li+PSpUuEh4eTl5fHpEmTUKvVjBw5ki1bttSqa+XUqVMAVS6737ZtWwBSU1Nr/FwhhBD3JwmJqLXdu3eza9cuYmNjiYyMRKlU4ufnR1JSEt7e3ixatKjaMSQlJSVoNBq9joyMjCqfoVarCQ0N5ciRIyQnJxMaGkpiYiKBgYGo1WpeeeUV9uzZo/dy3LoWlubNm1d6zdraGoDs7Gy9niWEEEI/kpCIWhszZgzx8fF069YNgMLCQgoLC7GwsGD69Ons3r27wWfduLq6snDhQs6fP8+ePXsYNWoUMTEx+Pr60r179zo/X5fU1HdXlBBCNDWSkAiDKSwspKCgwNhhANqEQalUolQqazywVqVSAXDr1q1Kr+nO6a4RQghhGPfdXE+Imjp9+nSN7zEzM6O0tFSva+3t7e/bbaOTmppKVFQUUVFRnDlzBpVKRWBgICEhIfj4+OhVTpcuXQC4dOlSpdcuX74MQKdOnfR6lhBCCP1IC4kwKkOMIbly5QrLly+nZ8+edO7cmQ8++AAPDw9iYmLIyMhg3bp1+Pr66t3N4uvrC0BiYmKl13TnBg4cWMsaCyGEqIpBEpK4SHijvyGeVD80ZXDqJ/h0Hrw5ACb3gOvpxo7qwVbN0Mb537nGjuTh5u/vT9u2bZk2bRpWVlasWbOGjIwMYmNjCQwMrNUYFm9vb9zc3IiJianQBVVaWsqmTZto164d/v7+hqyGuA9NWRmnftrJp/Ne5s0BtkzuoeB6+nljh/VAq2aMYHIPBf+d+zdjhyLEI6VRtZB8/QlM86l8/txJ+G49uHiC3wsNHlaNJcRD6hEwq981xRqF9PR03n//fc6fP88PP/zApEmTaNGiRZ2eaWJiQmRkJFlZWbz88stkZGRw/fp1XnvtNdLS0oiIiECpVBqoBg+3rz95h2k+9T9e5n7lnDt5mO/WL8TFsz9+L8yo9zjqKiF+M6lHfsDM3MLYoQjxyDFIQjJ0AizfZ4gn1Q/nbvDWKug7HKwqz+R8qNzKhU0fwojXwFRG+FTr6NGjvP322zzxxBMGfW6vXr04cOAAubm5dO7cGScnJ9LS0tizZw/PPvtsjZ6VnZ1Nfn6+QeNrKpy79eatVTvpO3w8Vs1tjR3OA93Kvc6mD19nxGsLMZW/JoSosXrpsolZCv83GG7maLse3ugP/xgKuzZVvE93Xc5VWP4GvN4PZgXA/76oeN1/5sDCKlo2lkyCT6Zrv9+8BOL+A/k3tV0dk3toy6wrXYx5WbBymrYuc4Mg7aj29RM/wrwgmNoHPnoVcjJrV0ed6CXQUg39R9Q9dlE3np6exMXFkZuby40bN9i5cyd9+/at8XP27dtH69atef7554mLi6O4uLgeor3j1E87+deEfkzt24w3ve34d+hwMs6fqnDNf+Y8z8IXKq9Eu2SSD59M/ysAm5dMI+4/C8i/mcvkHgom91Dwj6HaxeJils7g/warybmazvI3/sLr/ZozK6A9//viY4OWUxe6GPOyrrByWgBv9LdmbpA7aUe1fz2d+PFb5gV1ZWofKz569c/kZF6u8v7q6qgTvWQaLdXt6T9iUp1jF6IpqrcuGw3aJGFQCCz+Dv48FqLD4ewvla/b9CEMHa+9bugE+GoZ7IutWXlB07XPsLKGNQnaY3Gc4eoSsxQCXoEPvgWX7tpE6NRPcHQXvLkS3o2G7EzY+K+q79enjicPwE/fw7i3QdGoOtPErVu3iI6Oxt/fn9atWzNlyhT27dtHWVmZQcs59dNOlk19lvauXizcepawDYkUF+Tzr/F9ycqo2X4/QdOXMnR8GFbWdqxJ0LAmQcPiuDszjzRo2PTh6wwdH8bi7y4zdMI7fLVsJvtiIwxaTl1o0BCzdAYBr7zLB9/+hkv3fnwy/TlO/bSTo7u28ObK7bwbfYLszEts/NfUKu/Xp44nD3zHT99/wbi3P0FhIr+8QtRGvf3m3MiCnn+BJz21ScKzL0IrRziwrfJ1vf21H/LNbLQtA70DYNtaKNNvNmi9u5GljcnJHZrZwl+nQP4NiFoE42aBqg20aQcDg+H4Xm0rTaX7q6ljwW3YsAC8A6G9W8PXUdS/kpISAHJzc4mMjGTAgAGo1WrefPNNfvzxR4OU8fWqd3Ds6M6YGcuwbammTTsXXlm0ieKiArZ/VkW2XAc3sjLp7f8iLt370cxGRf8Rr9A74CW2rZ1LWWmJQcuqrRtZmfQOeAkn9540s23BX6csIP9GDlGLXmXcrFWo2rSlTTsXBgZP4/jereTfzK18fzV1LLh9gw0LJuMd+Crt3Sq3Bj3sOnbsSFRUlLHDMJhjx47h7++PSqXCxsaGQYMGsX//fmOHJfRQbwmJiQm4PVPxnLpD5dktCgW496l4zqOftovj2kMyE8bEBDrf9T5jrdImJk+4Vhx4at9eO6Mn657ZqfrU8atlUFIMz02pnzqIh4tuSf2rV6+yevVq+vfvj4uLC3Pnzq31PjnFRQWcS/oJj/4BFc43t2tJx6f6kpqwp65hV6BQKHDv85cK5zz6+ZNzNZ1rD8lMGBMTUzr38C3/2VrVima2j/GEq1eFgaf27TuhKSur1IqkTx2/WjaTkuJCnpuyoP4qUo+USmWDr6hcXw4fPkyfPn2wsbEhJSWFc+fO4ezsjI+PDzt27DB2eKIa9TZssrkKTEwrnlM2r5yQWFlXnk1i+5j2a85VbcvD/ei3M0ndNVdpk5K7KZvdiVPH8o+d6u9tIamujpoy2LcF/jZP24JiKIcOHZIlzh8CCQkJD3xdl5ycOXOGBQsWMG/ePLp3745Go6HMRv+xFPk3ctCUlWHTok2l12xb2nP59Ilqn6GpwW+VlbVdpdkkto9py865epk27VwMUk5dNFe1xOSeNyJlM2tsH7OvcM7SSrtH0b0tJNXVUVNWyr4ta/jbvE9pZvNorN4bHR1NZGQk4eHhdOvWDUtLSywtLSkqKmLlypV88803bN++HQuLR2umUFlZGRMmTEClUrF+/XqsrLRvyKtWrWLv3r1MnDiRtLS0RpN8NUb1lpDo+zGYf1PbMnD3B3ZelvarqrX2q7K5tkvjXrnXDPsBfj/3q4u+n/XV1fFmDmg0sP5d7XG3g9u0xxvLK7eyVGfZsmV8/HHVA/DEw0nXrXPs2DEUCgXWqnQunz5BWxePau+1slGhMDHhZvbVSq/dyMrE2q5l+c/K5rYU3L5Z6brca7/TzEa/adP5N3MpKS6q8IGdl6Ud1a1q3dZg5dSF4j6/vfom6tXV8WbONTQaDevffZH1775Y4d6D2z7l4LZPeWP5d7j3GVLLGhiej48PqampDBs2DD8/PwoKCoiPj2fGjBm4ubkxe/bsGm+3UFOenp6MHTuW4OBgg82Q27t3L0lJSbz++uvlyQiAqakpwcHBzJ07l23bthEYGGiQ8oThGX30lUYDSQcrnju5H+xaacecgPZrVgYU3jVzMvM3uHbPuDcLpfaD/2FTXR2dPe4MxL37sLTSjjVZk1DzZARg48aNeq+CKkf9HV9//bVe/1+6DwEXFxfee+89hgwZwpNPe+uVjACYWyjp4N6TEz9+W+H8rbwszhzfTycv7/JzrRw7kJVxkcL8O/v1ZP52mmuXzla410LZjJLiqnds1mg0JB38vsK5k/vjsGvlQCtHJ4OVY0zV1dHZo1f5QNy7D0ur5vQOeIk1CZqHKhkB7RYMc+bMITU1leLiYlJSUti4cSPr1q0jNjYWPz+/em9ZdXBwICwsDCcnJ3x8fIiIiCjfZbu2du3aBUCPHpXH8ejO7dy5s05liPpl9ITEpgUc2gZnjmtbEvZ/rW0RCJh0p8vnT0O0gz9jV8LtG3D5NMSugHadKz5L3QGKC+HXBG03SE0lHdBOFz5soNk5OvrUUTRNuiTE0dGR0NBQUlJSSEtLY+7cuTRvXvNFc4a/Op/Lp0+w+aO3yMu6wrXLZ1k3OxhTM3MGvziz/Lo/DQmmrLSE2JWzuH0jh8unTxC74m3ada64I7K6gyvFhfn8mrAbzT0zgmxatObQts84c3w/+Tdz2f91JAe3fUrApPcw+WMRHUOUo4+kA98zuYeCw3Ebanzvg+hTx0dNZmYmixYtws3NDTMzM1xdXQkODmb8+PEMHz6cHTt2lO9qfT9mZmYoFAq9DrVaXen+uLg4Ll26RHh4OHl5eUyaNAm1Ws3IkSPZsmULhYWFNa7XqVPaqe2PP165m7NtW22LXW3HZ4mGYfTfKIUCgmbAZ/O1a3tY28GIqTBg5J1rWrSBiQu1Sci+WOjgDi+8o52Vcrfu3trFz1bPhNt52tkvi+O0yczf7xlgO3u49qtHP5i61Ph1FE2HhYUFRUVFtGrVinHjxjF69Gj69u1rkL9KXZ/x440V3/HNmrnMDnDC1MycTl7ezIzcT0uH9uXXtWjzOBMXbiR2xdvsi11LB/eevPBOBBsWTK7wvO7ez9F3+HhWzwzkdl42qjZty6fkKhQmBM1YymfzJ5B2dB/Wdi0ZMXURA0ZONlg5ZaUl/P2Zit0Hs4d3ALSDS6cuvWfanoHpU8dHze7du9m1axexsbF069aNp59+Gj8/P8LDw1mxYgWLFi3C29v7gWMtdF2LdaFWqwkNDS1PxD///HOioqKIjY1FpVIxatQoQkJC8Pb21ut3Q9fCUlUib22tHSOUnZ1d57hF/VFo7kmFN2/ezJgxY1jz4HF4BhGzVNsa8WEjHvxsrDpO7qEdvBYUFNSwBYtKtm7dynPPPQeAjY0NQUFB5W+0Jg9Ys2L06NGczYbJi79sqFD1FrN0BofjNvDhjgfvvvwoM0YdE+I3EzFrTLUtFIbk7u7OvHnzGDVqVIOVeT8ajYa9e/eyYcMGYmJiyMnJoVu3bhw/frzaewcPHkx8fDyHDh3imWcq/gWalpZGp06d8PLyqnaQuTAeo7eQCNHYWVlZlQ/gGzJkyCM3e0E0boWFhRU2kTQmhUKBUqlEqVTWeGCtSqWd5XTr1q1Kr+nO6a4RDydJSISoZ35+fvj5+Rk7DCGqdPr06RrfY2ZmRmmpfitX2tvbk5Hx4Fam1NRUoqKiiIqK4syZM6hUKgIDAwkJCcHHx0evcrp06QLApUuVV/m9fFm7LUCnTp30epYwDqMOah01rXF310DTqKNoekZNC2/U3TXQNOpYWyUlJXrPMrtfMnLlyhWWL19Oz5496dy5Mx988AEeHh7ExMSQkZHBunXr8PX11Xtsla+vdgG8xMTESq/pzg0cOLCWNRYNweizbIQQQjQt/v7+tG3blmnTpmFlZcWaNWvIyMggNjaWwMDAWi1e5u3tjZubGzExMRW6oEpLS9m0aRPt2rXD39/fkNUQBiYJiRBCiAaVnp7O+++/z/nz5/nhhx+YNGkSLVrUbaE8ExMTIiMjycrK4uWXXyYjI4Pr16/z2muvkZaWRkREBEql0kA1EPVBxpAIIcRD5tVXX8XDwwN3d3c8PDxo2bJl9Tc9Qo4ePVovz+3VqxcHDhwgLCyMzp07U1ZWRs+ePdmzZw99+/atlzKF4UhCIoQQD5mUlBQ2b95cvm6GWq2ma9eudO3atTxJcXNzw8amAfbOeMR4enoSF2fg1S1raPPmzUYt/1HQp0+fSovYSUIihBAPmR9++AHQLuSVlJREcnIySUlJ/Pzzz6xbt46bN7X7Azk4OODu7o6bm1v516effppmzZoZM/wmb8yYMcYO4aFX1TpZkpAIIcRDqkWLFvTr149+/fpVOJ+enl6epCQmJrJ//34iIiLIz8/HzMyMJ554okKS4u7uTteuXWWn2wYUHh7Os88+a+wwHkoeHlXvzyUJiRBCPGIcHR1xdHRk0KBB5edKSkq4ePFihRaVb775hvDwcEpLSzE3N+fJJ5+s1KLi6ur6wBWDhWgokpAIIUQjYGZmhrOzM87OzgwbNqz8fFFREWlpaeVJSnJyMl9++SXz589Ho9FgY2NDp06dKrWoODs7G7E2oimShEQIIRoxCwsL3N3dcXd3Z/To0eXn8/LySEtLq9CismzZMn7//XdA2110b5Ly1FNP0bp1a2NVRTRykpAIIUQTZGtri5eXF15eXhXO3zuQNjk5mS1btnDt2jXgTqLi5eVVnqx4enpWucuuEDUhCYkQQohy+gykTU5OJjExkXXr1nH79m1AO+Pn7iRF1yoji5EJfUlCIoQQolpVDaQtLS3lwoULFVpU/ve//7F06VIKCwsxNzenXbt2lVpUZCCtqIokJEIIIWrF1NS0yoG0xcXFpKamVhpI+89//pOysjIsLCxwcXGp1KLSoUMHvTfTE42PJCRCCCEMytzcvMqBtLoZP4mJieXJytq1azl79iwAdnZ2uLi4VGhR8fDwwN7e3lhVEQ1IEhIhhBAN4u4ZP3fLycnh5MmTFVpUFi5cSGZmJlB5xo+Xlxfdu3fH2tq63mOOjY1l0KBBskx/A7hvQpIQ35BhCCGqkpN5iYR42RejqTh74qCxQzAKlUpV5UBa3Yyfu1tUvvjiiyqXzr+7+8fKyspgsYWGhpKXl8fChQuZMGECZmbyd3x9ue+/bMSshgxDCFGVsycOcXaW7IshmqaaLJ2/du1aCgoKqlw638vLiy5dumBqalqj8m/fvs2FCxfQaDRMmTKFJUuW8PHHH+Pv72/Iaoo/KDQajcbYQQghhBB1cffS+Xe3qPz6668PXDrfzc3tvgNpf/75Z3r27Fn+s4mJCWVlZQwYMIClS5fi6elZ5X0KhUL2snkADw8P2VxPCCFE46Tv0vmJiYl8/vnnnDt3Do1Gg62tLU8++WSFJKVHjx44ODhw8uRJTE1NKS0tBaCsrAyAAwcO4OXlxciRIwkPD8fJyckYVW50JCERQgjRaN1v6Xzd+JSTJ09y8uRJkpKSiIuL4/r16wC0adMGOzu7CgmJTklJCQBbt27lm2++4a233mLWrFnY2dk1XMUaIUlIhBBCNDn3G5+SkZFRnqT8+9//pqio6L7PKC4uBmDJkiWsXr2aefPm8dprr9Vr3I2ZLJUnhBBC/EGtVjNo0CCmTZtGbm6uXveUlJSQm5vLW2+9hZubWz1H2HhJQiKEEELcIzs7m6tXr+p1rYWFBWZmZmg0GtLS0gDYuXNn+ZgToR/pshFCCCHukZSUVOmcbg0S3RgSOzs7unbtSvfu3enatSuurq507dqVVq1aMXDgQNmvp4YkIRFCCCHucfLkyfLvbW1t6dq1K0899VR54uHh4UGrVq2MGGHjIwmJEEI0YR07dmT+/PmEhIQYOxSDiYuLY9q0aZw9e7a8NaOmevTowc6dO+natStt2rQxcISiKpKQCCFEE6ZUKrG0tDR2GAZx5swZ3nrrLS5cuMCVK1fq9KwePXoYKCqhL+ngEkKIJiQ6OprBgwfzyy+/AGBpaYmlpSVFRUV89NFH+Pr6PnCq68Nszpw59OnTh8TERNkM7xEkLSRCCNGE+Pj4kJqayrBhw/Dz86OgoID4+HhmzJiBm5sbs2fPxtzcvF5j8PT0ZOzYsQQHB/PEE08Y7LmRkZEG3VhPNCxpIRFCiCbE3t6eOXPmkJqaSnFxMSkpKWzcuJF169YRGxuLn5/fffd2MRQHBwfCwsJwcnLCx8eHiIgIcnJy6vxcSUYebZKQCCFEE5KZmcmiRYtwc3PDzMwMV1dXgoODGT9+PMOHD2fHjh1Ut+eqmZkZCoVCr0OtVle6Py4ujkuXLhEeHk5eXh6TJk1CrVYzcuRItmzZQmFhYX1VXzzEJCERQogmZPfu3ezatYvY2FgiIyNRKpX4+fmRlJSEt7c3ixYtqnYMSUlJCRqNRq8jIyOjymeo1WpCQ0M5cuQIycnJhIaGkpiYSGBgIGq1mldeeYU9e/ZUmxyJxkMSEiGEaELGjBlDfHw83bp1A6CwsJDCwkIsLCyYPn06u3fvbvBZN66urixcuJDz58+zZ88eRo0aRUxMDL6+vnTv3r1BYxHGIwmJEEI0YYWFhRQUFBg7DAAUCgVKpRKlUlnvA2vFw0dm2QghRBN2+vTpGt9jZmZGaWmpXtfa29vft9tGJzU1laioKKKiojhz5gwqlYrAwEBCQkLw8fGpcXzi0SQJiRBCiBqp7eqnd7ty5QrR0dFs2LCBn3/+GQsLC4YOHcrixYsJCAhoNIu1Cf1JQiKEEKJB+fv7s337dsrKyujfvz9r1qxh9OjRtGjRwtihlTtx4gTm5uY4ODhgZ2dn7HCaBElIhBBCNKj09HTef/99xo0bZ9CF0QxpxYoVREREAGBhYUGLFi1wdHTE0dERtVqNg4MDbdq0wd7eHrVaTZs2bVCr1ahUKiNH/uiShEQIIUSDOnr0aL08d9u2bQwbNqzCOd0ibxEREUycOFHvZ+kWbAMoKiriypUrXLlyhaNHj2JmZoapqSllZWXlU6B1dINxf/jhBwYPHlzvi8w1JpUSkkuXLnHgwAFjxCIMrE+fPjz++OPGDkPU0sGDB/ntt9+MHYYwgqCgIGOH8EgKCAgw2LolDxpMW1JSUuU4GoVCga2tLdevX8fb21uSkRqqlJAcOHCAMWPGGCMWYWDR0dHyxvYI++ijj4iJiTF2GMII5PfW+BwdHXFycuL8+fPVXmtiYkJZWRkjR45k9erVtG7duv4DbITu22WzJqEhwxCGNll2zm4Unh44ismLvzR2GKKBJMRvJmKW/EFobFlZWRw6dIh27dqRnp7+wJVrzc3NsbW1JSIighEjRjRglI2PjCERQgjRZJWUlHDy5EkOHjzIoUOHOHz4MKmpqWg0Gtq1a0dxcXGV9+laRYYPH87atWt57LHHGjjyxkcSEiGEEE3GhQsXOHLkCIcPH+bQoUMkJCRw69YtbG1t6dmzJ6NHj6ZXr14888wzlJSU4OjoWOkZZmZmqFQqIiMjGT58uBFq0ThJQiKEEKLRKS0tJS0tjaNHj5YfR44cISsrCxMTE1xdXenVqxcvvPACzzzzDG5ubpiYVN5NpUOHDpw9exagfGbN2LFjWb58+UO1bkpjIAmJMJiOHTsyf/58QkJCjB2KQRw7doywsDD2799PaWkpzzzzDPPmzaNv377GDk0IcZfCwkKSkpIqJB/Hjx/n1q1bmJub4+7ujqenJ8OHD8fT05OnnnoKGxsbvZ797LPPsnbtWhQKBWq1mv/+978MHDiwnmvUNElCIgxGqVQ2muWeDx8+jK+vL8OHDyclJQVzc3Nmz56Nj48P3377LYMHDzZ2iEI0Senp6SQnJ5OUlERiYiLJycmcPHmyfMdiFxcXvLy8CAoKwsvLCy8vL6ysrGpdno+PD2vWrOHVV1/lgw8+wNra2oC1EXeThETUWnR0NJGRkYSHh9OtWzcsLS2xtLSkqKiIlStX8s0337B9+3YsLCyMHWqNlJWVMWHCBFQqFevXry9/M1u1ahV79+5l4sSJpKWlNZrkS4iHUV5eHsnJyfzyyy/lx4kTJ8jJyQHAyckJDw8Pnn32WWbOnImHhwedOnXC1NTUoHH4+vqye/duBgwYYNDnisokIRG15uPjQ2pqKsOGDcPPz4+CggLi4+OZMWMGbm5uzJ49u963EPf09GTs2LEEBwcbbAnqvXv3kpSUxOuvv17hLytTU1OCg4OZO3cu27ZtIzAw0CDlCdGUZWdnc/bsWZKSkspbPpKTkzl37hwajQYbGxs6deqEm5sbgYGBuLu789RTTzXYWh+tW7eWdUUaiCQkotbs7e2ZM2cOM2fOZNKkSaSkpHD16lW2bNlC//79GyQGBwcHwsLCmDVrFgMGDCAkJITRo0fXaT+JXbt2AdCjR+XFXHTndu7cKQmJEHrSaDRcuHCBU6dOkZSUxKlTp0hJSSElJYWsrCwAVCoVXbp0wd3dnQEDBuDm5oarqysdOnSQFU+bCElIRK1lZmYSGRnJunXr8PHxwdXVlUGDBjF+/HhcXV2ZOnUqfn5+D3wzMTMzo7S0VK/y7O3tycjIqHAuLi6OjIwMvvjiCzZs2MCkSZN4/fXXGTp0KM8//zz+/v417lo5deoUQJXL7rdt2xaA1NTUGj1TiKagpKSEixcvlrdy6JqqJRwAAA+qSURBVFo+jh8/zs2bNwFo0aIFbm5uuLu7M2zYsPLvJfEQkpCIWtu9eze7du0iNjaWbt268fTTT+Pn50d4eDgrVqxg0aJFeHt7PzAhqGo/iJpSq9WEhoYSGhpKSkoKn3/+OVFRUcTGxqJSqRg1ahQhISF67y2h66Nu3rx5pdd0A9qys7PrHLcQj6orV65w+vRp0tLSSEtL49dffyU5OZnTp09TXFyMiYkJTk5OdOnShd69e/Pyyy+Xt3g0ld1wjx8/buwQHjmSkIhaGzNmTIV9jwoLC8tHuk+fPp3p06c3eEyurq4sXLiQBQsWsHfvXjZs2EBMTAzr1q2jW7dudX6T0G3cJX/JicYuPT2d06dPV3ncuHED0M6s69ixI66urgQGBuLm5kaXLl3o0qVLnWa2NAaff/45n3/+ubHDeKRIQiIMprCwkIKCAmOHAWgTBqVSiVKprPHAWt1fcLdu3ar0mu5cU/krTzRuugGldw8qPXv2LKmpqeVJh4WFBY8//jjOzs786U9/4qWXXsLd3R1nZ2fat29v8FktjYGhdhxuaiQhEQZz+vTpGt9T1zEk90pNTSUqKoqoqCjOnDmDSqUiMDCQkJCQB24nfrcuXboAcOnSpUqvXb58GYBOnTrp9SwhjKmoqIiLFy9y/vx5zpw5U97Cofs+Pz8f0HZFuri44OLigp+fH3//+9/Lf9aNmxKivklCIozKEGNIrly5QnR0NBs2bODnn3/GwsKCoUOHsnjxYgICAmo8qNXX15d//vOfJCYm8uKLL1Z4LTExEUBWahQPjbtbOe49Lly4UJ7wK5VKnJ2dcXd3Z+jQoTg7O5cfMqBUPAwMkpDERcL3/4Xl+wzxNMPLyoC9X8HxvXDtMti1gq59YdgkaG5n7OiqtmoGHNsDvQPgb3ONHc3Dy9/fn+3bt1NWVkb//v1Zs2YNo0ePrtMeE97e3ri5uRETE8PixYtRKpWAdm+MTZs20a5dO/z9/Q1VBfEAWRkX2fvVao7v/YZrl89i18qBrn2HMmzSezS3a2ns8Kq0asYIju35f/QOeIm/zf1vnZ/3oITj4sWL5Um9paUlbdu2LU8yBg0ahIODA46OjpJ0iEdCo2oh+foT2L0Zlu6peH79u3AjG0aHgkt3+P0cfDoXkg/CO1+AhdIY0d5fQjykHgGz+l1TrFFIT0/n/fffZ9y4cQZbGM3ExITIyEh8fX15+eWX+fjjjzE3NycsLIy0tDS2bdtWnqQ0dl9/8g67N69k6Z4co5Sz/t0XuZGdyejQj3Hp3o/fzyXz6dyXST64nXe+OIqFslm9xlVTCfGbST3yA2bmdVud2M/Pj/Pnz3Px4kWKiooAbcLh5OSEk5MTHTt2ZODAgTg5OdGhQwecnJywt7c3RBWEMBqDJCRDJ2iPh5VrLxgYDJZ/DPp2coOQ2fDhRDiyE3o9RH/s3sqFTR/CiNcgZqmxo3n4HT16tF6e26tXLw4cOEBYWBidO3emrKyMnj17smfPnhpvrpednY1SqWzysw5qw7WXHwODp2FppZ2C7eT2J0Jmr+bDif05sjOGXv4vVvOEhnMr9zqbPnydEa8tJGbpjDo9y8nJCR8fn/IEpEOHDjg4OEgLh2jUKu+1XAtxkfDGXQtzxiyF/xsMN3O0XQ9v9Id/DIVdmyrep7su5yosfwNe7wezAuB/X1S87j9zYOELlctdMgk++WNm6eYlEPcfyL8Jk3toj38M1b42dPydZESn1R/jtK7//uC66WLMy4KV07R1mRsEaX98Dp74EeYFwdQ+8NGrkJNZuzrqRC+BlmroP+LBcYn65+npSVxcHLm5udy4cYOdO3fWaqffffv20bp1a55//nni4uIoLi6uh2jvOPXTTv41oR9T+zbjTW87/h06nIzzpypc8585z7Pwhcor0S6Z5MMn0/8KwOYl04j7zwLyb+YyuYeCyT0U/GOodrG4mKUz+L/BanKuprP8jb/wer/mzApoz/+++Nig5QwdH1aejOi0ausMwPXfLzzw30EXY17WFVZOC+CN/tbMDXIn7ai2b/nEj98yL6grU/tY8dGrfyYn83KV91dXR53oJdNoqW5P/xGTHhiXPiIiIggLCyMkJIS+ffvi6OgoyYho9AySkFRFgzZJGBQCi7+DP4+F6HA4+0vl6zZ9qE0aFn+nbWn5ahnsi61ZeUHTtc+wsoY1Cdpjcdz9r086qP3aSo8B5Bq0iUXAK/DBt9pun0+mw6mf4OgueHMlvBsN2Zmw8V9V369PHU8egJ++h3Fvg6Le/meEMdy6dYvo6Gj8/f1p3bo1U6ZMYd++fZSVlRm0nFM/7WTZ1Gdp7+rFwq1nCduQSHFBPv8a35esjIs1elbQ9KUMHR+GlbUdaxI0rEnQsDjuzswjDRo2ffg6Q8eHsfi7ywyd8A5fLZvJvtgIg5Zzr6SD3wN3EpMH0aAhZukMAl55lw++/Q2X7v34ZPpznPppJ0d3beHNldt5N/oE2ZmX2PivqVXer08dTx74jp++/4Jxb3+CwkR+eYWojXr7zbmRBT3/Ak96apOEZ1+EVo5wYFvl63r7az/km9loWwZ6B8C2tVCm32zQGruZA1tXQQt7ePrP+tWldwA4uUMzW/jrFMi/AVGLYNwsULWBNu203ULH92pbaWpax4LbsGEBeAdCezfD11kYn27wYW5uLpGRkQwYMAC1Ws2bb77Jjz/+aJAyvl71Do4d3RkzYxm2LdW0aefCK4s2UVxUwPbPqsiW6+BGVia9/V/EpXs/mtmo6D/iFXoHvMS2tXMpK6377Kmq3My5xtZVc2hh346n/zxSvxgDXsLJvSfNbFvw1ykLyL+RQ9SiVxk3axWqNm1p086FgcHTOL53K/k3c2tcx4LbN9iwYDLega/S3q1ya5AQQj/1lpCYmIDbMxXPqTvA9fSK5xQKcO9T8ZxHP20Xx7V7rjWE0hKImKUd5Dp+PpjrMSPUxAQ63/U+Y63SJiZPuFYceGrfHjRl2lk9d9Onjl8tg5JieG5K7eolHi26gYpXr15l9erV9O/fHxcXF+bOnVvrfXKKiwo4l/QTHv0DKpxvbteSjk/1JTVhT13DrkChUODe5y8Vznn08yfnajrX0s8btCyA0pJiImaN4Ub2VcbP/wzze/thq2BiYkrnHr7lP1urWtHM9jGecPWqMPDUvn0nNGVllVqR9KnjV8tmUlJcyHNTFtShdkKIeptl01wFJvcs4KdsXjkhsbKuPJvE9jHt15yr2paH+6npWngaDax/D35NgPH/hE5e+t3XXKVNSu6mbHYnTh3d++O9LSTV1VFTBvu2wN/maVtQDOXQoUPS7/wQSEhIeODruuTkzJkzLFiwgHnz5tG9e3c0Gg1lNpU3+Luf/Bs5aMrKsGnRptJrti3tuXz6RLXP0NTgt8rK2q7SbBLbx7Rl51y9TJt2LgYpB7QrX65/7yV+TdjN+H9uoJOXj173NVe1xOSeNyJlM2tsH6s4I8XSSrtH0b0tJNXVUVNWyr4ta/jbvE9pZiOr9wpRF/WWkOj7MZh/U9sycPcHdp52N2pUrbVflc21XRr3yr1Wsw/wLz+Gn7dD8EzoOUT/++5XF30/66ur482cP5Kld7XH3Q5u0x5vLK/cylKdZcuW8fHHVQ/AEw8nXbfOsWPHUCgUWKvSuXz6BG1dPKq918pGhcLEhJvZVyu9diMrE+u71u1QNrel4PbNStflXvudZjb6reGSfzOXkuKiCh/YeVnaUd2q1m0NVg7Alx+H8vP2jQTPXEnPIeP0vk9xn99efRP16up4M+eaNll690XWv1txxs/BbZ9ycNunvLH8O9z71OANR4gmyuijrzSaOwNMdU7u1y5e1spR+3MrR203SGH+nWsyf4Nr94x7s1BqP/ir8t162PmFtkvEJ8hw8eujujo6e9wZiHv3YWmlHWuyJqHmyQjAxo0b0Wg0chj5+Prrr/X6/9LtuePi4sJ7773HkCFDePJpb72SEQBzCyUd3Hty4sdvK5y/lZfFmeP76eTlXX6ulWMHsjIuUph/Z7+ezN9Oc+3S2Qr3WiibUVJcVGV5Go2mfICpzsn9cdi1cqCVo5PByvlu/SJ2frGU56a8j0/Qa/epff2oro7OHr3KB+LefVhaNad3wEusSdBIMiKEnoyekNi0gEPb4MxxbUvC/q+1LQIBk+50+fxpiHbwZ+xKuH0DLp+G2BXQrnPFZ6k7QHGhtktGc9fkhQNb4f/9G/ye1850uZ+kA9rpwocfMDunvuoomiZdEuLo6EhoaCgpKSmkpaUxd+5cmjdvXs3dlQ1/dT6XT59g80dvkZd1hWuXz7JudjCmZuYMfnFm+XV/GhJMWWkJsStncftGDpdPnyB2xdu069y9wvPUHVwpLszn14TdaO6ZEWTTojWHtn3GmeP7yb+Zy/6vIzm47VMCJr2HiamZQco5sHU9/+/fs/F7fjpDx4fdt95JB75ncg8Fh+M21Pjf7EH0qaMQwjCM/hulUEDQDPhsvnZtD2s7GDEVBtw1gL5FG5i4UJuE7IuFDu7wwjvaWSl36+4NfYfD6plwO087+2VxHMT/8R4Vv+HO9zo+QdouHGPXUTQdFhYWFBUV0apVK8aNG8fo0aPp27evQcb7uD7jxxsrvuObNXOZHeCEqZk5nby8mRm5n5YO7cuva9HmcSYu3EjsirfZF7uWDu49eeGdCDYsmFzhed29n6Pv8PGsnhnI7bxsVG3alk/JVShMCJqxlM/mTyDt6D6s7VoyYuoiBoycbLBy4jcsASB+w5Ly73V8gl4jeObKOv+bPYg+dRRCGIZCc88+yZs3b2bMmDGsefA4PIOIWaptjfhwR/2XZSzGquPkHhAdHU1QUAP3T4lKtm7dynPPPQeAjY0NQUFBhISE4O3tjckD1qwYPXo0Z7Nh8uIvGypUvcUsncHhuA18uOPBuy8/yoxRx4T4zUTMGiPb14smyegtJEI0dlZWVowdO5bg4GCGDBmChUXd9jkRQojGSBISIeqZn58ffn5+xg5DCCEeakYd1DpqWuPuroGmUUfR9IyaFt6ou2ugadRRiIeJ0WfZCCGEEEJIQiKEEEIIo5OERAghhBBGJwmJEEIIIYxOEhIhhBBCGJ0kJEIIIYQwOklIhBBCCGF0kpAIIYQQwugkIRFCCCGE0UlCIoQQQgijk4RECCGEEEYnCYkQQgghjE4SEiGEEEIYnSQkQgghhDA6SUiEEEIIYXRm93shIb4hwxBCVCUn8xIJ8ZuNHYZoIGdPHDR2CEIYzX0TkohZDRmGEKIqZ08c4uysMcYOQwgh6p1Co9FojB2EEEIIIZo2GUMihBBCCKOThEQIIYQQRicJiRBCCCGMzgz40thBCCGEEKJp+//+JSDdCqdWUgAAAABJRU5ErkJggg==", + "text/plain": [ + "GlobalStream(node=GlobalNode(kwargs=(), inputs=(OutputStream(node=OutputNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input1.mp4'), index=None),), filename='output1.mp4'), index=None), OutputStream(node=OutputNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input2.mp4'), index=None),), filename='output2.mp4'), index=None))), index=None)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ diff --git a/docs/usage/complex-filtering.ipynb b/docs/usage/complex-filtering.ipynb new file mode 100644 index 00000000..534e9a20 --- /dev/null +++ b/docs/usage/complex-filtering.ipynb @@ -0,0 +1,254 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Complex Filtering with FFmpeg\n", + "\n", + "### Introduction to FFmpeg's Filter System\n", + "FFmpeg's versatility and power largely stem from its comprehensive filter system, allowing for complex video and audio processing. The typed-ffmpeg library maintains this capability, providing a user-friendly interface for applying various filters.\n", + "\n", + "### Applying Basic Filters\n", + "Below is an example of how to trim a video and add a text watermark using FFmpeg's filter functions:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "unterminated string literal (detected at line 4) (820833972.py, line 4)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[2], line 4\u001b[0;36m\u001b[0m\n\u001b[0;31m FFmpeg's versatility and power largely stem from its comprehensive filter system, allowing for complex video and audio processing. The typed-ffmpeg library maintains this capability, providing a user-friendly interface for applying various filters.\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unterminated string literal (detected at line 4)\n" + ] + } + ], + "source": [ + "import ffmpeg\n", + "\n", + "# Initialize the input stream from a video file\n", + "input_stream = ffmpeg.input('input.mp4')\n", + "\n", + "# Apply trimming and drawtext filters, then output to a new file\n", + "(\n", + " input_stream\n", + " .trim(start=10, end=20)\n", + " .drawtext(text='Hello World', fontsize=12, x=10, y=10)\n", + " .output(filename=\"output.mp4\")\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This operation is visualized in the accompanying diagram, illustrating the workflow of trimming a video and adding a watermark.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Handling Stream Types with FFmpeg\n", + "\n", + "#### Understanding Typed Filters in FFmpeg\n", + "FFmpeg classifies its filters based on the type of media stream they process: some are intended for video streams, while others are for audio streams. This type-specific approach ensures that each filter operates on the appropriate kind of data. The typed-ffmpeg library enforces this classification through both static type checking (compatible with tools like mypy) and runtime validation, minimizing errors and streamlining filter application.\n", + "\n", + "#### Example: Applying Filters Correctly by Stream Type\n", + "\n", + "Consider the following code where we initialize an input stream and apply different filters:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Initialize an input stream from a video file\n", + "input1 = ffmpeg.input('input1.mp4') # The input stream here is an AVStream, capable of handling both audio and video operations.\n", + "\n", + "# Apply a reverse filter, which is specifically a video filter, to the stream\n", + "video = input1.reverse() # The 'reverse' filter is applied, resulting in a VideoStream output.\n", + "\n", + "# Attempting to apply an audio filter (amix) to a video stream results in an error\n", + "ffmpeg.filters.amix(video) # This line will raise an exception because 'amix' is an audio filter, incompatible with a VideoStream." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "In this example, the `reverse` filter, which is designed for video streams, successfully transforms the input into a reversed video stream. However, when attempting to apply the `amix` filter, which is intended for audio streams, to the reversed video stream, the code will raise an exception. This error occurs because typed-ffmpeg recognizes the mismatch between the stream type (video) and the expected input type for the `amix` filter (audio).\n", + "\n", + "By incorporating these type checks, typed-ffmpeg aids in preventing common mistakes, such as applying an audio filter to a video stream or vice versa, thereby ensuring that filters are applied correctly and efficiently.\n", + "\n", + "### Working with Multiple Inputs\n", + "Certain filters accept multiple inputs. When using such filters with typed-ffmpeg, ensure that the exact number of required streams is passed, as validated by static type checking:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Initialize two input streams\n", + "input1 = ffmpeg.input('input1.mp4')\n", + "input2 = ffmpeg.input('input2.mp4')\n", + "\n", + "# Overlay one stream over the other and output to a new file\n", + "(\n", + " input1\n", + " .overlay(input2, x=10, y=10)\n", + " .output(filename=\"output.mp4\")\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The process of overlaying two video streams is illustrated in the following diagram:\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Handling Multiple Outputs\n", + "Some filters, when applied, generate multiple output streams. typed-ffmpeg facilitates handling these scenarios with clear and concise code:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Initialize input streams\n", + "input1 = ffmpeg.input('input1.mp4')\n", + "input2 = ffmpeg.input('input2.mp4')\n", + "\n", + "# Apply a filter that generates multiple outputs\n", + "video, feedout = input1.feedback(input2) # Generates two output streams\n", + "\n", + "# Process and output each stream separately\n", + "o1 = video.drawtext(text='Hello World', fontsize=12, x=10, y=10).output(filename=\"output1.mp4\")\n", + "o2 = feedout.drawtext(text='Hello World', fontsize=12, x=10, y=10).output(filename=\"output2.mp4\")\n", + "\n", + "# Merge the outputs\n", + "ffmpeg.merge_outputs(o1, o2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The generation of multiple output streams from a single filter application is depicted below:\n", + "\n", + "\n", + "### Dynamic Input Filters\n", + "Some filters accept a variable number of inputs. In these cases, typed-ffmpeg offers flexibility but requires careful input management:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Correct usage with the expected number of inputs\n", + "input1 = ffmpeg.input('input1.mp4')\n", + "input2 = ffmpeg.input('input2.mp4')\n", + "ffmpeg.filters.amix(input1, input2, inputs=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Incorrect input numbers will trigger exceptions, providing immediate feedback without needing to execute FFmpeg:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Incorrect usage leading to a ValueError\n", + "input1 = ffmpeg.input('input1.mp4')\n", + "input2 = ffmpeg.input('input2.mp4')\n", + "f = ffmpeg.filters.amix(input1, input2, inputs=3) # This will raise a ValueError" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Dynamic Output Filters\n", + "Similarly, some filters yield a dynamic number of outputs. typed-ffmpeg ensures that any mismatches are quickly identified:\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Initialize input and apply a split filter\n", + "input1 = ffmpeg.input('input1.mp4')\n", + "split = input1.split(outputs=2)\n", + "\n", + "# Correctly accessing the outputs\n", + "video0 = split.video(0)\n", + "video1 = split.video(1)\n", + "\n", + "# Incorrectly accessing an out-of-range output will raise an error\n", + "video2 = split.video(2) # This will raise a ValueError\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/usage/customizing-filters.ipynb b/docs/usage/customizing-filters.ipynb new file mode 100644 index 00000000..3704a6ea --- /dev/null +++ b/docs/usage/customizing-filters.ipynb @@ -0,0 +1,257 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Customizing Filters in Typed-FFmpeg\n", + "\n", + "### Introduction to Custom Filters\n", + "While Typed-FFmpeg supports most of the FFmpeg filters out-of-the-box, there might be instances where you need to use filters that are not predefined in the library. For such cases, Typed-FFmpeg provides a flexible way to define and utilize custom filters.\n", + "\n", + "### Creating Single-input Custom Filters\n", + "Easily create your own single-input custom filters with the `vfilter`, `afilter` method. This allows for direct application of new or specialized video filters not standard in Typed-FFmpeg." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "OutputStream(node=OutputNode(kwargs=(), inputs=(VideoStream(node=FilterNode(kwargs=(('option1', 'value1'), ('option2', 'value2')), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input.mp4'), index=None),), name='custom_filter', input_typings=(,), output_typings=(,)), index=0),), filename='output.mp4'), index=None)" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import ffmpeg\n", + "\n", + "# Apply a custom single-input video filter\n", + "(\n", + " ffmpeg.input(\"input.mp4\")\n", + " .vfilter(name=\"custom_filter\", option1=\"value1\", option2=\"value2\") # Apply \"custom_filter\" with specified options\n", + " .output(filename=\"output.mp4\")\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This code snippet will correspond to the following FFmpeg command line:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"ffmpeg -i input.mp4 -filter_complex '[0]custom_filter=option1=value1:option2=value2[s0]' -map '[s0]' output.mp4\"" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " ffmpeg.input(\"input.mp4\")\n", + " .vfilter(name=\"custom_filter\", option1=\"value1\", option2=\"value2\") # Apply \"custom_filter\" with specified options\n", + " .output(filename=\"output.mp4\")\n", + ").compile_line()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "VideoStream(node=FilterNode(kwargs=(('option1', 'value1'), ('option2', 'value2')), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input.mp4'), index=None),), name='custom_video_filter', input_typings=(,), output_typings=(,)), index=0)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import ffmpeg\n", + "\n", + "# Define a custom video filter for later use\n", + "ffmpeg.vfilter(\n", + " ffmpeg.input(\"input.mp4\"),\n", + " name=\"custom_video_filter\",\n", + " option1=\"value1\",\n", + " option2=\"value2\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Implementing Multi-input Custom Filters\n", + "For filters that require multiple inputs, specify the type of each input using the `input_typings` parameter to ensure correct stream handling.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "VideoStream(node=FilterNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input1.mp4'), index=None), AVStream(node=InputNode(kwargs=(), inputs=(), filename='input2.mp4'), index=None)), name='custom_video_filter', input_typings=(, ), output_typings=(,)), index=0)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import ffmpeg\n", + "from ffmpeg.schema import StreamType\n", + "\n", + "# Create a multi-input custom video filter\n", + "(\n", + " ffmpeg.input(\"input1.mp4\")\n", + " .vfilter(\n", + " ffmpeg.input(\"input2.mp4\"),\n", + " name=\"custom_video_filter\",\n", + " input_typings=(StreamType.video, StreamType.video),\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Alternatively, use the `vfilter`, `afilter` function directly for multi-input scenarios:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "VideoStream(node=FilterNode(kwargs=(), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input1.mp4'), index=None), AVStream(node=InputNode(kwargs=(), inputs=(), filename='input2.mp4'), index=None)), name='custom_video_filter', input_typings=(, ), output_typings=(,)), index=0)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import ffmpeg\n", + "from ffmpeg.schema import StreamType\n", + "\n", + "# Define and apply a multi-input custom video filter\n", + "ffmpeg.vfilter(\n", + " ffmpeg.input(\"input1.mp4\"),\n", + " ffmpeg.input(\"input2.mp4\"),\n", + " name=\"custom_video_filter\",\n", + " input_typings=(StreamType.video, StreamType.video),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Defining Multi-output Custom Filters\n", + "In cases where a filter generates multiple outputs, use `ffmpeg.filter_multi_output` function and specify the expected types of these outputs using the `output_typings` parameter. This feature is particularly useful for filters that split the input stream into several output streams.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "FilterNode(kwargs=(('output_typings', (, )),), inputs=(AVStream(node=InputNode(kwargs=(), inputs=(), filename='input1.mp4'), index=None),), name='custom_split', input_typings=(,), output_typings=())" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import ffmpeg\n", + "from ffmpeg.schema import StreamType\n", + "\n", + "# Create a custom filter that yields multiple outputs\n", + "ffmpeg.filter_multi_output(\n", + " ffmpeg.input(\"input1.mp4\"),\n", + " name=\"custom_split\",\n", + " input_typings=(StreamType.video,),\n", + " output_typings=(StreamType.video, StreamType.video),\n", + ")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "By following these guidelines, you can extend the functionality of Typed-FFmpeg to accommodate any specific filtering needs, ensuring maximum flexibility and efficiency in your video processing tasks.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/usage/execute.ipynb b/docs/usage/execute.ipynb new file mode 100644 index 00000000..b4cbe81a --- /dev/null +++ b/docs/usage/execute.ipynb @@ -0,0 +1,210 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Execute\n", + "\n", + "Once you have defined your FFmpeg processing pipeline in Typed-FFmpeg, executing the command or inspecting the underlying FFmpeg command is straightforward. This section covers how to run your FFmpeg tasks programmatically and how to retrieve the command line equivalent for debugging or educational purposes.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "import ffmpeg\n", + "\n", + "# Define the FFmpeg command with filters and output\n", + "input_stream = ffmpeg.input('input.mp4')\n", + "f = (\n", + " input_stream\n", + " .trim(start=10, end=20)\n", + " .drawtext(text='Hello World', fontsize=12, x=10, y=10)\n", + " .output(filename=\"output.mp4\")\n", + ")\n", + "\n", + "# Execute the FFmpeg command\n", + "f.run()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Retrieving the Command Line\n", + "\n", + "For debugging or verification purposes, you might want to inspect the exact command line that Typed-FFmpeg will execute. This can be done using the .compile() or .command_line() methods. These methods are especially useful for understanding how Typed-FFmpeg translates your Python code into FFmpeg command-line arguments.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "# Compile the FFmpeg command into a list format\n", + "command_list = f.compile()\n", + "print(command_list)\n", + "# Outputs: ['ffmpeg', '-i', 'input.mp4', '-filter_complex', '[0:v]trim=start=10:end=20,drawtext=text=Hello World:fontsize=12:x=10:y=10', '-map', '0:v', 'output.mp4']\n", + "\n", + "# Alternatively, get the command line as a single string\n", + "command_string = f.command_line()\n", + "print(command_string)\n", + "# Outputs: ffmpeg -i input.mp4 -filter_complex '[0:v]trim=start=10:end=20,drawtext=text=Hello World:fontsize=12:x=10:y=10' -map '0:v' output.mp4\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "These methods are primarily intended for debugging and ensuring that the Typed-FFmpeg commands align with your expectations.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Visualizing the Command\n", + "\n", + "Typed-FFmpeg also offers a method to visualize your filter graph, which can help in understanding the flow and structure of your FFmpeg command. This is particularly helpful when dealing with complex filter chains or multi-stream workflows.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "# Visualize the FFmpeg filter graph\n", + "f.view()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Utilizing the .view() method renders a graphical representation of your command's filter graph, providing a clear and intuitive overview of how your streams and filters are interconnected.\n", + "\n", + "By following these steps, you can effectively execute, debug, and visualize your video and audio processing tasks within the Typed-FFmpeg framework.\n", + "\n", + "\n", + "### Validate & Auto Fix with Typed-FFmpeg\n", + "\n", + "Typed-FFmpeg introduces an advanced feature for validating and automatically correcting your FFmpeg commands. This functionality is invaluable for ensuring that your commands are not only syntactically correct but also adhere to FFmpeg's operational requirements, which can sometimes be non-intuitive and lead to user confusion.\n", + "\n", + "#### Resolving Missing Split Filters\n", + "\n", + "A common issue in FFmpeg commands is the improper reuse of filtered streams without a split. FFmpeg requires distinct stream references when a stream is used in multiple contexts. Typed-FFmpeg can automatically insert necessary split filters to rectify this.\n", + "\n", + "**Example of a Missing Split Filter Issue:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "from ffmpeg import input\n", + "from ffmpeg.filters import concat\n", + "\n", + "# Define a problematic FFmpeg graph without the required split\n", + "input_stream = input(\"input.mp4\")\n", + "stream = input_stream.reverse()\n", + "graph = concat(stream, stream).video(0).output(filename=\"tmp.mp4\")\n", + "\n", + "# Attempt to compile the command without auto-fixing\n", + "graph.compile_line(auto_fix=False)\n", + "# Incorrect command: ffmpeg -i input.mp4 -filter_complex '[0:v]reverse[r];[r][r]concat[c]' -map '[c]' tmp.mp4\n", + "\n", + "# Automatically fix and compile the command\n", + "graph.compile_line()\n", + "# Corrected command: ffmpeg -i input.mp4 -filter_complex '[0:v]reverse[r];[r]split=2[s1][s2];[s1][s2]concat[c]' -map '[c]' tmp.mp4" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "In this case, Typed-FFmpeg intelligently adds a split filter to meet FFmpeg's requirements for stream usage.\n", + "\n", + "#### Eliminating Redundant Split Filters\n", + "\n", + "Conversely, unnecessary split filters can also introduce problems, such as unintended stream selections or inefficient processing. Typed-FFmpeg can identify and remove these redundant filters, streamlining your command.\n", + "\n", + "**Example of Redundant Split Filter Issue:**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "plaintext" + } + }, + "outputs": [], + "source": [ + "from ffmpeg import input\n", + "\n", + "# Set up an FFmpeg graph with a redundant split\n", + "input1 = input(\"input1.mp4\")\n", + "f = (\n", + " input1\n", + " .split(outputs=2)\n", + " .video(0)\n", + " .trim(end=5)\n", + " .output(filename=\"tmp.mp4\")\n", + ")\n", + "\n", + "# Compile the command with the redundant split, without auto-fixing\n", + "f.compile_line(auto_fix=False)\n", + "# Inefficient command: ffmpeg -i input1.mp4 -filter_complex '[0:v]split=2[s0][s1];[s0]trim=end=5[t]' -map '[t]' tmp.mp4\n", + "\n", + "# Auto-remove the redundant split and compile\n", + "f.compile_line()\n", + "# Optimized command: ffmpeg -i input1.mp4 -filter_complex '[0:v]trim=end=5[t]' -map '[t]' tmp.mp4\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "In this example, Typed-FFmpeg eliminates the unnecessary split, thereby simplifying the command and potentially improving processing efficiency.\n", + "\n", + "#### Conclusion\n", + "\n", + "Typed-FFmpeg's validation and auto-fixing capabilities greatly enhance the user experience by automating the resolution of common issues and optimizing command structure. This ensures that users can focus more on their creative and technical goals rather than on navigating the intricacies of FFmpeg's syntax and stream management rules.\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/mkdocs.yml b/mkdocs.yml index 0c602621..2d95e8c0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -41,7 +41,9 @@ nav: - Get Started: - Overview: index.md - Usage: - - How to Use: usage/how_to_use-1.ipynb + - Basic API Usage: usage/basic-api-usage.ipynb + - Complex Filtering: usage/complex-filtering.ipynb + - Customizing Filters: usage/customizing-filters.ipynb - API Documentation: - ffmpeg: src/base.md - types: src/types.md @@ -110,7 +112,11 @@ markdown_extensions: plugins: - search - - mknotebooks + - mknotebooks: + execute: false + timeout: 100 + # preamble: "" + allow_errors: true - mkdocstrings: handlers: python: