add comments, change structure of parsing data- attribs
This commit is contained in:
parent
8c7d55f67b
commit
04d8953464
|
@ -3,6 +3,13 @@
|
||||||
<head>
|
<head>
|
||||||
<script type="text/javascript" src="jquery.js"></script>
|
<script type="text/javascript" src="jquery.js"></script>
|
||||||
<script type="text/javascript" src="padmavideo.js"></script>
|
<script type="text/javascript" src="padmavideo.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(function() {
|
||||||
|
$('.padmaVideo').padmavideo({
|
||||||
|
'callback': function(video) { console.log(video); foo = video;}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="padmaVideo" data-padma-id="AJW"></div>
|
<div class="padmaVideo" data-padma-id="AJW"></div>
|
||||||
|
|
200
padmavideo.js
200
padmavideo.js
|
@ -1,28 +1,48 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function($) {
|
(function($) {
|
||||||
$.fn.padmavideo = function(id, options) {
|
$.fn.padmavideo = function(options) {
|
||||||
|
|
||||||
|
//get options, giving preference, in order, to data- attributes defined on the html element, options passed when instantiatiing $(element).padmavideo(options), defaults.
|
||||||
|
var options = options || {},
|
||||||
|
namespace = options.namespace || "padma",
|
||||||
|
$this = this;
|
||||||
|
|
||||||
|
|
||||||
|
var optionTypes = {
|
||||||
|
'strings': ['api', 'base', 'resolution', 'action', 'id'],
|
||||||
|
'integers': ['in', 'out', 'width', 'interval'],
|
||||||
|
'arrays': ['layers', 'keys']
|
||||||
|
//'functions': ['callback'] FIXME: lets not.
|
||||||
|
};
|
||||||
|
|
||||||
|
var dataOptions = $.extend(options, $this.getDataOptions(optionTypes, namespace));
|
||||||
|
|
||||||
var opts = $.extend({
|
var opts = $.extend({
|
||||||
|
'id': 'ABC', //FIXME: throw an error if id is undefined at this point
|
||||||
'layers': ['transcripts'],
|
'layers': ['transcripts'],
|
||||||
'url': "http://pad.ma/api/",
|
'keys': ['layers'], //FIXME: add more apt keys
|
||||||
'time_in': 0,
|
'api': "http://pad.ma/api/",
|
||||||
'time_out': 0,
|
'in': 0,
|
||||||
|
'out': 0,
|
||||||
'padma_base': 'http://pad.ma/',
|
'padma_base': 'http://pad.ma/',
|
||||||
'resolution': '480p',
|
'resolution': '480p',
|
||||||
'width': '640',
|
'width': '640',
|
||||||
'interval': 400,
|
'interval': 400,
|
||||||
'action': 'get' //action POST param to send to url
|
'action': 'get', //action POST param to send to url
|
||||||
}, options);
|
'callback': function() { $.noop(); } //function to call after done instantiating PadmaVideo object, called with the object.
|
||||||
var $this = this;
|
}, dataOptions);
|
||||||
|
|
||||||
var keys = ['layers']; //FIXME: add more apt keys
|
//get the padma id and instantiate a PadmaVideo object with the current element and render it and execute optional callback
|
||||||
var $loading = $('<div />').addClass("padmaLoading").text("Loading video...").appendTo($this);
|
var id = opts.id,
|
||||||
var sendData = JSON.stringify({'id': id, 'keys': keys});
|
$loading = $('<div />').addClass("padmaLoading").text("Loading video...").appendTo($this),
|
||||||
//alert("hi");
|
sendData = JSON.stringify({'id': id, 'keys': opts.keys});
|
||||||
var deferred = $.post(opts.url, {'action': opts.action, 'data': sendData}, function(response) {
|
|
||||||
|
var deferred = $.post(opts.api, {'action': opts.action, 'data': sendData}, function(response) {
|
||||||
$loading.hide().remove();
|
$loading.hide().remove();
|
||||||
var padma = new PadmaVideo(id, response.data, $this, opts);
|
var padma = new PadmaVideo(id, response.data, $this, opts);
|
||||||
padma.render();
|
padma.render();
|
||||||
|
opts.callback(padma);
|
||||||
}, "json");
|
}, "json");
|
||||||
|
|
||||||
deferred.error(function(data) {
|
deferred.error(function(data) {
|
||||||
|
@ -30,29 +50,80 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
PadmaVideo class
|
||||||
|
Parameters:
|
||||||
|
id: <string> pandora video id
|
||||||
|
data: <object> data for the video object
|
||||||
|
$el: <jQuery element>
|
||||||
|
opts: <object> options object
|
||||||
|
|
||||||
|
*/
|
||||||
var PadmaVideo = function(id, data, $el, opts) {
|
var PadmaVideo = function(id, data, $el, opts) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.$el = $el;
|
this.$el = $el;
|
||||||
this.o = opts;
|
this.o = opts;
|
||||||
this.videoURL = opts.padma_base + id + "/" + opts.resolution + ".webm";
|
this.getVideoURL = function() {
|
||||||
|
return opts.padma_base + id + "/" + opts.resolution + ".webm";
|
||||||
|
};
|
||||||
|
//empties element, appends video widget
|
||||||
this.render = function() {
|
this.render = function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
this.$el.empty();
|
this.$el.empty();
|
||||||
this.$el.append(that.getWidget());
|
this.$el.append(that.getWidget());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Use this to set options on the player from the outside.
|
||||||
|
Example:
|
||||||
|
var padmaVideoObject = $('#video').data("padmavideo");
|
||||||
|
padmaVideoObject.setOption("width", 250);
|
||||||
|
*/
|
||||||
|
this.setOption = function(key, val) {
|
||||||
|
var that = this;
|
||||||
|
this.o[key] = val;
|
||||||
|
if ($.inArray(key, ['resolution']) != -1) {
|
||||||
|
this.destroy();
|
||||||
|
this.render();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if ($.inArray(key, ['in', 'out', 'layers']) != -1) {
|
||||||
|
this.updatePlayer();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if ($.inArray(key, ['width']) != -1) {
|
||||||
|
this.$video.animate({'width': that.o.width + "px"});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
console.log("attempt to set invalid option or option which will make no difference to player state");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns currently defined option for key specified
|
||||||
|
Parameters:
|
||||||
|
key: <string> eg. 'width'
|
||||||
|
*/
|
||||||
|
this.getOption = function(key) {
|
||||||
|
return this.o[key] || "invalid option";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//returns <jQuery element> widget for this PadmaVideo object
|
||||||
this.getWidget = function() {
|
this.getWidget = function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
var $container = this.$container = $('<div />').addClass("padmaContainer");
|
var $container = this.$container = $('<div />').addClass("padmaContainer");
|
||||||
var $video = this.$video = $('<video />')
|
var $video = this.$video = $('<video />')
|
||||||
.appendTo($container)
|
.appendTo($container)
|
||||||
.attr("src", that.videoURL)
|
.attr("src", that.getVideoURL())
|
||||||
.attr("controls", "controls")
|
.attr("controls", "controls")
|
||||||
.addClass("padmaVideo")
|
.addClass("padmaVideo")
|
||||||
.animate({'width': that.o.width})
|
.animate({'width': that.o.width})
|
||||||
.load()
|
.load()
|
||||||
|
.bind("loadedmetadata", function() {
|
||||||
|
that.updatePlayer();
|
||||||
|
})
|
||||||
.bind("play", function() {
|
.bind("play", function() {
|
||||||
that.interval = setInterval(function() {
|
that.interval = setInterval(function() {
|
||||||
that.updatePlayer();
|
that.updatePlayer();
|
||||||
|
@ -73,18 +144,19 @@
|
||||||
return $container;
|
return $container;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//update annotations, etc. based on video currentTime
|
||||||
this.updatePlayer = function() {
|
this.updatePlayer = function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
var currentTime = this.$video[0].currentTime;
|
var currentTime = this.$video[0].currentTime;
|
||||||
|
|
||||||
//first, handle if video has crossed end-point
|
//first, handle if video has crossed out-point or is before in-point
|
||||||
if (that.o.time_out != 0) {
|
if (that.o.out != 0) {
|
||||||
if (currentTime > that.o.time_out) {
|
if (currentTime >= that.o.out) {
|
||||||
that.$video[0].currentTime = that.o.time_out;
|
that.$video[0].currentTime = that.o.out;
|
||||||
that.$video[0].pause();
|
that.$video[0].pause();
|
||||||
}
|
}
|
||||||
if (currentTime < that.o.time_in) {
|
if (currentTime <= that.o['in']) {
|
||||||
that.$video[0].currentTime = that.o.time_in;
|
that.$video[0].currentTime = that.o['in'];
|
||||||
that.$video[0].pause();
|
that.$video[0].pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +184,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parameters:
|
||||||
|
layerName: <string> eg. 'transcripts'
|
||||||
|
currentTime: <float> in seconds
|
||||||
|
Returns <array> of matched layer objects
|
||||||
|
*/
|
||||||
this.getLayersAtTimecode = function(layerName, currentTime) {
|
this.getLayersAtTimecode = function(layerName, currentTime) {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
var theseLayers = this.data.layers[layerName];
|
var theseLayers = this.data.layers[layerName];
|
||||||
|
@ -124,8 +202,19 @@
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.destroy = function() {
|
||||||
|
this.$video[0].pause();
|
||||||
|
this.$video.remove();
|
||||||
|
this.$el.empty();
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parameters:
|
||||||
|
layerName: <string> eg. 'transcripts'
|
||||||
|
layers: <array> layer objects to render
|
||||||
|
Returns <jQuery element> for an annotation type - i.e. all 'transcripts', or all 'descriptions'
|
||||||
|
*/
|
||||||
function getElemForLayer(layerName, layers) {
|
function getElemForLayer(layerName, layers) {
|
||||||
var $elem = $('<div />').addClass("padmaLayer");
|
var $elem = $('<div />').addClass("padmaLayer");
|
||||||
var title = layerName.substr(0,1).toUpperCase() + layerName.substr(1, layerName.length);
|
var title = layerName.substr(0,1).toUpperCase() + layerName.substr(1, layerName.length);
|
||||||
|
@ -142,6 +231,14 @@
|
||||||
return $elem;
|
return $elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Silly function to check if two layer arrays are the same (i.e. to check if matchedLayers have changed)
|
||||||
|
Parameters:
|
||||||
|
layers1: <array> of layer objects
|
||||||
|
layers2: <array> of layer objects to compare with
|
||||||
|
Returns <boolean> true if layer arrays are the same, false if different
|
||||||
|
FIXME: this id concatenation string comparison is a bit weird, but it seemed like a non-expensive simple way to do it
|
||||||
|
*/
|
||||||
function isSameLayers(layers1, layers2) {
|
function isSameLayers(layers1, layers2) {
|
||||||
var idString1 = '',
|
var idString1 = '',
|
||||||
idString2 = '';
|
idString2 = '';
|
||||||
|
@ -162,34 +259,55 @@
|
||||||
return idString1 == idString2
|
return idString1 == idString2
|
||||||
}
|
}
|
||||||
|
|
||||||
//return true or false based on whether the browser can play padma video
|
//Returns <boolean> true or false based on whether the browser can play padma video
|
||||||
|
//FIXME: actually implement this function
|
||||||
function canPlayVideo() {
|
function canPlayVideo() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//loop through all elements with class padmaVideo and automagically instantiate them using optional data- attributes for options
|
/*
|
||||||
$(document).ready(function() {
|
Get options from data- attributes
|
||||||
$('.padmaVideo').each(function() {
|
Parameters:
|
||||||
var padmaId = $(this).attr("data-padma-id"),
|
optionTypes: <object>
|
||||||
options = {},
|
example: {
|
||||||
$this = $(this);
|
'strings': ['option1', 'option2', 'option3'],
|
||||||
|
'integers': ['fooint', 'barint'],
|
||||||
|
'arrays': ['list1', 'list2']
|
||||||
|
}
|
||||||
|
|
||||||
if ($this.hasAttr("data-padma-layers")) options.layers = $this.attr("data-padma-layers");
|
namespace: <string>
|
||||||
if ($this.hasAttr("data-padma-url")) options.url = $this.attr("data-padma-url");
|
example: 'padma'
|
||||||
if ($this.hasAttr("data-padma-in")) options.time_in = $this.attr("data-padma-in");
|
namespace for data- attributes
|
||||||
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");
|
example html:
|
||||||
if ($this.hasAttr("data-padma-resolution")) options.resolution = $this.attr("data-padma-resolution");
|
<div id="blah" data-padma-option1="foobar" data-padma-fooint="23" data-padma-list2="apples, oranges">
|
||||||
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);
|
|
||||||
|
|
||||||
|
usage:
|
||||||
|
var dataOptions = $('#blah').getDataOptions(optionTypes, namespace);
|
||||||
|
*/
|
||||||
|
$.fn.getDataOptions = function(optionTypes, namespace) {
|
||||||
|
var $element = this;
|
||||||
|
var prefix = "data-" + namespace + "-",
|
||||||
|
options = {};
|
||||||
|
$.each(optionTypes['strings'], function(i,v) {
|
||||||
|
var attr = prefix + v;
|
||||||
|
options[v] = $element.hasAttr(attr) ? $element.attr(attr) : undefined;
|
||||||
});
|
});
|
||||||
});
|
$.each(optionTypes['integers'], function(i,v) {
|
||||||
|
var attr = prefix + v;
|
||||||
|
options[v] = $element.hasAttr(attr) ? parseInt($element.attr(attr)) : undefined;
|
||||||
|
});
|
||||||
|
$.each(optionTypes['arrays'], function(i,v) {
|
||||||
|
var attr = prefix + v;
|
||||||
|
options[v] = $element.hasAttr(attr) ? $element.attr(attr).split(",") : undefined;
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
FIXME: possibly improve - http://stackoverflow.com/questions/1318076/jquery-hasattr-checking-to-see-if-there-is-an-attribute-on-an-element#1318091
|
||||||
|
*/
|
||||||
$.fn.hasAttr = function(attr) {
|
$.fn.hasAttr = function(attr) {
|
||||||
return this.attr(attr) != undefined;
|
return this.attr(attr) != undefined;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user