escapecharacter
escapecharacter

Reputation: 965

Why don't media range fragments work when embedding local video in a Jupyter Notebook?

Motivation

Goal: Given a longer video, I would like to embed it in a Jupyter Notebook with a programmatically-determined start/stop time.

Context: We are working with a large corpus of videos. We are doing investigatory detection experiments for events in those videos. We work out of Jupyter notebooks. Previously, we'd use ffmpeg to generate short snippets of video with the events of interest. However, this is time-consuming and error-prone.

I was hoping to use media fragments as described here:

Issue

I've launched jupyter via the jupyter lab shell command in a folder that contains both the notebook and the video file.

In a Jupyter cell:

from IPython.display import HTML

video_type="video/mp4"
start_s = 5
end_s = 10

# https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime    
_html = f"""
<video style="width:100%" 
    id="{video_dom_id}"
    alt="{local_relative_path_video}" 
    controls>
    <source src="{local_relative_path_video}#t={start_s},{end_s}" type="{video_type}">
</video>
"""

display(HTML(_html))

The video does not load, with error "No video with supported format and MIME type found". Video loads successfully if #t={start_s}{end_s} is omitted. As instructed in the web.dev article, I've already checked Accept-Ranges and confirmed it appears in bytes. Confirmed with both Firefox and Chrome on macOS.

Workaround

For now, using .currentTime. However, this does not allow me to define the end time of the snippet of interest:

_html = f"""
<video style="width:100%" 
    id="{video_dom_id}"
    alt="{local_relative_path_video}" 
    controls>
    <source src="{local_relative_path_video}" type="{video_type}">
</video>
<script>
    document.getElementById("{video_dom_id}").addEventListener('loadeddata', function() {{
        document.getElementById("{video_dom_id}").currentTime = {start_s};
    }}, false);
    document.getElementById("{video_dom_id}").load();    
</script>
"""

Upvotes: 0

Views: 54

Answers (1)

VC.One
VC.One

Reputation: 15881

The only mistake I notice is a missing comma , on the #time setting of the video path.

It should look something like this example:
"c:/users/somecoder/desktop/testfile.mp4#t=5,10"

Solution:

 <source src="{local_relative_path_video}#t={start_s},{end_s}" type="{video_type}">

Edit for workaround:

"Video loads successfully if #t={start_s}{end_s} is omitted."

Go ahead and omit them in the initial HTML tag setup.
Then use Javascript to update the src with a custom #t time setting...

<script>
    document.getElementById("{video_dom_id}").addEventListener('loadeddata', function() {{
        document.getElementById("{video_dom_id}").src = ( {local_relative_path_video} + "#t=" + {start_s} + "," + {end_s} );
        document.getElementById("{video_dom_id}").load();
    
        document.getElementById("{video_dom_id}").muted = true;
        document.getElementById("{video_dom_id}").play();
    }}, false);
    
    
</script>

Upvotes: 0

Related Questions