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
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[camelCaseValue] ) && (depth != maxDepth) ) {
  328. instance = instance[camelCaseValue];
  329. }
  330. else if( instance[camelCaseValue] !== undefined ) {
  331. found = instance[camelCaseValue];
  332. return false;
  333. }
  334. else if( $.isPlainObject( instance[value] ) && (depth != maxDepth) ) {
  335. instance = instance[value];
  336. }
  337. else if( instance[value] !== undefined ) {
  338. found = instance[value];
  339. return false;
  340. }
  341. else {
  342. module.error(error.method, query);
  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 );