Moral Dilemmas in Batman Begins (2005)

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. 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.

In [1]:
from IPython.display import YouTubeVideo
In [2]:
YouTubeVideo('G_-X_wCZ-yc')
Out[2]:

Preparing the raw material

Loading the movie

First, let's create a reference to the movie file from which we'll extract individual scenes.

In [16]:
from moviepy import editor
In [17]:
batman = editor.VideoFileClip("batman.mkv")

Writing functions for easy movie creation

I want all my video excerpts to follow the same pattern:

  • a title screen
  • the excerpt from the movie
  • a question

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.

In [18]:
def make_text_clip(title, duration, screensize, fontsize=70):
    "Returns a text clip that can be written to file."
    clip = editor.TextClip(txt=title, 
                    color='white', 
                    font='DejaVuSansMonoBObforPowerline', 
                    fontsize=fontsize,
                    stroke_width=10).set_duration(duration).set_pos('center')
    return editor.CompositeVideoClip([clip], size=screensize)
In [19]:
def insert_text_before(clip, text, duration=1):
    "Returns a clip starting with a title text."
    title_clip = make_text_clip(text, duration, screensize=(1280, 534))
    return editor.concatenate((title_clip, clip))
In [20]:
def insert_text_after(clip, text, duration=1):
    "Returns a clip that ends with the given text."
    end_clip = make_text_clip(text, duration, fontsize=50, screensize=(1280, 534))
    return editor.concatenate([clip, end_clip])

We define an Episode structure that keeps all the things we need for a movie clip together.

In [21]:
from collections import namedtuple
Episode = namedtuple('Episode', 'start, end, start_text, end_text')

Finally, we define a rendering function that takes an episode and a filename as inputs and renders everything to disk.

In [22]:
def render(episode, filename):
    "Renders an episode to a file."
    clip = batman.subclip(episode.start, episode.end)
    clip = insert_text_before(clip, episode.start_text, duration=5)
    clip = insert_text_after(clip, "Isn't there a strange moral situation\nin this scene?", duration=3)
    clip = insert_text_after(clip, episode.end_text, duration=10)
    clip.write_videofile(filename)

Let's make movies

Now that our framework is in place, let's get to work.

Episode 1

