Javascript

changing source on html5 video tag

27 September 2026 · 7 min read

changing source on html5 video tag

In today’s dynamic web landscape, delivering engaging multimedia experiences is paramount. Videos captivate audiences, convey complex information, and significantly boost user engagement. However, static video content often falls short when user interactions or evolving data demand a more flexible approach. This is where the ability to dynamically update or change the source on an HTML5 video tag becomes invaluable. Mastering this technique empowers developers to create responsive, interactive video players that adapt in real-time, whether for a personalized streaming experience, a modular e-learning platform, or an interactive product showcase.

Mastering the HTML5 Video Tag: A Foundation for Dynamic Content

The core of modern web video lies within the HTML5 <video> tag, a powerful element that brought native video playback to browsers without relying on third-party plugins. This tag supports various attributes such as controls, autoplay, loop, and preload, which dictate how the video behaves and loads. Understanding these foundational attributes is crucial before attempting to manipulate the video source dynamically.

Typically, a video is embedded using either a src attribute directly on the <video> tag or by nesting one or more <source> elements within it. The latter approach is particularly robust for ensuring cross-browser compatibility and handling different video formats (like MP4, WebM, Ogg), as the browser will automatically select the first format it supports. For instance, a video might have a WebM version for Chrome and Firefox, and an MP4 version for Safari.

The ability to change the video source on the fly opens up a world of possibilities for developers. Imagine a user selecting a different language for a tutorial video, or a product configurator that updates the video demonstration based on chosen features. This dynamic capability is central to creating truly interactive and user-centric web applications. According to a study by Wistia, viewers spend 2.6x more time on pages with video, underscoring the importance of delivering flawless video experiences.

Two Primary Approaches for Changing Video Source Dynamically

When it comes to changing the source of an HTML5 video dynamically, developers primarily utilize two methods, both involving JavaScript manipulation of the Document Object Model (DOM). Each method has its own use cases and considerations.

The first method involves directly updating the src attribute of the <video> element. This is often the simplest approach for scenarios where you have a single video source to change. You select the video element using JavaScript (e.g., document.getElementById('myVideo')), and then assign a new URL to its src property. After updating the source, it’s crucial to call the load() method on the video element. This tells the browser to reload the media from the newly specified source, otherwise, the video player might not recognize the change.

The second, more flexible method, involves manipulating the nested <source> elements within the <video> tag. This is particularly useful when you need to switch between different video formats or resolutions. Instead of changing the src on the main video tag, you can dynamically add, remove, or modify the src and type attributes of individual <source> children. After making changes to the <source> elements, the video.load() method is still essential to ensure the browser re-evaluates the available sources and loads the appropriate video file. This approach provides greater control over content negotiation, allowing for robust cross-browser and device compatibility.

Regardless of the method chosen, careful consideration of video MIME types is vital. The type attribute within the <source> tag, or implicitly handled by the browser when setting video.src, informs the browser about the video format (e.g., video/mp4, video/webm). Mismatched or incorrect MIME types can lead to playback errors, as the browser may not be able to decode the media stream correctly. Ensuring these types are accurate is a key aspect of successful dynamic video loading.

Step-by-Step: Implementing Dynamic Video Source Changes with JavaScript

