javascripthtmlflowplayer

How to create onclick events for video embedded using the Flowplayer javascript API?


My aim is to add buttons below my player that jump to specific moments in the video.

There's a demo example that does basically what I want: https://flowplayer.com/demos/using-the-apihowever it is based on the cloud player implementation of Flowplayer, and I'm using the Javascript API to embed my player. The basic relevant script is this:

flowplayer.cloud.then(function () {
    var api = flowplayer("#player")

    seek3.onclick = function() {
      api.fas.seek_to('00:01:01:11');
    }
});

An example I found of creating buttons using the Javascript API is as follows:

flowplayer(function(opts, root, api) {

    // small jQuery-compatible utility built inside the player
    var $ = flowplayer.mq;

    // render a custom button when the player is mounted
    api.on('mount', function() {
    var btn = $('<button>').txt('Test Button').on('click', function() {
    api.toggleMute();
    });

    $('.fp-controls', root).append(btn);

    });

});

That works fine with my player. When I try to merge the two approaches, though, I fail. Here is the broken code:

flowplayer(function(opts, root, api) {

   var api = flowplayer("#flowplayer");

    seek3.onclick = function() {
      api.fas.seek_to('00:01:01:11');
    }

 });

I tried also as alternatives

document.getElementById('seek3').onclick = function()

And

$('#seek1').onclick = function() {

(preceded by the additional line of code borrowed from the working example):

var $ = flowplayer.mq;

but with every variation I keep getting the following error: "Uncaught TypeError: Cannot set property 'onclick' of null".

Any help would be much appreciated. I've found the Flowplayer documentation really difficult to use, since in search results it's often hard to even tell which version of the player is being referenced. I would really like to find some basic info about interacting with the API in addition to solving this particular problem.


Solution

  • For anyone else who might be having difficulties interacting with the API, Flowplayer kindly posted a new demo example -- with similar functionality as in the cloudplayer demo, but this one for the javascript player: https://codepen.io/team/flowplayer/pen/KOzWOK

    var api = flowplayer("#player", 
      { src      : "//edge.flowplayer.org/drive.m3u8"
      , autoplay : false
      , token    : "eyJraWQiOiJqOEF6djg5NlJMMWIiLCJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJjIjoie1wiYWNsXCI6NixcImlkXCI6XCJqOEF6djg5NlJMMWJcIixcImRvbWFpblwiOltcIm5ncm9rLmlvXCJdfSIsImlzcyI6IkZsb3dwbGF5ZXIifQ.UtJliSh4IcIKs71PVzXWdIrJJ8-1_KRK0hKd7OKp5EJhAdpZStuYbbU4bgDs--C6Gak6OBrb-xQBh6sd4dyrlA"
      , muted    : true
      })
    
    /**
     * helper function to seek if possible or 
     * tell the player to seek when possible
     * 
     * btn     {HTMLElement}
     * seconds {Number}
     */
    function chapter (btn, seconds) {
      btn.onclick = function () {
        // player is preload=none so we must tell 
        // the player to seek when it is possible
        if (api.readyState == 0) api.setOpts({start_time: seconds})
        // player has already started loading content
        if (api.readyState > 0) api.currentTime = seconds
        // attempt to play content
        api.togglePlay(true)
      }
    }
    // bind the buttons to times
    chapter(seek1, 20)
    chapter(seek2, 45)
    chapter(seek3, 60)
    

    My working version includes the following variations on the JS code:

    /**
     * helper function to seek if possible or 
     * tell the player to seek when possible
     * 
     * seconds {Number}
     */
    function seek_to_cue (seconds) {
      //alert('bingo?'); //tft
      // player is preload=none so we must tell the player to seek when it is possible
      if (api.readyState == 0) {
          api.setOpts({start_time: seconds});
      }
      // player has already started loading content
      if (api.readyState > 0) {
          api.currentTime = seconds;
      }
      // attempt to play content
      api.togglePlay(true);
    }
    

    and in my PHP code which includes the JS player call:

    $button_actions .= 'document.getElementById("'.$button_id.'").addEventListener("click", function(){ seek_to_cue('.$start_time_seconds.'); });';