In [25]:
episode1 = Episode((2, 3, 8),
                   (2, 4, 0),
                   "Socrates meets Batman\nEpisode 1",
                   """Batman says he doesn't kill.
But isn't letting someone die, 
when you could save him, killing?
Especially when you set the fire yourself?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [26]:
render(episode1, 'episode1.mp4')
[MoviePy] >>>> Building video episode1.mp4
[MoviePy] Writing audio in episode1TEMP_MPY_wvf_snd.mp3
100%|██████████| 1257/1257 [00:01<00:00, 951.88it/s]
[MoviePy] Done.
[MoviePy] Writing video episode1.mp4
100%|██████████| 1679/1679 [00:59<00:00, 28.18it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode1.mp4 

Episode 2

In [29]:
episode2 = Episode((0, 24, 20),
                   (0, 24, 39),
                   "Socrates meets Batman\nEpisode 2",
                   """Joe chill murdered Bruce Wayne's parents.
He went to prison to pay his debt to 
society.
Is it just to release him early?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [30]:
render(episode2, 'episode2.mp4')
[MoviePy] >>>> Building video episode2.mp4
[MoviePy] Writing audio in episode2TEMP_MPY_wvf_snd.mp3
100%|██████████| 530/530 [00:00<00:00, 902.48it/s]
[MoviePy] Done.
[MoviePy] Writing video episode2.mp4
100%|██████████| 888/888 [00:29<00:00, 19.33it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode2.mp4 

Episode 3

In [31]:
episode3 = Episode((0, 36, 5),
                   (0, 37, 7),
                   "Socrates meets Batman\nEpisode 3",
                   """Bruce Wayne is asked to kill
a murderer in this scene.
How is that not murder?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [32]:
render(episode3, 'episode3.mp4')
[MoviePy] >>>> Building video episode3.mp4
[MoviePy] Writing audio in episode3TEMP_MPY_wvf_snd.mp3
100%|██████████| 1478/1478 [00:01<00:00, 974.19it/s] 
[MoviePy] Done.
[MoviePy] Writing video episode3.mp4
100%|██████████| 1919/1919 [00:49<00:00, 39.09it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode3.mp4 

Episode 4

In [36]:
episode4 = Episode((1, 39, 22),
                   (1, 40, 12.5),
                   "Socrates meets Batman\nEpisode 4",
                   """Batman breaks traffic laws, 
putting innocent people and cops 
at risk to save Rachel from dying.
Is Rachels life worth it? Why?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [37]:
render(episode4, 'episode4.mp4')
[MoviePy] >>>> Building video episode4.mp4
[MoviePy] Writing audio in episode4TEMP_MPY_wvf_snd.mp3
100%|██████████| 1224/1224 [00:01<00:00, 970.00it/s]
[MoviePy] Done.
[MoviePy] Writing video episode4.mp4
100%|██████████| 1643/1643 [00:39<00:00, 24.42it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode4.mp4 

Episode 5

In [38]:
episode5 = Episode((1, 40, 15),
                   (1, 40, 34),
                   "Socrates meets Batman\nEpisode 5",
                   """Has Bruce Wayne a moral 
obligation to preserve the reputation 
of his dead father?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [39]:
render(episode5, 'episode5.mp4')
[MoviePy] >>>> Building video episode5.mp4
[MoviePy] Writing audio in episode5TEMP_MPY_wvf_snd.mp3
100%|██████████| 530/530 [00:00<00:00, 1015.27it/s]
[MoviePy] Done.
[MoviePy] Writing video episode5.mp4
100%|██████████| 888/888 [00:22<00:00, 26.81it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode5.mp4 

Episode 6

In [40]:
episode6 = Episode((1, 57, 22),
                   (1, 57, 54),
                   "Socrates meets Batman\nEpisode 6",
                   """Is it what you do that 
defines you? Why does your name
have no importance?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [41]:
render(episode6, 'episode6.mp4')
[MoviePy] >>>> Building video episode6.mp4
[MoviePy] Writing audio in episode6TEMP_MPY_wvf_snd.mp3
100%|██████████| 816/816 [00:00<00:00, 851.21it/s]
[MoviePy] Done.
[MoviePy] Writing video episode6.mp4
100%|██████████| 1199/1199 [00:32<00:00, 36.91it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode6.mp4 

Episode 7

In [42]:
episode7 = Episode((0, 4, 3),
                   (0, 5, 20),
                   "Socrates meets Batman\nEpisode 7",
                   """Does devoting yourself to 
a cause entirely make your cause become 
just?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [43]:
render(episode7, 'episode7.mp4')
[MoviePy] >>>> Building video episode7.mp4
[MoviePy] Writing audio in episode7TEMP_MPY_wvf_snd.mp3
100%|██████████| 1809/1809 [00:01<00:00, 928.41it/s]
[MoviePy] Done.

[MoviePy] Writing video episode7.mp4
100%|██████████| 2278/2278 [00:59<00:00, 24.05it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode7.mp4 

Episode 8

In [44]:
episode8 = Episode((1, 10, 2),
                   (1, 11, 17),
                   "Socrates meets Batman\nEpisode 8",
                   """Is it what you think 
that defines you?
Or what you do?
\nConfused? Start today:
www.coursera.org/learn/plato-dialogues""")
In [45]:
render(episode8, 'episode8.mp4')
[MoviePy] >>>> Building video episode8.mp4
[MoviePy] Writing audio in episode8TEMP_MPY_wvf_snd.mp3
100%|██████████| 1764/1764 [00:01<00:00, 947.05it/s]
[MoviePy] Done.
[MoviePy] Writing video episode8.mp4
100%|██████████| 2230/2230 [01:02<00:00, 35.69it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: episode8.mp4 

Metadata for YouTube

  • Video titles: Socrates meets Batman Episode 2
  • Description: A scene from Batman Begins (2005), created for educational purposes for the Coursera class "Reason and Persuasion: Thinking Through Three Dialogues By Plato" (see https://www.coursera.org/learn/plato-dialogues/).
  • Tags: Socrates, Batman, ethics, Plato, dilemma

Conclusion

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!

Comments