- function Video(options) {
- // name of folder
- this.slug = options.slug;
- Video[options.slug] = this;
- // files to load, recursive object, associates files with keys
- this.deps = options.deps || {};
- // function to call before another video starts
- this._teardown = options.teardown || function() {};
- // function to call when this video starts
- this._start = options.start || function(container, callback) { callback() };
- // function to call when the position is changed
- this._setPosition = options.setPosition || function() {};
- this._loop = options.loop;
- this._resize = options.resize;
- this._canPlay = options.canPlay || function () { return true };
- _.extend(this, options.methods || {});
- // should we smooth the playhead
- this.smoothPosition = true;
- // maximum amount to let the smoothed playhead drift from the actual playhead
- this.maxSmooth = 300;
- // global millisecond offset for midi player
- this.offset = options.offset;
- this.lastPosition = this.position = 0;
- this.started = false;
- }
- Video.prototype.start = function(container, forcePlayback, success, failure) {
- if (!forcePlayback) {
- var canPlay = this._canPlay();
- if (canPlay !== true) {
- failure(canPlay);
- return;
- }
- }
- var _this = this;
- var count = 0;
- count += this.player ? 0 : 1;
- count += countStrings(this.deps);
- var loaded = _.after(count, function() {
- _this.depsLoaded = true;
- if (_this._resize) window.removeEventListener('resize', this._resize, false);
- start();
- });
- container.className = this.slug;
- // if we haven't made a player object for this track yet ...
- if (!this.player) {
- this.player = new midi.Player('mid/'+this.slug+'.mid');
- this.player.load(loaded);
- }
- // load deps
- if (this.depsLoaded) {
- start();
- } else {
- _.each(this.deps, function(paths, dict) {
- this.deps[dict] = {};
- _.each(paths, function(path, key) {
- get(path, function(text) {
- _this.deps[dict][key] = text;
- loaded();
- });
- });
- }, this);
- }
- function start() {
- _this._start(container, function() {
- _this.started = true;
- success();
- });
- }
- // count keys in 1 level deep object
- function countStrings(obj) {
- var count = 0;
- _.each(obj, function(dict, key) {
- count += _.keys(dict).length;
- });
- return count;
- }
- };
- Video.prototype.update = function(sourcePosition) {
- sourcePosition = sourcePosition || 0;
- this.lastTime = this.time;
- this.time = Date.now();
- if (sourcePosition != this.lastPosition) {
- this.position = sourcePosition;
- } else if (this.smoothPosition) {
- this.position += (this.time - this.lastTime);
- this.position = Math.min(this.position, sourcePosition + this.maxSmooth);
- }
- this.lastPosition = sourcePosition;
- this.player.update(this.position - this.offset);
- };
- // gives videos access to the main raf loop.
- Video.prototype.loop = function() {
- this.started && this._loop && this._loop(this.position, this.lastPosition);
- };
- Video.prototype.setPosition = function(position) {
- this._loop && this.loop(position, this.lastPosition);
- this._setPosition(position, this.lastPosition);
- this.lastTime = this.time = Date.now();
- this.player.setPosition(position);
- };
- Video.prototype.play = function() {
- this.lastTime = this.time = Date.now();
- if (this.player) this.player.play();
- };
- Video.prototype.pause = function() {
- if (this.player) this.player.pause();
- };
- Video.prototype.teardown = function(container) {
- // todo: reset clock?
- this.lastPosition = this.position = 0;
- this.pause();
- this._teardown(container);
- this.started = false;
- if (this._resize) window.removeEventListener('resize', this._resize, false);
- }
Recent Pastes