Adding videos in JupyterBook


A short post, hopefully to help out future fellow users who want to embed videos in their Jupyter Book.Book not Notebook. These are very different (albeit related) projects. It probably wasn’t the best idea to use this name, since googling for Jupyter Book only returns irrelevant results.

For a commercial endeavour, we’ve been using the Jupyter Book project to compile a bunch of instructional material (in the form Notebooks and Markdown) into an easy-to-publish format (static HTML) that is easy to distribute (the internet) and that looks beautiful (JupyterBook).

TL;DR: The project is (mostly) awesome. In terms of the output it produces, it makes many of the benefits of Org-mode + Babel + literate programming paradigm accessible to scientists and their ilk.

I say mostly, because this open issue on the official repo complains about local embedded videos not working in the output HTML. Someone tried to help, but they unfortunately went down the wrong path.

Here’s a solution (hack?) that worked for me:

  1. Create a _static folder inside the root of your project.
  2. Embed your video using <video> tags, linking to the relative path of the video.

For example, if your directory structure looked like this:

├── _config.yml
├── content
│   ├── my_notebook.ipynb
├── _static  # <-- put your video in here 
│   └── videos
│       ├── my_video.mp4
└── _toc.yml

Then your video tag in markdown cell in my_notebook should be:

<video src="../_static/videos/my_video.mp4"></video>

You’re, of course, free to add in any other attributes you need, such as controls.

So, why does this work?

By pure coincidence, we use Sphinx to build our documentation. It so happens that Sphinx is the same engine that is used to build Jupyter Books. By default, Sphinx copies across the _static folder (intended for static content) into the output HTML of your Jupyter Book. This means that it’ll be in the right location for the video tags in your processed Notebook or Markdown files, and your video will be playable.

et voilà ! 🍦