JAVASCRIPT 13
Video.js Guest on 6th April 2021 03:12:58 AM
  1. function Video(options) {
  2.  
  3.     // name of folder
  4.     this.slug = options.slug;
  5.  
  6.     Video[options.slug] = this;
  7.  
  8.     // files to load, recursive object, associates files with keys
  9.     this.deps = options.deps || {};
  10.    
  11.     // function to call before another video starts
  12.     this._teardown = options.teardown || function() {};
  13.  
  14.     // function to call when this video starts
  15.     this._start = options.start || function(container, callback) { callback() };
  16.  
  17.     // function to call when the position is changed
  18.     this._setPosition = options.setPosition || function() {};
  19.  
  20.     this._loop = options.loop;
  21.  
  22.     this._resize = options.resize;
  23.  
  24.     this._canPlay = options.canPlay || function () { return true };
  25.  
  26.     _.extend(this, options.methods || {});
  27.  
  28.     // should we smooth the playhead
  29.     this.smoothPosition = true;
  30.  
  31.     // maximum amount to let the smoothed playhead drift from the actual playhead
  32.     this.maxSmooth = 300;
  33.  
  34.     // global millisecond offset for midi player
  35.     this.offset = options.offset;
  36.  
  37.     this.lastPosition = this.position = 0;
  38.     this.started = false;
  39.  
  40. }
  41.  
  42. Video.prototype.start = function(container, forcePlayback, success, failure) {
  43.  
  44.     if (!forcePlayback) {
  45.         var canPlay = this._canPlay();
  46.  
  47.         if (canPlay !== true) {
  48.             failure(canPlay);
  49.             return;
  50.         }
  51.     }
  52.  
  53.     var _this = this;
  54.  
  55.     var count = 0;
  56.     count += this.player ? 0 : 1;
  57.     count += countStrings(this.deps);
  58.  
  59.     var loaded = _.after(count, function() {
  60.  
  61.         _this.depsLoaded = true;
  62.        
  63.         if (_this._resize) window.removeEventListener('resize', this._resize, false);
  64.         start();
  65.  
  66.     });
  67.  
  68.     container.className = this.slug;
  69.  
  70.     // if we haven't made a player object for this track yet ...
  71.     if (!this.player) {
  72.         this.player = new midi.Player('mid/'+this.slug+'.mid');
  73.         this.player.load(loaded);
  74.     }
  75.  
  76.     // load deps
  77.     if (this.depsLoaded) {
  78.  
  79.         start();
  80.  
  81.     } else {
  82.  
  83.         _.each(this.deps, function(paths, dict) {
  84.  
  85.             this.deps[dict] = {};
  86.  
  87.             _.each(paths, function(path, key) {
  88.                 get(path, function(text) {
  89.                     _this.deps[dict][key] = text;
  90.                     loaded();
  91.                 });
  92.             });  
  93.        
  94.         }, this);
  95.  
  96.     }
  97.  
  98.     function start() {
  99.         _this._start(container, function() {
  100.             _this.started = true;
  101.             success();
  102.         });
  103.     }
  104.  
  105.     // count keys in 1 level deep object    
  106.     function countStrings(obj) {
  107.         var count = 0;
  108.         _.each(obj, function(dict, key) {
  109.             count += _.keys(dict).length;
  110.         });
  111.         return count;
  112.     }
  113.  
  114. };
  115.  
  116. Video.prototype.update = function(sourcePosition) {
  117.  
  118.     sourcePosition = sourcePosition || 0;
  119.  
  120.     this.lastTime = this.time;
  121.     this.time = Date.now();
  122.  
  123.     if (sourcePosition != this.lastPosition) {
  124.         this.position = sourcePosition;
  125.     } else if (this.smoothPosition) {
  126.         this.position += (this.time - this.lastTime);
  127.         this.position = Math.min(this.position, sourcePosition + this.maxSmooth);
  128.     }
  129.  
  130.     this.lastPosition = sourcePosition;
  131.  
  132.     this.player.update(this.position - this.offset);
  133.  
  134. };
  135.  
  136. // gives videos access to the main raf loop.
  137. Video.prototype.loop = function() {
  138.     this.started && this._loop && this._loop(this.position, this.lastPosition);
  139. };
  140.  
  141. Video.prototype.setPosition = function(position) {
  142.     this._loop && this.loop(position, this.lastPosition);
  143.     this._setPosition(position, this.lastPosition);
  144.     this.lastTime = this.time = Date.now();
  145.     this.player.setPosition(position);
  146. };
  147.  
  148. Video.prototype.play = function() {
  149.     this.lastTime = this.time = Date.now();
  150.     if (this.player) this.player.play();
  151. };
  152.  
  153. Video.prototype.pause = function() {
  154.     if (this.player) this.player.pause();
  155. };
  156.  
  157. Video.prototype.teardown = function(container) {
  158.     // todo: reset clock?
  159.     this.lastPosition = this.position = 0;
  160.     this.pause();
  161.     this._teardown(container);
  162.     this.started = false;
  163.     if (this._resize) window.removeEventListener('resize', this._resize, false);
  164. }

Paste-bin is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.