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.

463 lines
14 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 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. if(value !== undefined) {
  211. if( $.isPlainObject(name) ) {
  212. $.extend(true, settings, name);
  213. }
  214. else {
  215. settings[name] = value;
  216. }
  217. }
  218. else {
  219. return settings[name];
  220. }
  221. },
  222. internal: function(name, value) {
  223. if(value !== undefined) {
  224. if( $.isPlainObject(name) ) {
  225. $.extend(true, module, name);
  226. }
  227. else {
  228. module[name] = value;
  229. }
  230. }
  231. else {
  232. return module[name];
  233. }
  234. },
  235. debug: function() {
  236. if(settings.debug) {
  237. if(settings.performance) {
  238. module.performance.log(arguments);
  239. }
  240. else {
  241. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  242. module.debug.apply(console, arguments);
  243. }
  244. }
  245. },
  246. verbose: function() {
  247. if(settings.verbose && settings.debug) {
  248. if(settings.performance) {
  249. module.performance.log(arguments);
  250. }
  251. else {
  252. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  253. module.verbose.apply(console, arguments);
  254. }
  255. }
  256. },
  257. error: function() {
  258. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  259. module.error.apply(console, arguments);
  260. },
  261. performance: {
  262. log: function(message) {
  263. var
  264. currentTime,
  265. executionTime,
  266. previousTime
  267. ;
  268. if(settings.performance) {
  269. currentTime = new Date().getTime();
  270. previousTime = time || currentTime;
  271. executionTime = currentTime - previousTime;
  272. time = currentTime;
  273. performance.push({
  274. 'Element' : element,
  275. 'Name' : message[0],
  276. 'Arguments' : [].slice.call(message, 1) || '',
  277. 'Execution Time' : executionTime
  278. });
  279. }
  280. clearTimeout(module.performance.timer);
  281. module.performance.timer = setTimeout(module.performance.display, 100);
  282. },
  283. display: function() {
  284. var
  285. title = settings.name + ':',
  286. totalTime = 0
  287. ;
  288. time = false;
  289. clearTimeout(module.performance.timer);
  290. $.each(performance, function(index, data) {
  291. totalTime += data['Execution Time'];
  292. });
  293. title += ' ' + totalTime + 'ms';
  294. if(moduleSelector) {
  295. title += ' \'' + moduleSelector + '\'';
  296. }
  297. if($allModules.size() > 1) {
  298. title += ' ' + '(' + $allModules.size() + ')';
  299. }
  300. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  301. console.groupCollapsed(title);
  302. if(console.table) {
  303. console.table(performance);
  304. }
  305. else {
  306. $.each(performance, function(index, data) {
  307. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  308. });
  309. }
  310. console.groupEnd();
  311. }
  312. performance = [];
  313. }
  314. },
  315. invoke: function(query, passedArguments, context) {
  316. var
  317. maxDepth,
  318. found,
  319. response
  320. ;
  321. passedArguments = passedArguments || queryArguments;
  322. context = element || context;
  323. if(typeof query == 'string' && instance !== undefined) {
  324. query = query.split(/[\. ]/);
  325. maxDepth = query.length - 1;
  326. $.each(query, function(depth, value) {
  327. var camelCaseValue = (depth != maxDepth)
  328. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  329. : query
  330. ;
  331. if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  332. instance = instance[value];
  333. }
  334. else if( $.isPlainObject( instance[camelCaseValue] ) && (depth != maxDepth) ) {
  335. instance = instance[camelCaseValue];
  336. }
  337. else if( instance[value] !== undefined ) {
  338. found = instance[value];
  339. return false;
  340. }
  341. else if( instance[camelCaseValue] !== undefined ) {
  342. found = instance[camelCaseValue];
  343. return false;
  344. }
  345. else {
  346. module.error(error.method);
  347. return false;
  348. }
  349. });
  350. }
  351. if ( $.isFunction( found ) ) {
  352. response = found.apply(context, passedArguments);
  353. }
  354. else if(found !== undefined) {
  355. response = found;
  356. }
  357. if($.isArray(returnedValue)) {
  358. returnedValue.push(response);
  359. }
  360. else if(returnedValue !== undefined) {
  361. returnedValue = [returnedValue, response];
  362. }
  363. else if(response !== undefined) {
  364. returnedValue = response;
  365. }
  366. return found;
  367. }
  368. };
  369. if(methodInvoked) {
  370. if(instance === undefined) {
  371. module.initialize();
  372. }
  373. module.invoke(query);
  374. }
  375. else {
  376. if(instance !== undefined) {
  377. module.destroy();
  378. }
  379. module.initialize();
  380. }
  381. })
  382. ;
  383. return (returnedValue !== undefined)
  384. ? returnedValue
  385. : this
  386. ;
  387. };
  388. $.fn.video.settings = {
  389. name : 'Video',
  390. namespace : 'video',
  391. debug : true,
  392. verbose : true,
  393. performance : true,
  394. metadata : {
  395. source : 'source',
  396. id : 'id',
  397. url : 'url'
  398. },
  399. onPlay : function(){},
  400. onReset : function(){},
  401. onChange : function(){},
  402. // callbacks not coded yet (needs to use jsapi)
  403. onPause : function() {},
  404. onStop : function() {},
  405. width : 'auto',
  406. height : 'auto',
  407. autoplay : false,
  408. color : '#442359',
  409. hd : true,
  410. showUI : false,
  411. api : true,
  412. error : {
  413. noVideo : 'No video specified',
  414. method : 'The method you called is not defined'
  415. },
  416. className : {
  417. active : 'active'
  418. },
  419. selector : {
  420. embed : '.embed',
  421. placeholder : '.placeholder',
  422. playButton : '.play'
  423. }
  424. };
  425. })( jQuery, window , document );