Dynamically changing the video source in HTML5 requires a clear understanding of JavaScript and the browser’s media API. Here’s a detailed guide to achieve this, focusing on the common scenario of updating the video.src property.

  1. Identify Your Video Element: First, you need to get a reference to your <video> element in JavaScript. The most common way is to assign it an id attribute and use document.getElementById(). ```
    
     Then, in JavaScript: ```
    const videoPlayer = document.getElementById('myDynamicVideo');
    
  2. Define New Video Sources: Prepare the URLs for your new video content. These could come from user input, an API response, or pre-defined variables. ``` const newVideoUrl = ‘path/to/your/new-video.mp4’; const anotherVideoUrl = ‘path/to/yet/another-video.webm’;
  3. Update the src Property: Assign the new video URL to the src property of your video element. ``` videoPlayer.src = newVideoUrl;
    
     If you are using nested `<source>` elements and wish to change one of them, you would access it like: ```
    videoPlayer.querySelector('source').src = newVideoUrl; videoPlayer.querySelector('source').type = 'video/mp4'; // Update type if necessary
    
  4. Load the New Media: This is a critical step. After changing the source, you must call the load() method on the video element. This tells the browser to reset the media player and fetch the new video. ``` videoPlayer.load();
  5. (Optional) Play the New Media: If you want the video to start playing immediately after the source changes, call the play() method. Remember that autoplay policies might prevent this without user interaction. ``` videoPlayer.play();

By following these steps, you can reliably update the video content displayed in your HTML5 player, enabling rich, interactive experiences. This process is fundamental for applications requiring on-demand content switching, such as educational platforms or media galleries where a user might select different video clips.

Best Practices and Advanced Considerations for Seamless Video Experiences

While the basic steps for changing source on an HTML5 video tag are straightforward, implementing them seamlessly requires attention to best practices and advanced considerations. Performance, error handling, and user experience are paramount for successful dynamic video content.

When dynamically updating video sources, it’s crucial to manage the preload attribute. Setting preload="auto" instructs the browser to download the entire video, which might be inefficient if the video isn’t immediately played. Consider using preload="metadata" or preload="none" for initial loads, and only switch to "auto" once a user explicitly selects a video. This conserves bandwidth and improves initial page load times. Furthermore, handling video events like loadeddata, canplay, and error is essential for a robust player. For instance, you might show a loading spinner until loadeddata fires, or display an error message if the error event is triggered, indicating issues like an invalid video URL or unsupported format.

Cross-browser compatibility is another significant factor. While modern browsers generally support the HTML5 video API Question & Answer :

I’m trying to build a video player that works everywhere. so far I’d be going with:

<video> <source src="video.mp4"></source> <source src="video.ogv"></source> <object data="flowplayer.swf" type="application/x-shockwave-flash"> <param name="movie" value="flowplayer.swf" /> <param name="flashvars" value='config={"clip":"video.mp4"}' /> </object> </video> 

(as seen on several sites, for example video for everybody) so far, so good.

But now I also want some kind of playlist/menu along with the video player, from which I can select other videos. Those should be opened within my player right away. So I will have to “dynamically change the source of the video” (as seen on dev.opera.com/articles/everything-you-need-to-know-html5-video-audio/ - section “Let’s look at another movie”) with Javascript. Let’s forget about the Flash player (and thus IE) part for the time being, I will try to deal with that later.

So my JS to change the <source> tags should be something like:

<script> function loadAnotherVideo() { var video = document.getElementsByTagName('video')[0]; var sources = video.getElementsByTagName('source'); sources[0].src = 'video2.mp4'; sources[1].src = 'video2.ogv'; video.load(); } </script> 

The problem is, this doesn’t work in all browsers. Namely, in Firefox there is a nice page where you can observe the problem I’m having: http://www.w3.org/2010/05/video/mediaevents.html

As soon as I trigger the load() method (in Firefox, mind you), the video player dies.

Now I have found out that when I don’t use multiple <source> tags, but instead just one src attribute within the <video> tag, the whole thing does work in Firefox.

So my plan is to just use that src attribute and determine the appropriate file using the canPlayType() function.

Am I doing it wrong somehow or complicating things?

I hated all these answers because they were too short or relied on other frameworks.

Here is “one” vanilla JS way of doing this, working in Chrome, please test in other browsers:

``` var video = document.getElementById('video'); var source = document.createElement('source'); source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.mp4'); source.setAttribute('type', 'video/mp4'); video.appendChild(source); video.play(); console.log({ src: source.getAttribute('src'), type: source.getAttribute('type'), }); setTimeout(function() { video.pause(); source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.webm'); source.setAttribute('type', 'video/webm'); video.load(); video.play(); console.log({ src: source.getAttribute('src'), type: source.getAttribute('type'), }); }, 3000); ```
<video id="video" width="320" height="240"></video>
[External Link](https://jsfiddle.net/mattdlockyer/5eCEu/2/)