PageRenderTime 77ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Mockups/ptototype/src/live.js

https://github.com/TheBiggerGuy/FreshAir
JavaScript | 497 lines | 307 code | 67 blank | 123 comment | 39 complexity | 53801d812d24db730a4c3d0ce33785af MD5 | raw file
Possible License(s): AGPL-1.0, Apache-2.0
  1. /**
  2. * @preserve FreshAir.org.uk Radio Player.
  3. * @author guy@thebiggerguy.com (Guy Taylor)
  4. * @version 0.6
  5. * @updated 29-DEC-2011
  6. * @created 08-JUL-2011
  7. * -----------------------------------------------------------------------------
  8. * Copyright (c) 2011 Guy Taylor (http://www.thebiggerguy.com)
  9. * Dual licensed under the MIT and GPL licenses.
  10. * - http://www.opensource.org/licenses/mit-license.php
  11. * - http://www.gnu.org/copyleft/gpl.html
  12. * -----------------------------------------------------------------------------
  13. * Includes jquery.pulse.js (version 0.1 16-DEC-09)
  14. * https://github.com/jamespadolsey/jQuery-Plugins/tree/master/pulse
  15. * Copyright (c) 210 James Padolsey (http://james.padolsey.com)
  16. * Dual licensed under the MIT and GPL licenses.
  17. * - http://www.opensource.org/licenses/mit-license.php
  18. * - http://www.gnu.org/copyleft/gpl.html
  19. * -----------------------------------------------------------------------------
  20. * Includes jquery.jplayer.js (version 2.0.0 20-DEC-10)
  21. * http://www.happyworm.com/jquery/jplayer
  22. * Copyright (c) 2009 - 2010 Happyworm Ltd
  23. * Dual licensed under the MIT and GPL licenses.
  24. * - http://www.opensource.org/licenses/mit-license.php
  25. * - http://www.gnu.org/copyleft/gpl.html
  26. * -----------------------------------------------------------------------------
  27. */
  28. /**
  29. * The CSS solector of the play/pasue image
  30. * @const
  31. * @type {string}
  32. */
  33. var CSS_PLAY_PAUSE_IMG = '#header-control img';
  34. /**
  35. * The CSS solector of the play/pasue div
  36. * @const
  37. * @type {string}
  38. */
  39. var CSS_PLAY_PAUSE_DIV = '#header-control';
  40. /**
  41. * The CSS solector of the hi-fi button
  42. * @const
  43. * @type {string}
  44. */
  45. var CSS_CHANGE_AUDIO_URL_HIGH = '#footer-hifi';
  46. /**
  47. * The CSS solector of the lo-fi button
  48. * @const
  49. * @type {string}
  50. */
  51. var CSS_CHANGE_AUDIO_URL_LOW = '#footer-lofi';
  52. /**
  53. * The CSS solector of the external button
  54. * @const
  55. * @type {string}
  56. */
  57. var CSS_CHANGE_AUDIO_URL_EXT = '#footer-ext';
  58. /**
  59. * The base URL to be used
  60. * @const
  61. * @type {string}
  62. */
  63. var BASE_URL = 'http://radio.freshair.org.uk/';
  64. /**
  65. * The URL the high quaility audio stream
  66. * 'http://live.freshair.org.uk:3066/;'
  67. * or
  68. * 'http://radio.home.thebiggerguy.com:8080/freshair-high'
  69. * @const
  70. * @type {string}
  71. */
  72. var AUDIO_URL_HIGH = 'http://stream0.freshair.org.uk:3066/;';
  73. /**
  74. * The URL the hight quaility audio stream
  75. * 'http://live.freshair.org.uk:3088/;'
  76. * or
  77. * 'http://radio.home.thebiggerguy.com:8080/freshair-high'
  78. * @const
  79. * @type {string}
  80. */
  81. var AUDIO_URL_LOW = 'http://stream0.freshair.org.uk:3088/;';
  82. /**
  83. * The URL the high quaility audio stream playlist
  84. * @const
  85. * @type {string}
  86. */
  87. var AUDIO_URL_HIGH_EXT = BASE_URL + 'live.m3u';
  88. /**
  89. * Max number of chars for now playing song
  90. * @const
  91. * @type {number}
  92. */
  93. var MAX_NOW_PLAYING = 30;
  94. /**
  95. * Array of images to preload
  96. * @const
  97. */
  98. var IMAGES = [
  99. BASE_URL + 'playbutton.png',
  100. BASE_URL + 'pausebutton.png',
  101. BASE_URL + 'throbber.gif'
  102. ];
  103. /**
  104. * URL to Jplayer.swf. not including the filename
  105. * @const
  106. */
  107. var JPLAYER_SWF_URL = BASE_URL;
  108. /**
  109. * Are we in debug mode (prints to the console)
  110. * @define {boolean} Enable Debug?
  111. */
  112. var DEBUG = true;
  113. /** @const */ var TIMEOUT_WEBCAM = 7 * 1000;
  114. /** @const */ var TIMEOUT_INFO = 17 * 1000; // stager the GETs
  115. /** @const */ var TIMEOUT_INFO_INIT = 100;
  116. // stop errors for browsers that have no debug console
  117. if (DEBUG) {
  118. if (!window.console) {
  119. console = {};
  120. }
  121. /** Debug at level 'info' */
  122. console.info = console.info || function() {};
  123. /** Debug at level 'log' */
  124. console.log = console.log || function() {};
  125. /** Debug at level 'warn' */
  126. console.warn = console.warn || function() {};
  127. /** Debug at level 'error' */
  128. console.error = console.error || function() {};
  129. }
  130. /**
  131. * @const
  132. * @enum {number}
  133. */
  134. var STATES = {
  135. EMPTY: 0,
  136. STOPED: 1,
  137. PAUSED: 2,
  138. PLAYING: 4
  139. };
  140. var state = STATES.EMPTY;
  141. var player = null;
  142. var currentAudioURL = AUDIO_URL_HIGH;
  143. var autoPlay = false; //TODO
  144. var trackCount = 0;
  145. $(function() { // executed when $(document).ready()
  146. if (DEBUG) {
  147. console.info('$(document).ready()');
  148. }
  149. $(CSS_PLAY_PAUSE_IMG).hover(
  150. function()
  151. {
  152. $(this).stop();
  153. $(this).pulse(
  154. {
  155. opacity: [0.5, 1]
  156. },
  157. {
  158. duration: 500,
  159. times: 999999,
  160. easing: 'swing'
  161. });
  162. },
  163. function()
  164. {
  165. $(this).stop();
  166. $(this).pulse(
  167. {
  168. opacity: [1, 0.5]
  169. },
  170. {
  171. duration: 2000,
  172. times: 999999,
  173. easing: 'swing'
  174. });
  175. }
  176. ).trigger('mouseleave');
  177. $('.footer-item').hover(
  178. function()
  179. {
  180. $(this).parent().animate(
  181. {
  182. height: 25,
  183. easing: 'swing'
  184. });
  185. },
  186. function()
  187. {
  188. $(this).parent().animate(
  189. {
  190. height: 20,
  191. easing: 'swing'
  192. });
  193. }
  194. );
  195. $(CSS_PLAY_PAUSE_IMG).bind('click', playPause);
  196. $(CSS_CHANGE_AUDIO_URL_HIGH).bind('click', function()
  197. {
  198. if (currentAudioURL == AUDIO_URL_HIGH && state == STATES.PLAYING) {
  199. return;
  200. }
  201. destroyPlayer();
  202. currentAudioURL = AUDIO_URL_HIGH;
  203. autoPlay = true;
  204. makePlayer();
  205. });
  206. $(CSS_CHANGE_AUDIO_URL_LOW).bind('click', function()
  207. {
  208. if (currentAudioURL == AUDIO_URL_LOW && state == STATES.PLAYING) {
  209. return;
  210. }
  211. destroyPlayer();
  212. currentAudioURL = AUDIO_URL_LOW;
  213. autoPlay = true;
  214. makePlayer();
  215. });
  216. $(CSS_CHANGE_AUDIO_URL_EXT).bind('click', function()
  217. {
  218. destroyPlayer();
  219. window.location = AUDIO_URL_HIGH_EXT;
  220. });
  221. // preload images
  222. for (var i in IMAGES) {
  223. (new Image).src = IMAGES[i];
  224. }
  225. // start audio
  226. makePlayer();
  227. // start webcam feed
  228. setTimeout(updateWebCam1, TIMEOUT_WEBCAM);
  229. setTimeout(updateWebCam2, TIMEOUT_WEBCAM);
  230. setTimeout(updateInfo, TIMEOUT_INFO_INIT);
  231. });
  232. function makePlayer() {
  233. player = $('#radio').jPlayer(
  234. {
  235. ready: function()
  236. {
  237. if (DEBUG) {
  238. console.info('jPlayer: Ready');
  239. }
  240. $(this).jPlayer(
  241. 'setMedia',
  242. {
  243. mp3: currentAudioURL
  244. });
  245. state = STATES.STOPED;
  246. $(CSS_PLAY_PAUSE_IMG)
  247. .attr('src', BASE_URL + 'playbutton.png')
  248. .attr('alt', 'play');
  249. $(CSS_PLAY_PAUSE_DIV).attr('title', 'play');
  250. if (autoPlay) {
  251. playPause();
  252. autoPlay = false;
  253. }
  254. },
  255. swfPath: JPLAYER_SWF_URL,
  256. supplied: 'mp3',
  257. error: function(error)
  258. {
  259. if (DEBUG)
  260. console.info('jPlayer: error');
  261. //$(CSS_PLAY_PAUSE_DIV).html('Error !'); // TODO
  262. $(CSS_PLAY_PAUSE_IMG)
  263. .attr('src', BASE_URL + 'throbber.gif')
  264. .attr('alt', 'error');
  265. $(CSS_PLAY_PAUSE_DIV).attr('title', 'error');
  266. //destroyPlayer();
  267. },
  268. play: function()
  269. {
  270. if (DEBUG)
  271. console.info('jPlayer: play');
  272. state = STATES.PLAYING;
  273. $(CSS_PLAY_PAUSE_IMG)
  274. .attr('src', BASE_URL + 'pausebutton.png')
  275. .attr('alt', 'pause');
  276. $(CSS_PLAY_PAUSE_DIV).attr('title', 'pause');
  277. },
  278. pause: function()
  279. {
  280. if (DEBUG) {
  281. console.info('jPlayer: pause');
  282. }
  283. state = STATES.STOPED;
  284. $(CSS_PLAY_PAUSE_IMG)
  285. .attr('src', BASE_URL + 'playbutton.png')
  286. .attr('alt', 'play');
  287. $(CSS_PLAY_PAUSE_DIV).attr('title', 'play');
  288. },
  289. playing: function()
  290. {
  291. if (DEBUG) {
  292. console.info('jPlayer: pauseplaying');
  293. }
  294. state = STATES.PLAYING;
  295. $(CSS_PLAY_PAUSE_IMG)
  296. .attr('src', BASE_URL + 'pausebutton.png')
  297. .attr('alt', 'pause');
  298. $(CSS_PLAY_PAUSE_DIV).attr('title', 'pause');
  299. },
  300. backgroundColor: '#EA6A11',
  301. errorAlerts: false,
  302. warningAlerts: false,
  303. solution: 'html, flash',
  304. preload: 'none',
  305. cssSelector: {
  306. videoPlay: '',
  307. play: '',
  308. pause: '',
  309. stop: '',
  310. seekBar: '',
  311. playBar: '',
  312. mute: '',
  313. unmute: '',
  314. volumeBar: '',
  315. volumeBarValue: '',
  316. currentTime: '',
  317. duration: ''
  318. }
  319. });
  320. if (DEBUG)
  321. console.info('makePlayer: made player');
  322. }
  323. function destroyPlayer() {
  324. if (player != null) {
  325. /*
  326. try {
  327. player.jPlayer('pause');
  328. } catch (e) {
  329. }
  330. try {
  331. player.jPlayer('setMedia', {mp3: ''}); // try to stop the stream
  332. } catch (e) {
  333. }
  334. */
  335. try {
  336. player.jPlayer('destroy');
  337. } catch (e) {
  338. if (DEBUG)
  339. console.info('destroyPlayer: Unable to destroy player !');
  340. }
  341. }
  342. //$('#radio').html('');
  343. //player = null;
  344. state = STATES.EMPTY;
  345. }
  346. function playPause(eventObject) {
  347. if (player == null) {
  348. makePlayer();
  349. return;
  350. }
  351. switch (state)
  352. {
  353. case STATES.STOPED:
  354. if (DEBUG)
  355. console.info('playPau: play');
  356. player.jPlayer('play');
  357. break;
  358. case STATES.PAUSED:
  359. if (DEBUG)
  360. console.info('playPau: play');
  361. player.jPlayer('play');
  362. break;
  363. case STATES.PLAYING:
  364. if (DEBUG)
  365. console.info('playPau: pause');
  366. player.jPlayer('stop');
  367. destroyPlayer();
  368. break;
  369. default:
  370. if (DEBUG)
  371. console.info('playPause: Unknown !');
  372. destroyPlayer();
  373. makePlayer();
  374. break;
  375. }
  376. }
  377. var lastUid = 1;
  378. function updateInfo() {
  379. if (DEBUG)
  380. console.info('updateInfo:');
  381. // view-source:http://live.freshair.org.uk:3066/7.html
  382. jQuery.ajax(
  383. {
  384. url: BASE_URL + 'info',
  385. dataType: 'json',
  386. success: function(data)
  387. {
  388. if (DEBUG)
  389. console.info('updateInfo: ' + data.status);
  390. if (data.status != 'ok')
  391. return;
  392. var json = data.data;
  393. var now = json.now;
  394. var next = json.next;
  395. // preload images as fast as possible
  396. (new Image).src = now.img;
  397. (new Image).src = next.img;
  398. if (json.track.length > MAX_NOW_PLAYING)
  399. json.track = json.track.substring(0, 11) + '...';
  400. $('#nowplaying-title').html(json.track);
  401. $('#header-subheader-title').html(now.title);
  402. $('#header-subheader-time').html(now.onat.long_);
  403. $('#header-subheader').css('visibility', 'visible');
  404. $('#showinfo-des').html(now.des);
  405. $('#showinfo-img').attr('src', now.img);
  406. $('#showinfo').css('visibility', 'visible');
  407. $('#next-title').html(next.title);
  408. $('#next-time').html(next.onat.short_);
  409. $('#next').css('visibility', 'visible');
  410. },
  411. complete: function()
  412. {
  413. setTimeout(updateInfo, TIMEOUT_INFO);
  414. }
  415. }
  416. );
  417. }
  418. function updateWebCam1() {
  419. updateWebCamx(1);
  420. setTimeout(updateWebCam1, TIMEOUT_WEBCAM);
  421. }
  422. function updateWebCam2() {
  423. updateWebCamx(2);
  424. setTimeout(updateWebCam2, TIMEOUT_WEBCAM);
  425. }
  426. function updateWebCamx(camNum) {
  427. if (DEBUG)
  428. console.info('updateWebCam: ' + camNum);
  429. $('#webcam' + camNum).attr('src', 'http://webcam.freshair.org.uk/' + camNum);
  430. }