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.

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