75

I've got a local video file (an .avi, but could be converted) that I would like to show a client (ie it is private and can't be published to the web), but I can't figure out how to play it in IPython notebook.

After a little Googling it seems that maybe the HTML5 video tag is the way to go, but I don't know any html and can't get it to play.

Any thoughts on how I can embed this?

minrk
  • 37,545
  • 9
  • 92
  • 87
Chris
  • 9,603
  • 15
  • 46
  • 67

11 Answers11

105

(updated 2019, removed unnecessarily costly method)

Just do:

from IPython.display import Video

Video("test.mp4")

If you get an error No video with supported format or MIME type found, just pass embed=True to the function: Video("test.mp4", embed=True). In previous IPython versions, you may need to call the from_file method: Video.from_file("test.mp4").

Or if you want to use the HTML element:

from IPython.display import HTML

HTML("""
    <video alt="test" controls>
        <source src="test.mp4" type="video/mp4">
    </video>
""")
Viktor Kerkez
  • 45,070
  • 12
  • 104
  • 85
  • 3
    You don't need the 'io' module. You can read the video file simply as follows: `video = open('test.m4v', "rb").read()` – Apostolos Apr 07 '19 at 07:28
  • This answer should be ignored in 2019 and above. It costs a massive amount of time and produces the same output as Ziyad's. – Raskell Jul 25 '19 at 10:56
  • 1
    Updated the answer with the more up-to-date method. – waterproof Nov 20 '19 at 19:54
  • Please include the deleted method in this answer as well. Though that method is costly, it is the only method which prevents browsers from loading cached video file if the original video is modified. Even query string with timestamp are ignored by some browsers. – Akash Karnatak Jul 14 '20 at 09:41
  • @Apostolos How do you play a video opened that way? – Austin Aug 30 '20 at 15:53
  • @Austin, the code line I mentioned is part of a .ipynb file I use to test videos. The full code is the following: `from IPython.display import HTML / from base64 import b64encode / video = open(file, "rb").read() / video_encoded = b64encode(video).decode('ascii') / video_tag = ' – Apostolos Aug 31 '20 at 17:14
  • @Viktor, where does the 'Video' module com from? Is it something extra one has to install? – Apostolos Aug 31 '20 at 17:20
  • @Apostolos It's from the IPython package. https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html – Viktor Kerkez Sep 01 '20 at 12:55
  • @Viktor, thank you. I was using PY2 and this module was not part if the 'Jupyter' (IPython) package. I then installed and used 'Jupyter' in my PY3 system and it worked. (As you can see, I'm not a fan of JNB! :)) – Apostolos Sep 03 '20 at 10:09
  • I had to add the parameter 'embed = True' for it to work. – Wanderer Feb 06 '22 at 08:54
  • Try: `Video.from_file("test.mp4")` – alvas Mar 24 '23 at 18:41
39

Play it as an HTML5 video :]

from IPython.display import HTML

HTML("""
<video width="320" height="240" controls>
  <source src="path/to/your.mp4" type="video/mp4">
</video>
""")

UPDATE

Additionally, use a magic cell:

%%HTML
<video width="320" height="240" controls>
  <source src="path/to/your.mp4" type="video/mp4">
</video>

and the same applies for audio too

%%HTML
<audio controls>
  <source src="AUDIO-FILE.mp3">
</audio>

enter image description here

Aziz Alto
  • 19,057
  • 5
  • 77
  • 60
  • 2
    This does not really work for me. I have a black video preview and that's it. Perhaps the `base64` encoding is missing? – Atcold Feb 09 '17 at 16:10
  • It's a MP4. Nothing fancy. – Atcold Feb 09 '17 at 18:22
  • yea, unfortunately no clue. – Aziz Alto Feb 09 '17 at 23:00
  • Hmm... I've just tried this in a HTML file and it runs just fine in Chrome (on Linux). Nevertheless, if I copy and paste the content of it into a code cell of Jupyter notebook, it will just display the video player with a blank black content and disabled play button. :/ – Atcold Feb 10 '17 at 13:26
  • 1
    OK, I think it's a bug of Jupyter ([ref.](https://github.com/jupyter/notebook/issues/1024)). – Atcold Feb 10 '17 at 14:03
  • 9
    Haha, figured it out. One cannot use absolute paths, so I ended up symlinking the file. It works just fine now. Thank you. – Atcold Feb 10 '17 at 14:47
  • Oh, great it worked :-) I've not ran into such problem before. Thank you for figuring it out and sharing the solution here. – Aziz Alto Feb 10 '17 at 20:45
26

Use a markdown cell:

<video controls src="path/to/video.mp4" />

Citation: Jupyter Notebook » Docs » Examples » Markdown Cells

Kent Horvath
  • 283
  • 3
  • 4
14

An easier way:

from IPython.display import Video
Video.from_file("OUT.mp4")
alvas
  • 115,346
  • 109
  • 446
  • 738
Ziyad Moraished
  • 351
  • 2
  • 11
3

@Atcold's comment saved me today ;) so I'm posting this as an answer with more detail.

I had a cell with video capture command like this:

!sudo ffmpeg -t 5 -s 320x240 -i /dev/video0 /home/jovyan/capture.mp4

captured file was saved in a location out of git repository to manage disk usage.

for jupyter notebook, a file needs to be on the same directory as the .ipynb file.

# run this before calling Video()
! ln -sf "/home/jovyan/capture.mp4" ./capture.mp4
from IPython.display import Video

Video("capture.mp4")

voila! Thank you everyone for the wonderful answers and comments.

taiyodayo
  • 331
  • 4
  • 13
2

Look at this link, you'll find more https://gist.github.com/christopherlovell/e3e70880c0b0ad666e7b5fe311320a62

from IPython.display import HTML

from IPython.display import HTML

HTML('<iframe width="560" height="315" src="https://www.youtube.com/embed/S_f2qV2_U00?rel=0&amp;controls=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>')
2

Up to my knowledge, Ubuntu systems have some issues supporting direct rendering of video files such as .mp4. You will need to do some encoding/decoding with jupyter notebook. Example:

mp4 = open(path,'rb').read()
data_url = "data:video/mp4;base64," + b64encode(mp4).decode()

This snippet can solve this issue.

from IPython.display import HTML 
from base64 import b64encode

def display_video(path):  
    mp4 = open(path,'rb').read()   
    data_url = "data:video/mp4;base64," + b64encode(mp4).decode()
    display(
      HTML(
      """
          <video width=400 controls>
                <source src="%s" type="video/mp4">
          </video>
      """ % data_url
           )   
    )

the snipet was obtained from (https://github.com/facebookresearch/AugLy/blob/main/examples/AugLy_video.ipynb) but it is used quite often in other repositories

2

You could also try this:

from ipywidgets import Video
Video.from_file("./play_video_test.mp4", width=320, height=320)
  • This is far better than embedding the mp4 if `IPython.display.Video` throws unsupported MIME type. This creates a `blob:...` url to the file, and does not embed it. – Deadly Pointer Nov 17 '22 at 09:50
1

from IPython.display import Video

video_path='myvid.mp4'

Video(video_path, width=640, height=360, embed=True)

It will solve the issue.

PeterPan
  • 11
  • 2
0

from IPython.display import IFrame

# play video of video in jupyter notebook
IFrame(src='https://www.youtube.com/embed/mcVEbWh5uWU? rel=0&amp;controls=0&amp;showinfo=0', width=500, height=300)
Johnny
  • 1,112
  • 1
  • 13
  • 21
0

It appears a common issue is not including the video in the same directory as the calling notebook. Given an MP4 'generating_bootstrap_replicates.mp4' in the same directory as the notebook, the following function will load a video in an HTML player at full cell width while also asserting the video is in fact available locally. Works in Jupyter Notebook and Jupyter Lab. Tested with Python v3.8 kernel.

#!/usr/bin/env python3


def video_player(video, mtype="video/mp4"):
    """ Displays mp4 video in Jupyter cell. Jupyter requires video 
    in the same directory as the calling notebook. An assertion error
    will be thrown if this is not true.
    
    Parameters
    ----------
    video (str): the filename of the video. Example: "generating_bootstrap_replicates.mp4"
    mtype (str): the mime type of the video. Example: "video/mp4"
    
    """
    
    from pathlib import Path
    from IPython.display import HTML, display
    
    cwd = Path.cwd()
    
    assert video in [file.name for file in list(cwd.glob('*'))], \
        f'{video} must be in local directory: {cwd}' 
        
    call = """
    <video width=100% controls>
        <source src="{}" type="{}">
    </video>""".format(video, mtype)
    
    display(HTML(call))
    

video_player('generating_bootstrap_replicates.mp4')
Liquidgenius
  • 639
  • 5
  • 17
  • 32