The Easy Part
When using an HTML video element, it is rather straight forward to change its source. The value of the src attribute needs to be changed and then the load method called (and eventually the play method, to start the video playback).
<video id="video" controls="true" src=""></video>
Changing video src attribute
const src = 'video_file_url'; const video = $( '#video' )[ 0 ]; video.src = src; video.load();
Reset the source
With more complex cases, there are probably thousands of reasons to do it differently. For example, the whole video element can be replaced:
Replacing whole video element
<div id="video"> <video controls="true" src=""></video> </div>
// Create new video element const src = 'video_file_url'; const prevVideo = $( '#video > video' )[ 0 ], const $video = $( '<video/>' ), const video = $video[ 0 ]; // Replace old video element $( '#video' ).html( video ); //method 1 $( '#video' ).empty().html( video ); //method 2 $( '#video' ).find( 'video' ).remove().end().html( video ); //method 3 // Set new source video.src = src; video.load();
Just one more thing needs to be done - the source of the previous video element should be reset.
Resetting src attribute
// Reset prevVideo.src = null; prevVideo.load(); // Set new source video.src = src; video.load();
Death by a thousand videos
The problem: Video elements detached from dom can still play and buffer video files. When a video element is replaced or even removed before being replaced… well, it shouldn’t be there, and I am not sure in what state it is in. Is it detached, or waiting for some dom garbage collector?
The thing is, the video element is still there and is still buffering video (but not playing, so here is the difference between being detached and this unknown state). If you replace a video element multiple times, you end up with the browser (in my case Chrome) downloading all videos at the same time, hence starting to slow down. That’s why resetting the source is important, and it is basically the solution to this problem.
You can experience this case on the jsfiddle demo here (check the Network tab in dev tools):
- Normal loading - replace video element with source reset
- Parallel loading - replace video element without source reset
- Detached - create many video elements without attaching to dom
Here is how it should look in the dev console:
Normal (proper) loading