src/widgets/VideojsPlayer.js
author ymh <ymh.work@gmail.com>
Tue, 22 Oct 2024 07:03:54 +0200
changeset 1076 510fd2a482f4
parent 1073 687133dc13cf
permissions -rw-r--r--
Add Dailymotion Tech and remove unused libs

// VideojsPlayer
import "videojs-youtube/dist/Youtube.js";
import Vimeo from './videojs_plugins/Vimeo.js';
import Dailymotion from "./videojs_plugins/Dailymotion.js";
import videojs from "video.js";

import videojsStyles from "./VideojsPlayer.module.css";
import mime from "mime-types";

const alternative_types = [{ 
    regex:/^(https?:\/\/)?((?:www|m)\.)?(?:youtube(?:-nocookie)?\.com|youtu.be)/,
    type: "video/youtube"
  }, {
    regex:/^(https?:\/\/)?(www\.)?vimeo\.com/,
    type: "video/vimeo"
  }, {
    regex:/^(https?:\/\/)?(www\.)?dailymotion\.com/,
    type: "video/dailymotion"
  }
]

const VideojsPlayerWidget = function (ns) {
  return class extends ns.Widgets.Widget {
    constructor(player, config) {
      super(player, config);
    }

    static defaults = {};

    draw() {

      const techOrder = [ 'html5', 'Youtube', 'Vimeo' ];
      if(this.dailymotionPlayerId) {
        techOrder.push("Dailymotion");
        Dailymotion.loadLibrary(this.dailymotionPlayerId);
      }

      var _opts = { techOrder },
        _seekPause = false,
        _pauseState = true;

      if (typeof this.video === "undefined") {
        this.video = this.media.video;
      }

      let type = mime.lookup(this.video);

      if(!type) {
        for(const tdef of alternative_types) {
          if(tdef.regex.test(this.video)) {
            type = tdef.type;
            break;
          }
        }
      }
      _opts.src = { type: type || false, src:this.video };
      _opts.controls = false;
      _opts.width = this.width;
      if (this.height) {
        _opts.height = this.height;
      }

      if (this.autostart) {
        // There seems to be an autostart bug
        _opts.autostart = true;
//        _pauseState = false;
//        this.media.trigger("play");
      }

      if (this.url_transform) {
        _opts.src.src = this.url_transform(_opts.src.src);
      }

      // Binding functions to jwplayer
      if(!this.media) {
        return;
      }
      var _media = this.media;
      const videoId = `video_${this.generateUid("_")}`;
      this.$.append(`<video class="video-js" id="${videoId}"><source type="${_opts.src.type || 'video/mp4'}" src="${_opts.src.src}"></source></video>`)
      const _player = videojs(videoId, _opts);

      _media.on("setcurrenttime", function (_milliseconds) {
        _seekPause = _pauseState;
        _player.currentTime(_milliseconds/1000);
      });

      _media.on("setvolume", function (_vol) {
        _player.volume(_vol);
        _media.volume = _vol;
      });

      _media.on("setmuted", function (_muted) {
        _player.muted(_muted);

        _media.muted = _muted;
      });

      _media.on("setplay", function () {
        _player.play();
        _media.paused = false;
      });

      _media.on("setpause", function () {
        _player.pause();
        _media.paused = true;
      });

      // Binding jwplater events to media

      function getVolume() {
        _media.muted = _player.muted();
        _media.volume = _player.volume();
      }

      _player.on("timeupdate", function() {
        _media.trigger(
          "timeupdate",
          new ns.Model.Time(_player.currentTime()*1000)
        );
      })

      _player.ready(function () {
        _media.trigger(
          "timeupdate",
          new ns.Model.Time(_player.currentTime()*1000)
        );
        _pauseState = _player.paused();
        _media.paused = _player.paused();
        _media.trigger("loadedmetadata");
        
      });

      _player.on("pause", function() {
        _pauseState = true;
        _media.trigger("pause");
      })

      _player.on("play", function() {
        _pauseState = false;
        _media.trigger("play");
      })

      videojs.use("*", function (player) {
        return {
          play: function (terminated, value) {
            _pauseState = false;
            _media.trigger("play");
            return value;
          },
          setCurrentTime: function (value) {
            if (_seekPause) {
              _player.pause();
              _seekPause = false;
            } else {
              if (_pauseState && !_player.paused()) {
                _pauseState = false;
                _media.trigger("play");
              }
            }
            _media.trigger("timeupdate", new ns.Model.Time(value));
            return value;
          },
          pause: function (terminated, value) {
            _pauseState = true;
            _media.trigger("pause");
            return value;
          },
          setMuted: function (value) {
            _media.muted = value;
            _media.trigger("muted");
            _media.trigger("volumechange");
            return value;
          },
          setVolume: function (value) {
            _media.volume = value;
            _media.trigger("volumechange");
            return value;
          },
        };
      });

      this.videojsPlayer = _player;
    }
  };
};

export { VideojsPlayerWidget as VideojsPlayer, videojsStyles, Vimeo, Dailymotion };