src/widgets/videojs_plugins/Vimeo.js
changeset 1073 687133dc13cf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/widgets/videojs_plugins/Vimeo.js	Thu Oct 17 00:58:24 2024 +0200
@@ -0,0 +1,285 @@
+import videojs from 'video.js';
+import VimeoPlayer from '@vimeo/player';
+
+let cssInjected = false;
+
+// Since the iframe can't be touched using Vimeo's way of embedding,
+// let's add a new styling rule to have the same style as `vjs-tech`
+function injectCss() {
+  if (cssInjected) {
+    return;
+  }
+  cssInjected = true;
+  const css = `
+    .vjs-vimeo iframe {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+    }
+  `;
+  const head = document.head || document.getElementsByTagName('head')[0];
+
+  const style = document.createElement('style');
+
+  style.type = 'text/css';
+
+  if (style.styleSheet) {
+    style.styleSheet.cssText = css;
+  } else {
+    style.appendChild(document.createTextNode(css));
+  }
+
+  head.appendChild(style);
+}
+
+const Tech = videojs.getTech('Tech');
+
+/**
+ * Vimeo - Wrapper for Video Player API
+ *
+ * @param {Object=} options Object of option names and values
+ * @param {Function=} ready Ready callback function
+ * @extends Tech
+ * @class Vimeo
+ */
+class Vimeo extends Tech {
+  constructor(options, ready) {
+    super(options, ready);
+    injectCss();
+    this.setPoster(options.poster);
+    this.initVimeoPlayer();
+  }
+
+  initVimeoPlayer() {
+    const options = this.options({});
+    const vimeoOptions = {
+      url: this.options_.source.src,
+      byline: false,
+      portrait: false,
+      title: false,
+      controls: false,
+    };
+
+    if (this.options_.autoplay) {
+      vimeoOptions.autoplay = true;
+    }
+    if (typeof(this.options_.controls) != "undefined") {
+      vimeoOptions.controls = this.options_.controls;
+    }
+
+    if (this.options_.height) {
+      vimeoOptions.height = this.options_.height;
+    }
+    if (this.options_.width) {
+      vimeoOptions.width = this.options_.width;
+    }
+    if (this.options_.maxheight) {
+      vimeoOptions.maxheight = this.options_.maxheight;
+    }
+    if (this.options_.maxwidth) {
+      vimeoOptions.maxwidth = this.options_.maxwidth;
+    }
+    if (this.options_.loop) {
+      vimeoOptions.loop = this.options_.loop;
+    }
+    if (this.options_.color) {
+      vimeoOptions.color = this.options_.color.replace(/^#/, '');
+    }
+    vimeoOptions.controls = false;
+
+
+    this._player = new VimeoPlayer(this.el(), vimeoOptions);
+    this.initVimeoState();
+
+    ['play', 'pause', 'ended', 'timeupdate', 'progress', 'seeked'].forEach(e => {
+      this._player.on(e, (progress) => {
+        if (this._vimeoState.progress.duration !== progress.duration) {
+          this.trigger('durationchange');
+        }
+        this._vimeoState.progress = progress;
+        this.trigger(e);
+      });
+    });
+
+    this._player.on('pause', () => (this._vimeoState.playing = false));
+    this._player.on('play', () => {
+      this._vimeoState.playing = true;
+      this._vimeoState.ended = false;
+    });
+    this._player.on('ended', () => {
+      this._vimeoState.playing = false;
+      this._vimeoState.ended = true;
+    });
+    this._player.on('volumechange', (v) => (this._vimeoState.volume = v));
+    this._player.on('error', e => this.trigger('error', e));
+
+    this.triggerReady();
+  }
+
+  initVimeoState() {
+    const state = this._vimeoState = {
+      ended: false,
+      playing: false,
+      volume: 0,
+      progress: {
+        seconds: 0,
+        percent: 0,
+        duration: 0
+      }
+    };
+
+    this._player.getCurrentTime().then(time => (state.progress.seconds = time));
+    this._player.getDuration().then(time => (state.progress.duration = time));
+    this._player.getPaused().then(paused => (state.playing = !paused));
+    this._player.getVolume().then(volume => (state.volume = volume));
+  }
+
+  createEl() {
+    const div = videojs.dom.createEl('div', {
+      id: this.options_.techId
+    });
+
+    div.style.cssText = 'width:100%;height:100%;top:0;left:0;position:absolute';
+    div.className = 'vjs-vimeo';
+
+    return div;
+  }
+
+  controls() {
+    return true;
+  }
+
+  supportsFullScreen() {
+    return true;
+  }
+
+  src() {
+    return this.options_.source;
+  }
+
+  currentSrc() {
+    return this.options_.source.src;
+  }
+
+  currentTime() {
+    return this._vimeoState.progress.seconds;
+  }
+
+  setCurrentTime(time) {
+    this._player.setCurrentTime(time);
+  }
+
+  volume() {
+    return this._vimeoState.volume;
+  }
+
+  setVolume(volume) {
+    return this._player.setVolume(volume);
+  }
+
+  duration() {
+    return this._vimeoState.progress.duration;
+  }
+
+  buffered() {
+    const progress = this._vimeoState.progress;
+
+    return videojs.createTimeRange(0, progress.percent * progress.duration);
+  }
+
+  paused() {
+    return !this._vimeoState.playing;
+  }
+
+  pause() {
+    this._player.pause();
+  }
+
+  play() {
+    this._player.play();
+  }
+
+  muted() {
+    return this._vimeoState.volume === 0;
+  }
+
+  setMuted(muted) {
+    return this._player.setMuted(muted);
+  }
+
+  ended() {
+    return this._vimeoState.ended;
+  }
+
+  playbackRate() {
+    return 1;
+  }
+
+}
+
+Vimeo.prototype.featuresTimeupdateEvents = true;
+
+Vimeo.isSupported = function () {
+  return true;
+};
+
+// Add Source Handler pattern functions to this tech
+Tech.withSourceHandlers(Vimeo);
+
+Vimeo.nativeSourceHandler = {
+};
+
+/**
+ * Check if Vimeo can play the given videotype
+ *
+ * @param  {string} source    The mimetype to check
+ * @return {string}         'maybe', or '' (empty string)
+ */
+Vimeo.nativeSourceHandler.canPlayType = function (source) {
+  if (source === 'video/vimeo') {
+    return 'maybe';
+  }
+
+  return '';
+};
+
+/*
+ * Check Vimeo can handle the source natively
+ *
+ * @param  {Object} source  The source object
+ * @return {String}         'maybe', or '' (empty string)
+ * @note: Copied over from YouTube — not sure this is relevant
+ */
+Vimeo.nativeSourceHandler.canHandleSource = function (source) {
+  if (source.type) {
+    return Vimeo.nativeSourceHandler.canPlayType(source.type);
+  } else if (source.src) {
+    return Vimeo.nativeSourceHandler.canPlayType(source.src);
+  }
+
+  return '';
+};
+
+// @note: Copied over from YouTube — not sure this is relevant
+Vimeo.nativeSourceHandler.handleSource = function (source, tech) {
+  tech.src(source.src);
+};
+
+// @note: Copied over from YouTube — not sure this is relevant
+Vimeo.nativeSourceHandler.dispose = function () { };
+
+Vimeo.registerSourceHandler(Vimeo.nativeSourceHandler);
+
+// Older versions of VJS5 doesn't have the registerTech function
+if (typeof videojs.registerTech !== 'undefined') {
+  videojs.registerTech('Vimeo', Vimeo);
+} else {
+  videojs.registerComponent('Vimeo', Vimeo);
+}
+
+// Include the version number.
+Vimeo.VERSION = '0.0.1';
+
+export default Vimeo;