src/widgets/VideojsPlayer.js
changeset 1073 687133dc13cf
child 1076 510fd2a482f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/VideojsPlayer.js	Thu Oct 17 00:58:24 2024 +0200
@@ -0,0 +1,176 @@
+// VideojsPlayer
+import "videojs-youtube/dist/Youtube.js";
+import Vimeo from './videojs_plugins/Vimeo.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"
+  }
+]
+
+const VideojsPlayerWidget = function (ns) {
+  return class extends ns.Widgets.Widget {
+    constructor(player, config) {
+      super(player, config);
+    }
+
+    static defaults = {};
+
+    draw() {
+      var _opts = { techOrder: [ 'html5', 'Youtube', 'Vimeo'] },
+        _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("volumechange");
+            return value;
+          },
+          setVolume: function (value) {
+            _media.volume = value;
+            _media.trigger("volumechange");
+            return value;
+          },
+        };
+      });
+
+      this.videojsPlayer = _player;
+    }
+  };
+};
+
+export { VideojsPlayerWidget as VideojsPlayer, videojsStyles, Vimeo };