'use strict'; (function($) { $.fn.padmavideo = function(id, options) { var opts = $.extend({ 'layers': ['transcripts'], 'url': "http://pad.ma/api/", 'time_in': 0, 'time_out': 0, 'padma_base': 'http://pad.ma/', 'resolution': '480p', 'width': '640', 'interval': 400, 'action': 'get' //action POST param to send to url }, options); var $this = this; var keys = ['layers']; //FIXME: add more apt keys var $loading = $('
').addClass("padmaLoading").text("Loading video...").appendTo($this); var sendData = JSON.stringify({'id': id, 'keys': keys}); //alert("hi"); var deferred = $.post(opts.url, {'action': opts.action, 'data': sendData}, function(response) { $loading.hide().remove(); var padma = new PadmaVideo(id, response.data, $this, opts); padma.render(); }, "json"); deferred.error(function(data) { alert("failed to load video data"); }); }; var PadmaVideo = function(id, data, $el, opts) { this.id = id; this.data = data; this.$el = $el; this.o = opts; this.videoURL = opts.padma_base + id + "/" + opts.resolution + ".webm"; this.render = function() { var that = this; this.$el.empty(); this.$el.append(that.getWidget()); }; this.getWidget = function() { var that = this; var $container = this.$container = $('').addClass("padmaContainer"); var $video = this.$video = $('') .appendTo($container) .attr("src", that.videoURL) .attr("controls", "controls") .addClass("padmaVideo") .animate({'width': that.o.width}) .load() .bind("play", function() { that.interval = setInterval(function() { that.updatePlayer(); }, that.o.interval); }) .bind("pause", function() { clearInterval(that.interval); }) .bind("ended", function() { clearInterval(that.interval); }) .bind("seeked", function() { that.updatePlayer(); }); var $annotations = this.$annotations = $('') .addClass("padmaAnnotations") .appendTo($container); return $container; }; this.updatePlayer = function() { var that = this; var currentTime = this.$video[0].currentTime; //first, handle if video has crossed end-point if (that.o.time_out != 0) { if (currentTime > that.o.time_out) { that.$video[0].currentTime = that.o.time_out; that.$video[0].pause(); } if (currentTime < that.o.time_in) { that.$video[0].currentTime = that.o.time_in; that.$video[0].pause(); } } //now get all matching layers at current time code var layerNames = this.o.layers, matchedLayers = {}; $.each(layerNames, function(i, layerName) { matchedLayers[layerName] = that.getLayersAtTimecode(layerName, currentTime) }); //if layers are the same as last update, return if (isSameLayers(matchedLayers, that.currentLayers)) return false; //else, construct DOM elements for currently matched layers, etc. that.currentLayers = matchedLayers; that.$annotations.empty(); for (var layer in matchedLayers) { if (matchedLayers.hasOwnProperty(layer)) { var theseLayers = matchedLayers[layer]; if (theseLayers.length > 0) { var $annotsForLayer = getElemForLayer(layer, theseLayers); $annotsForLayer.appendTo(that.$annotations); } } } }; this.getLayersAtTimecode = function(layerName, currentTime) { var ret = []; var theseLayers = this.data.layers[layerName]; $.each(theseLayers, function(i,layer) { if (layer['in'] < currentTime && layer.out > currentTime) { ret.push(layer); } }); return ret; }; }; function getElemForLayer(layerName, layers) { var $elem = $('').addClass("padmaLayer"); var title = layerName.substr(0,1).toUpperCase() + layerName.substr(1, layerName.length); var $title = $('').addClass("padmaLayerTitle").text(title).appendTo($elem); $.each(layers, function(i,v) { var $annot = $('').addClass("padmaAnnot"); //TODO: add time-code div var $annotText = $('') .addClass("padmaAnnotText") .html(v.value) .appendTo($annot); $annot.appendTo($elem); }); return $elem; } function isSameLayers(layers1, layers2) { var idString1 = '', idString2 = ''; for (var l in layers1) { if (layers1.hasOwnProperty(l)) { $.each(layers1[l], function(i,v) { idString1 += v.id; }); } } for (var l in layers2) { if (layers2.hasOwnProperty(l)) { $.each(layers2[l], function(i,v) { idString2 += v.id; }); } } return idString1 == idString2 } //return true or false based on whether the browser can play padma video function canPlayVideo() { return true; } //loop through all elements with class padmaVideo and automagically instantiate them using optional data- attributes for options $(document).ready(function() { $('.padmaVideo').each(function() { var padmaId = $(this).attr("data-padma-id"), options = {}, $this = $(this); if ($this.hasAttr("data-padma-layers")) options.layers = $this.attr("data-padma-layers"); if ($this.hasAttr("data-padma-url")) options.url = $this.attr("data-padma-url"); if ($this.hasAttr("data-padma-in")) options.time_in = $this.attr("data-padma-in"); if ($this.hasAttr("data-padma-out")) options.time_out = $this.attr("data-padma-out"); if ($this.hasAttr("data-padma-base")) options.padma_base = $this.attr("data-padma-base"); if ($this.hasAttr("data-padma-resolution")) options.resolution = $this.attr("data-padma-resolution"); if ($this.hasAttr("data-padma-width")) options.width = $this.attr("data-padma-width"); if ($this.hasAttr("data-padma-interval")) options.interval = $this.attr("data-padma-interval"); // if ($this.hasAttr("data-padma-height")) options.height = $this.attr("data-padma-height"); $this.padmavideo(padmaId, options); }); }); $.fn.hasAttr = function(attr) { return this.attr(attr) != undefined; }; })(jQuery);