VideoJS-Dynamically Change Sources

21,049

Solution 1

getPlayers() returns an object containing all players, not a player.

You'd normally get a particular player with videojs('my_player_id').

Solution 2

The way I do it is by using the suggested dispose method of the player object.

I have a function which creates a new player with an ID, which was different from the ID of the previous player (for some reason you can't instantiate a player with the same ID, even after it was disposed).

The full process is as follows:

  1. Create a parent element for your player.

        <div id="player-parent"></div>
    
  2. Create a function responsible for generating an initial player element on which you'll call the videojs constructor.

    function getPlayerInstance(curPlayerNumber, playerSource) {
        // curPlayerNumber is simply a counter number which must be different from any previous one passed to this function
        return $("<video id=\"video\ " + curPlayerNumber + "\" class=\"video-js vjs-default-skin\" controls data-setup='{\"plugins\" : { \"resolutionSelector\" : { \"default_res\" : \"360\" } } }'><source src=\"" + playerSource + "\" type=\"application/x-mpegURL\" data-res=\"360\"></video>");
    }
    
  3. Select your parent element

    $('#player-parent').append(getPlayerInstance(++playerCounter, someSourceHere));
    
    1. Instantiate your player, disposing any old players you might have.

This is pseudo code, for simplicity I assign the player to a global variable for easier access. You should do that differently.

    if (window.playerElement) {
        window.playerElement.dispose();
    }

    // the playerCounter variable is different for each function call
    videojs("video" + playerCounter).ready(function(){
        window.playerElement = this;
    });

Hope this was helpful, I wasted 3 days on this.

Share:
21,049
Aaron Chamberlain
Author by

Aaron Chamberlain

B.S. in Computer Engineering, M.S. in Cyber Security. Linux Systems Administrator, DevOps, and web programmer. Sometimes embedded too.

Updated on December 31, 2020

Comments

  • Aaron Chamberlain
    Aaron Chamberlain over 3 years

    I'm looking to change the video source of my VideoJS player dynamically. I tried one method of changing the source directly via the DOM and it did change it, but the player needs to reload. So looking at the official API here: http://docs.videojs.com/docs/api/player.html#Methodssrc

    There's a method to change the source but when running the following code, it throws an error.

        var source = dropdown.options[dropdown.selectedIndex].value;
    
    	var myVideo = videojs.getPlayers();
    	console.log(myVideo);
    	if (source == "Source2"){
    		myVideo.src([
    			{type: "application/x-mpegURL", src: "http://mycdn/playlist.m3u8"},
    			{type: "rtmp/mp4", src: "rtmp://mycdn"}
    		]);
    	}

    Although the console does verify that myVideo is an object, calling the .src(source) function throws "TypeError: myVideo.src is not a function. (In 'myVideo.src', 'myVideo.src' is undefined)"

    I've also found tutorials like this where the apparent more "official" way is to dispose of the player completely and reinitialize with new sources, but I can't seem to understand what he's doing. https://ineed.coffee/3201/how-to-dynamically-change-video-js-videos-and-captions-with-javascript/

    Any help would be appreciated.


    Solution: For testing purposes I just have a nice little drop down and added a click event to that, so it changes the channel to whatever the user wants.

    var dropdown = document.getElementById('sel1');
    var source = dropdown.options[dropdown.selectedIndex].value;
    
    dropdown.addEventListener("click", function(){
    source = dropdown.options[dropdown.selectedIndex].value;
    console.log(source)
    
    var myVideo = videojs('my-video');
    console.log(myVideo);   
    if (source == "Public Access"){
        myVideo.src([
            {type: "application/x-mpegURL", src: "http://mycdns/playlist.m3u8"},
            {type: "rtmp/mp4", src: "rtmp://mycdn"}
        ]);
    }
    else if (source == "Government"){
        myVideo.src([
            {type: "application/x-mpegURL", src: "http://mycdn/playlist.m3u8"},
            {type: "rtmp/mp4", src: "rtmp://mycdn"}
        ]);
    }
    else if (source == "Regional"){
        myVideo.src([
            {type: "application/x-mpegURL", src: "http://mycdn/playlist.m3u8"},
            {type: "rtmp/mp4", src: "rtmp://mysource"}
        ]);
    }
    });