You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

460 lines
13 KiB

10 years ago
  1. /* ******************************
  2. Module - Video
  3. Author: Jack Lukic
  4. This is a video playlist and video embed plugin which helps
  5. provide helpers for adding embed code for vimeo and youtube and
  6. abstracting event handlers for each library
  7. ****************************** */
  8. ;(function ($, window, document, undefined) {
  9. $.fn.video = function(parameters) {
  10. var
  11. $allModules = $(this),
  12. moduleSelector = $allModules.selector || '',
  13. time = new Date().getTime(),
  14. performance = [],
  15. query = arguments[0],
  16. methodInvoked = (typeof query == 'string'),
  17. queryArguments = [].slice.call(arguments, 1),
  18. returnedValue
  19. ;
  20. $allModules
  21. .each(function() {
  22. var
  23. settings = ( $.isPlainObject(parameters) )
  24. ? $.extend(true, {}, $.fn.video.settings, parameters)
  25. : $.extend({}, $.fn.video.settings),
  26. selector = settings.selector,
  27. className = settings.className,
  28. error = settings.error,
  29. metadata = settings.metadata,
  30. namespace = settings.namespace,
  31. eventNamespace = '.' + namespace,
  32. moduleNamespace = 'module-' + namespace,
  33. $module = $(this),
  34. $placeholder = $module.find(selector.placeholder),
  35. $playButton = $module.find(selector.playButton),
  36. $embed = $module.find(selector.embed),
  37. element = this,
  38. instance = $module.data(moduleNamespace),
  39. module
  40. ;
  41. module = {
  42. initialize: function() {
  43. module.debug('Initializing video');
  44. $placeholder
  45. .on('click' + eventNamespace, module.play)
  46. ;
  47. $playButton
  48. .on('click' + eventNamespace, module.play)
  49. ;
  50. module.instantiate();
  51. },
  52. instantiate: function() {
  53. module.verbose('Storing instance of module', module);
  54. instance = module;
  55. $module
  56. .data(moduleNamespace, module)
  57. ;
  58. },
  59. destroy: function() {
  60. module.verbose('Destroying previous instance of video');
  61. $module
  62. .removeData(moduleNamespace)
  63. .off(eventNamespace)
  64. ;
  65. $placeholder
  66. .off(eventNamespace)
  67. ;
  68. $playButton
  69. .off(eventNamespace)
  70. ;
  71. },
  72. // sets new video
  73. change: function(source, id, url) {
  74. module.debug('Changing video to ', source, id, url);
  75. $module
  76. .data(metadata.source, source)
  77. .data(metadata.id, id)
  78. .data(metadata.url, url)
  79. ;
  80. settings.onChange();
  81. },
  82. // clears video embed
  83. reset: function() {
  84. module.debug('Clearing video embed and showing placeholder');
  85. $module
  86. .removeClass(className.active)
  87. ;
  88. $embed
  89. .html(' ')
  90. ;
  91. $placeholder
  92. .show()
  93. ;
  94. settings.onReset();
  95. },
  96. // plays current video
  97. play: function() {
  98. module.debug('Playing video');
  99. var
  100. source = $module.data(metadata.source) || false,
  101. url = $module.data(metadata.url) || false,
  102. id = $module.data(metadata.id) || false
  103. ;
  104. $embed
  105. .html( module.generate.html(source, id, url) )
  106. ;
  107. $module
  108. .addClass(className.active)
  109. ;
  110. settings.onPlay();
  111. },
  112. generate: {
  113. // generates iframe html
  114. html: function(source, id, url) {
  115. module.debug('Generating embed html');
  116. var
  117. width = (settings.width == 'auto')
  118. ? $module.width()
  119. : settings.width,
  120. height = (settings.height == 'auto')
  121. ? $module.height()
  122. : settings.height,
  123. html
  124. ;
  125. if(source && id) {
  126. if(source == 'vimeo') {
  127. html = ''
  128. + '<iframe src="http://player.vimeo.com/video/' + id + '?=' + module.generate.url(source) + '"'
  129. + ' width="' + width + '" height="' + height + '"'
  130. + ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
  131. ;
  132. }
  133. else if(source == 'youtube') {
  134. html = ''
  135. + '<iframe src="http://www.youtube.com/embed/' + id + '?=' + module.generate.url(source) + '"'
  136. + ' width="' + width + '" height="' + height + '"'
  137. + ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
  138. ;
  139. }
  140. }
  141. else if(url) {
  142. html = ''
  143. + '<iframe src="' + url + '"'
  144. + ' width="' + width + '" height="' + height + '"'
  145. + ' frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
  146. ;
  147. }
  148. else {
  149. module.error(error.noVideo);
  150. }
  151. return html;
  152. },
  153. // generate url parameters
  154. url: function(source) {
  155. var
  156. api = (settings.api)
  157. ? 1
  158. : 0,
  159. autoplay = (settings.autoplay)
  160. ? 1
  161. : 0,
  162. hd = (settings.hd)
  163. ? 1
  164. : 0,
  165. showUI = (settings.showUI)
  166. ? 1
  167. : 0,
  168. // opposite used for some params
  169. hideUI = !(settings.showUI)
  170. ? 1
  171. : 0,
  172. url = ''
  173. ;
  174. if(source == 'vimeo') {
  175. url = ''
  176. + 'api=' + api
  177. + '&amp;title=' + showUI
  178. + '&amp;byline=' + showUI
  179. + '&amp;portrait=' + showUI
  180. + '&amp;autoplay=' + autoplay
  181. ;
  182. if(settings.color) {
  183. url += '&amp;color=' + settings.color;
  184. }
  185. }
  186. if(source == 'ustream') {
  187. url = ''
  188. + 'autoplay=' + autoplay
  189. ;
  190. if(settings.color) {
  191. url += '&amp;color=' + settings.color;
  192. }
  193. }
  194. else if(source == 'youtube') {
  195. url = ''
  196. + 'enablejsapi=' + api
  197. + '&amp;autoplay=' + autoplay
  198. + '&amp;autohide=' + hideUI
  199. + '&amp;hq=' + hd
  200. + '&amp;modestbranding=1'
  201. ;
  202. if(settings.color) {
  203. url += '&amp;color=' + settings.color;
  204. }
  205. }
  206. return url;
  207. }
  208. },
  209. setting: function(name, value) {
  210. module.debug('Changing setting', name, value);
  211. if( $.isPlainObject(name) ) {
  212. $.extend(true, settings, name);
  213. }
  214. else if(value !== undefined) {
  215. settings[name] = value;
  216. }
  217. else {
  218. return settings[name];
  219. }
  220. },
  221. internal: function(name, value) {
  222. if( $.isPlainObject(name) ) {
  223. $.extend(true, module, name);
  224. }
  225. else if(value !== undefined) {
  226. module[name] = value;
  227. }
  228. else {
  229. return module[name];
  230. }
  231. },
  232. debug: function() {
  233. if(settings.debug) {
  234. if(settings.performance) {
  235. module.performance.log(arguments);
  236. }
  237. else {
  238. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  239. module.debug.apply(console, arguments);
  240. }
  241. }
  242. },
  243. verbose: function() {
  244. if(settings.verbose && settings.debug) {
  245. if(settings.performance) {
  246. module.performance.log(arguments);
  247. }
  248. else {
  249. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  250. module.verbose.apply(console, arguments);
  251. }
  252. }
  253. },
  254. error: function() {
  255. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  256. module.error.apply(console, arguments);
  257. },
  258. performance: {
  259. log: function(message) {
  260. var
  261. currentTime,
  262. executionTime,
  263. previousTime
  264. ;
  265. if(settings.performance) {
  266. currentTime = new Date().getTime();
  267. previousTime = time || currentTime;
  268. executionTime = currentTime - previousTime;
  269. time = currentTime;
  270. performance.push({
  271. 'Element' : element,
  272. 'Name' : message[0],
  273. 'Arguments' : [].slice.call(message, 1) || '',
  274. 'Execution Time' : executionTime
  275. });
  276. }
  277. clearTimeout(module.performance.timer);
  278. module.performance.timer = setTimeout(module.performance.display, 100);
  279. },
  280. display: function() {
  281. var
  282. title = settings.name + ':',
  283. totalTime = 0
  284. ;
  285. time = false;
  286. clearTimeout(module.performance.timer);
  287. $.each(performance, function(index, data) {
  288. totalTime += data['Execution Time'];
  289. });
  290. title += ' ' + totalTime + 'ms';
  291. if(moduleSelector) {
  292. title += ' \'' + moduleSelector + '\'';
  293. }
  294. if($allModules.size() > 1) {
  295. title += ' ' + '(' + $allModules.size() + ')';
  296. }
  297. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  298. console.groupCollapsed(title);
  299. if(console.table) {
  300. console.table(performance);
  301. }
  302. else {
  303. $.each(performance, function(index, data) {
  304. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  305. });
  306. }
  307. console.groupEnd();
  308. }
  309. performance = [];
  310. }
  311. },
  312. invoke: function(query, passedArguments, context) {
  313. var
  314. object = instance,
  315. maxDepth,
  316. found,
  317. response
  318. ;
  319. passedArguments = passedArguments || queryArguments;
  320. context = element || context;
  321. if(typeof query == 'string' && object !== undefined) {
  322. query = query.split(/[\. ]/);
  323. maxDepth = query.length - 1;
  324. $.each(query, function(depth, value) {
  325. var camelCaseValue = (depth != maxDepth)
  326. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  327. : query
  328. ;
  329. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  330. object = object[camelCaseValue];
  331. }
  332. else if( object[camelCaseValue] !== undefined ) {
  333. found = object[camelCaseValue];
  334. return false;
  335. }
  336. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  337. object = object[value];
  338. }
  339. else if( object[value] !== undefined ) {
  340. found = object[value];
  341. return false;
  342. }
  343. else {
  344. return false;
  345. }
  346. });
  347. }
  348. if ( $.isFunction( found ) ) {
  349. response = found.apply(context, passedArguments);
  350. }
  351. else if(found !== undefined) {
  352. response = found;
  353. }
  354. if($.isArray(returnedValue)) {
  355. returnedValue.push(response);
  356. }
  357. else if(returnedValue !== undefined) {
  358. returnedValue = [returnedValue, response];
  359. }
  360. else if(response !== undefined) {
  361. returnedValue = response;
  362. }
  363. return found;
  364. }
  365. };
  366. if(methodInvoked) {
  367. if(instance === undefined) {
  368. module.initialize();
  369. }
  370. module.invoke(query);
  371. }
  372. else {
  373. if(instance !== undefined) {
  374. module.destroy();
  375. }
  376. module.initialize();
  377. }
  378. })
  379. ;
  380. return (returnedValue !== undefined)
  381. ? returnedValue
  382. : this
  383. ;
  384. };
  385. $.fn.video.settings = {
  386. name : 'Video',
  387. namespace : 'video',
  388. debug : false,
  389. verbose : true,
  390. performance : true,
  391. metadata : {
  392. source : 'source',
  393. id : 'id',
  394. url : 'url'
  395. },
  396. onPlay : function(){},
  397. onReset : function(){},
  398. onChange : function(){},
  399. // callbacks not coded yet (needs to use jsapi)
  400. onPause : function() {},
  401. onStop : function() {},
  402. width : 'auto',
  403. height : 'auto',
  404. autoplay : false,
  405. color : '#442359',
  406. hd : true,
  407. showUI : false,
  408. api : true,
  409. error : {
  410. noVideo : 'No video specified',
  411. method : 'The method you called is not defined'
  412. },
  413. className : {
  414. active : 'active'
  415. },
  416. selector : {
  417. embed : '.embed',
  418. placeholder : '.placeholder',
  419. playButton : '.play'
  420. }
  421. };
  422. })( jQuery, window , document );