{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "During the last three weeks, I've been following the excellent philosophy class Reason and Persuasion on Coursera. In one of the videos, professor John Holbo quotes a 2005 movie, Batman Begins. It turns out that the whole movie is full of interesting situations that make for fun philosophy style questions.\n", "In this notebook, we'll use the video editing library moviepy to cut some scenes from the full movie and format them in order to upload some videos to YouTube." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from IPython.display import YouTubeVideo" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkz\nODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2MBERISGBUYLxoaL2NCOEJjY2NjY2NjY2Nj\nY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY//AABEIAWgB4AMBIgACEQED\nEQH/xAAaAAEBAQEBAQEAAAAAAAAAAAAAAQIDBAUH/8QAKhABAQACAgIBBAEEAgMAAAAAAAECEQMh\nEjFBBCJRYTITcYGRQrEUNFL/xAAXAQEBAQEAAAAAAAAAAAAAAAAAAQID/8QAGhEBAQEBAAMAAAAA\nAAAAAAAAAAERAhIhMf/aAAwDAQACEQMRAD8A/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAFjWHtmN4e0HXGdKk9G1RoJDQBp\no0CaA0CNSGlkUNbNKsBcW2ZV+FG5kSsfKsjp5LvTnL0IOnltducuvbUoDWCWzW2LyTHtR2tYzv4c\ncuTLL11GbnnPd6TR2xu+mtduOPLI1/Vxl7qyjr8jO5fVWZKNVZEk216iwSxFSqhb2dro2CLKaRBa\nw1tkqoBUETL0VL6QfKAFAAAAAAAAAAAAAUBvCMSO2EBr4WQWiEWJF2Cm2fa6BFlXUNANSsqBvs2A\nNS6ancYalBqL0xakuwb2s/bEi7QdOqXr36YtYyy8vaaq58uVusfTn5fNZu71N/4aw+m58/jU/YuH\nmeXljq3Trj9Dn85z/TGX0fJPWUouOG5LTKeU6MuLPD+WKb1BG+PPPH18O/H9RMtSzTz4Za9tXWXp\nUfRxs10WvHhl/S455Zf4deHmxy3+mpUd0+V3LNp8tI0zfbXwfAqW9M7WsiLUEZVUEAS+lTJB8kAU\n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\n", "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "YouTubeVideo('G_-X_wCZ-yc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The full playlist can be found here: ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Preparing the raw material " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading the movie " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, let's create a reference to the movie file from which we'll extract individual scenes." ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from moviepy import editor" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "batman = editor.VideoFileClip(\"batman.mkv\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Writing functions for easy movie creation " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I want all my video excerpts to follow the same pattern:\n", "\n", "- a title screen\n", "- the excerpt from the movie\n", "- a question\n", "\n", "To achieve this, I have written the functions below that allow making individual text clips, inserting a text clip before or after the input clip." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def make_text_clip(title, duration, screensize, fontsize=70):\n", " \"Returns a text clip that can be written to file.\"\n", " clip = editor.TextClip(txt=title, \n", " color='white', \n", " font='DejaVuSansMonoBObforPowerline', \n", " fontsize=fontsize,\n", " stroke_width=10).set_duration(duration).set_pos('center')\n", " return editor.CompositeVideoClip([clip], size=screensize)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def insert_text_before(clip, text, duration=1):\n", " \"Returns a clip starting with a title text.\"\n", " title_clip = make_text_clip(text, duration, screensize=(1280, 534))\n", " return editor.concatenate((title_clip, clip))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def insert_text_after(clip, text, duration=1):\n", " \"Returns a clip that ends with the given text.\"\n", " end_clip = make_text_clip(text, duration, fontsize=50, screensize=(1280, 534))\n", " return editor.concatenate([clip, end_clip])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We define an Episode structure that keeps all the things we need for a movie clip together." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from collections import namedtuple\n", "Episode = namedtuple('Episode', 'start, end, start_text, end_text')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we define a rendering function that takes an episode and a filename as inputs and renders everything to disk." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def render(episode, filename):\n", " \"Renders an episode to a file.\"\n", " clip = batman.subclip(episode.start, episode.end)\n", " clip = insert_text_before(clip, episode.start_text, duration=5)\n", " clip = insert_text_after(clip, \"Isn't there a strange moral situation\\nin this scene?\", duration=3)\n", " clip = insert_text_after(clip, episode.end_text, duration=10)\n", " clip.write_videofile(filename)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Let's make movies " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that our framework is in place, let's get to work." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 1 " ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode1 = Episode((2, 3, 8),\n", " (2, 4, 0),\n", " \"Socrates meets Batman\\nEpisode 1\",\n", " \"\"\"Batman says he doesn't kill.\n", "But isn't letting someone die, \n", "when you could save him, killing?\n", "Especially when you set the fire yourself?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode1.mp4\n", "[MoviePy] Writing audio in episode1TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 1257/1257 [00:01<00:00, 951.88it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode1.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100%|██████████| 1679/1679 [00:59<00:00, 28.18it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode1.mp4 \n", "\n" ] } ], "source": [ "render(episode1, 'episode1.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 2 " ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode2 = Episode((0, 24, 20),\n", " (0, 24, 39),\n", " \"Socrates meets Batman\\nEpisode 2\",\n", " \"\"\"Joe chill murdered Bruce Wayne's parents.\n", "He went to prison to pay his debt to \n", "society.\n", "Is it just to release him early?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode2.mp4\n", "[MoviePy] Writing audio in episode2TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 530/530 [00:00<00:00, 902.48it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode2.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100%|██████████| 888/888 [00:29<00:00, 19.33it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode2.mp4 \n", "\n" ] } ], "source": [ "render(episode2, 'episode2.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 3 " ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode3 = Episode((0, 36, 5),\n", " (0, 37, 7),\n", " \"Socrates meets Batman\\nEpisode 3\",\n", " \"\"\"Bruce Wayne is asked to kill\n", "a murderer in this scene.\n", "How is that not murder?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode3.mp4\n", "[MoviePy] Writing audio in episode3TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 1478/1478 [00:01<00:00, 974.19it/s] \n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode3.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 1919/1919 [00:49<00:00, 39.09it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode3.mp4 \n", "\n" ] } ], "source": [ "render(episode3, 'episode3.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 4 " ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode4 = Episode((1, 39, 22),\n", " (1, 40, 12.5),\n", " \"Socrates meets Batman\\nEpisode 4\",\n", " \"\"\"Batman breaks traffic laws, \n", "putting innocent people and cops \n", "at risk to save Rachel from dying.\n", "Is Rachels life worth it? Why?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode4.mp4\n", "[MoviePy] Writing audio in episode4TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 1224/1224 [00:01<00:00, 970.00it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode4.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100%|██████████| 1643/1643 [00:39<00:00, 24.42it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode4.mp4 \n", "\n" ] } ], "source": [ "render(episode4, 'episode4.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 5 " ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode5 = Episode((1, 40, 15),\n", " (1, 40, 34),\n", " \"Socrates meets Batman\\nEpisode 5\",\n", " \"\"\"Has Bruce Wayne a moral \n", "obligation to preserve the reputation \n", "of his dead father?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode5.mp4\n", "[MoviePy] Writing audio in episode5TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 530/530 [00:00<00:00, 1015.27it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode5.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100%|██████████| 888/888 [00:22<00:00, 26.81it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode5.mp4 \n", "\n" ] } ], "source": [ "render(episode5, 'episode5.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 6 " ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode6 = Episode((1, 57, 22),\n", " (1, 57, 54),\n", " \"Socrates meets Batman\\nEpisode 6\",\n", " \"\"\"Is it what you do that \n", "defines you? Why does your name\n", "have no importance?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode6.mp4\n", "[MoviePy] Writing audio in episode6TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 816/816 [00:00<00:00, 851.21it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode6.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100%|██████████| 1199/1199 [00:32<00:00, 36.91it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode6.mp4 \n", "\n" ] } ], "source": [ "render(episode6, 'episode6.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 7 " ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode7 = Episode((0, 4, 3),\n", " (0, 5, 20),\n", " \"Socrates meets Batman\\nEpisode 7\",\n", " \"\"\"Does devoting yourself to \n", "a cause entirely make your cause become \n", "just?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode7.mp4\n", "[MoviePy] Writing audio in episode7TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 1809/1809 [00:01<00:00, 928.41it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Writing video episode7.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 2278/2278 [00:59<00:00, 24.05it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode7.mp4 \n", "\n" ] } ], "source": [ "render(episode7, 'episode7.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Episode 8 " ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": true }, "outputs": [], "source": [ "episode8 = Episode((1, 10, 2),\n", " (1, 11, 17),\n", " \"Socrates meets Batman\\nEpisode 8\",\n", " \"\"\"Is it what you think \n", "that defines you?\n", "Or what you do?\n", "\\nConfused? Start today:\n", "www.coursera.org/learn/plato-dialogues\"\"\")" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] >>>> Building video episode8.mp4\n", "[MoviePy] Writing audio in episode8TEMP_MPY_wvf_snd.mp3\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 1764/1764 [00:01<00:00, 947.05it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] Writing video episode8.mp4\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n", "100%|██████████| 2230/2230 [01:02<00:00, 35.69it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[MoviePy] Done.\n", "[MoviePy] >>>> Video ready: episode8.mp4 \n", "\n" ] } ], "source": [ "render(episode8, 'episode8.mp4')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Metadata for YouTube" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Video titles: Socrates meets Batman Episode 2\n", "- Description: A scene from Batman Begins (2005), created for educational purposes for the Coursera class \"Reason and \n", "Persuasion: Thinking Through Three Dialogues By Plato\" (see https://www.coursera.org/learn/plato-dialogues/). \n", "- Tags: Socrates, Batman, ethics, Plato, dilemma " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conclusion" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this post, we've leveraged the power of moviepy video editing (which is based on ffmpeg) to produce nice looking videos using Batman Begins scenes. I find that one of the most difficult things about this video business was to find the right questions to ask at the end of each segment. Feedback on the videos is welcome!" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }