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.

427 lines
12 KiB

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