/pigeoncms/Modules/PigeonCms.VideoPlayer/views/wmvplayer/wmvplayer.js

http://pigeoncms.googlecode.com/ · JavaScript · 794 lines · 673 code · 96 blank · 25 comment · 133 complexity · 264168f93fbba125e0f397762addd78c MD5 · raw file

  1. /****************************************************************************
  2. * JW WMV Player version 1.1, created with M$ Silverlight 1.0
  3. *
  4. * This file contains all logic for the JW WMV Player. For a functional setup,
  5. * the following two files are also needed:
  6. * - silverlight.js (for instantiating the silverlight plugin)
  7. * - wmvplayer.xaml (or another XAML skin describing the player graphics)
  8. *
  9. * More info: http://www.jeroenwijering.com/?item=JW_WMV_Player
  10. ****************************************************************************/
  11. if(typeof jeroenwijering == "undefined") {
  12. var jeroenwijering = new Object();
  13. jeroenwijering.utils = new Object();
  14. }
  15. /****************************************************************************
  16. * The player wrapper; loads config variables and starts MVC cycle.
  17. ****************************************************************************/
  18. jeroenwijering.Player = function(cnt,src,cfg) {
  19. this.controller;
  20. this.model;
  21. this.view;
  22. this.configuration = {
  23. backgroundcolor:'FFFFFF',
  24. windowless:'false',
  25. file:'',
  26. height:'260',
  27. image:'',
  28. backcolor:'FFFFFF',
  29. frontcolor:'000000',
  30. lightcolor:'000000',
  31. screencolor:'000000',
  32. width:'320',
  33. logo:'',
  34. overstretch:'false',
  35. shownavigation:'true',
  36. showstop:'false',
  37. showdigits:'true',
  38. usefullscreen:'true',
  39. usemute:'false',
  40. autostart:'false',
  41. bufferlength:'3',
  42. duration:'0',
  43. repeat:'false',
  44. sender:'',
  45. start:'0',
  46. volume:'90',
  47. link:'',
  48. linkfromdisplay:'false',
  49. linktarget:'_self'
  50. };
  51. for(itm in this.configuration) {
  52. if(cfg[itm] != undefined) {
  53. if (itm.indexOf('color') > 0) {
  54. this.configuration[itm] = cfg[itm].substr(cfg[itm].length-6);
  55. } else {
  56. this.configuration[itm] = cfg[itm];
  57. }
  58. }
  59. }
  60. Silverlight.createObjectEx({
  61. source:src,
  62. parentElement:cnt,
  63. properties:{
  64. width:this.configuration['width'],
  65. height:this.configuration['height'],
  66. version:'1.0',
  67. inplaceInstallPrompt:true,
  68. isWindowless:this.configuration['windowless'],
  69. background:'#'+this.configuration['backgroundcolor']
  70. },
  71. events:{
  72. onLoad:this.onLoadHandler,
  73. onError:null
  74. },
  75. context:this
  76. });
  77. }
  78. jeroenwijering.Player.prototype = {
  79. addListener: function(typ,fcn) {
  80. this.view.listeners.push({type:typ,func:fcn});
  81. },
  82. getConfig: function() {
  83. return this.configuration;
  84. },
  85. onLoadHandler: function(pid,tgt,sdr) {
  86. tgt.configuration['sender'] = sdr;
  87. tgt.controller = new jeroenwijering.Controller(tgt.configuration);
  88. tgt.view = new jeroenwijering.View(tgt.configuration,tgt.controller);
  89. tgt.model = new jeroenwijering.Model(tgt.configuration,tgt.controller,tgt.view);
  90. tgt.controller.startMVC(tgt.view,tgt.model);
  91. },
  92. sendEvent: function(typ,prm) {
  93. switch(typ.toUpperCase()) {
  94. case 'LINK':
  95. this.controller.setLink();
  96. break;
  97. case 'LOAD':
  98. this.controller.setLoad(prm);
  99. break;
  100. case 'MUTE':
  101. this.controller.setMute();
  102. break;
  103. case 'PLAY':
  104. this.controller.setPlay();
  105. break;
  106. case 'SCRUB':
  107. this.controller.setScrub(prm);
  108. break;
  109. case 'STOP':
  110. this.controller.setStop();
  111. break;
  112. case 'VOLUME':
  113. this.controller.setVolume(prm);
  114. break;
  115. }
  116. }
  117. }
  118. /****************************************************************************
  119. * The controller of the player MVC triad, which processes all user input.
  120. ****************************************************************************/
  121. jeroenwijering.Controller = function(cfg) {
  122. this.configuration = cfg;
  123. }
  124. jeroenwijering.Controller.prototype = {
  125. startMVC: function(vie,mdl) {
  126. this.view = vie;
  127. this.model = mdl;
  128. if(this.configuration['usemute'] == 'true') {
  129. this.view.onVolume(0);
  130. this.view.onMute(true);
  131. this.model.goVolume(0);
  132. } else {
  133. this.view.onVolume(this.configuration['volume']);
  134. this.model.goVolume(this.configuration['volume']);
  135. }
  136. if(this.configuration['autostart'] == 'true') {
  137. this.model.goStart();
  138. } else {
  139. this.model.goPause();
  140. }
  141. },
  142. setState: function(old,stt) {
  143. this.state = stt;
  144. var pos = this.configuration['start'];
  145. if(old == 'Closed' && pos > 0) {
  146. setTimeout(jeroenwijering.utils.delegate(this,this.setScrub),200,pos);
  147. }
  148. },
  149. setLink: function() {
  150. if (this.configuration['linktarget'].indexOf('javascript:') == 0) {
  151. return Function(this.configuration['linktarget']).apply();
  152. } else if (this.configuration['linktarget'] == '_blank') {
  153. window.open(this.configuration['link']);
  154. } else if (this.configuration['linktarget'] != '') {
  155. window.location = this.configuration['link'];
  156. }
  157. },
  158. setLoad: function(fil) {
  159. if(this.model.state != "Closed") {
  160. this.model.goStop();
  161. }
  162. this.configuration['file'] = fil;
  163. if(this.configuration['autostart'] == 'true') {
  164. setTimeout(jeroenwijering.utils.delegate(this.model,this.model.goStart),100);
  165. }
  166. },
  167. setMute: function() {
  168. if(this.configuration['usemute'] == 'true') {
  169. this.configuration['usemute'] = 'false';
  170. this.model.goVolume(this.configuration['volume']);
  171. this.view.onMute(false);
  172. } else {
  173. this.configuration['usemute'] = 'true';
  174. this.model.goVolume(0);
  175. this.view.onMute(true);
  176. }
  177. },
  178. setPlay: function() {
  179. if(this.state == 'Buffering' || this.state == 'Playing') {
  180. if(this.configuration['duration'] == 0) {
  181. this.model.goStop();
  182. } else {
  183. this.model.goPause();
  184. }
  185. } else {
  186. this.model.goStart();
  187. }
  188. },
  189. setScrub: function(sec) {
  190. if(sec < 2) {
  191. sec = 0;
  192. } else if (sec > this.configuration['duration']-4) {
  193. sec = this.configuration['duration']-4;
  194. }
  195. if(this.state == 'Buffering' || this.state == 'Playing') {
  196. this.model.goStart(sec);
  197. } else {
  198. this.model.goPause(sec);
  199. }
  200. },
  201. setStop: function() {
  202. this.model.goStop();
  203. },
  204. setVolume: function(pct) {
  205. if(pct < 0) { pct = 0; } else if(pct > 100) { pct = 100; }
  206. this.configuration['volume'] = Math.round(pct);
  207. this.model.goVolume(pct);
  208. this.view.onVolume(pct);
  209. if(this.configuration['usemute'] == 'true') {
  210. this.configuration['usemute'] = 'false';
  211. this.view.onMute(false);
  212. }
  213. },
  214. setFullscreen: function() {
  215. var fss = !this.configuration['sender'].getHost().content.FullScreen;
  216. this.configuration['sender'].getHost().content.FullScreen = fss;
  217. jeroenwijering.utils.delegate(this.view,this.view.onFullscreen);
  218. }
  219. }
  220. /****************************************************************************
  221. * The view of the player MVC triad, which manages the graphics.
  222. ****************************************************************************/
  223. jeroenwijering.View = function(cfg,ctr) {
  224. this.configuration = cfg;
  225. this.listeners = Array();
  226. this.controller = ctr;
  227. this.fstimeout;
  228. this.fslistener;
  229. this.display = this.configuration['sender'].findName("PlayerDisplay");
  230. this.controlbar = this.configuration['sender'].findName("PlayerControls");
  231. this.configuration['sender'].getHost().content.onResize =
  232. jeroenwijering.utils.delegate(this,this.resizePlayer);
  233. this.configuration['sender'].getHost().content.onFullScreenChange =
  234. jeroenwijering.utils.delegate(this,this.onFullscreen);
  235. this.assignColorsClicks();
  236. this.resizePlayer();
  237. }
  238. jeroenwijering.View.prototype = {
  239. onBuffer: function(pct) {
  240. var snd = this.configuration['sender'];
  241. if(pct == 0) {
  242. snd.findName("BufferText").Text = null;
  243. } else {
  244. pct < 10 ? pct = "0"+pct: pct = ""+pct;
  245. snd.findName("BufferText").Text = pct;
  246. }
  247. this.delegate('BUFFER',[pct]);
  248. },
  249. onFullscreen: function(fss) {
  250. var snd = this.configuration['sender'];
  251. var fst = snd.getHost().content.FullScreen;
  252. if(fst) {
  253. this.fstimeout = setTimeout(jeroenwijering.utils.delegate(this,
  254. this.hideFSControls),2000);
  255. this.fslistener = this.display.addEventListener('MouseMove',
  256. jeroenwijering.utils.delegate(this,this.showFSControls));
  257. snd.findName("FullscreenSymbol").Visibility = "Collapsed";
  258. snd.findName("FullscreenOffSymbol").Visibility = "Visible";
  259. } else {
  260. clearTimeout(this.fstimeout);
  261. this.display.removeEventListener("MouseMove",this.fslistener);
  262. this.controlbar.Visibility = "Visible";
  263. this.display.Cursor = "Hand";
  264. snd.findName("FullscreenSymbol").Visibility = "Visible";
  265. snd.findName("FullscreenOffSymbol").Visibility = "Collapsed";
  266. }
  267. this.resizePlayer();
  268. this.delegate('FULLSCREEN');
  269. },
  270. showFSControls: function(sdr,arg) {
  271. var vbt = sdr.findName('PlayerControls');
  272. var yps = arg.GetPosition(vbt).Y;
  273. clearTimeout(this.fstimeout);
  274. this.controlbar.Visibility = "Visible";
  275. this.display.Cursor = "Hand";
  276. if(yps < 0) {
  277. this.fstimeout = setTimeout(jeroenwijering.utils.delegate(this,
  278. this.hideFSControls),2000);
  279. }
  280. },
  281. hideFSControls: function() {
  282. this.controlbar.Visibility = "Collapsed";
  283. this.display.Cursor = "None";
  284. },
  285. onLoad: function(pct) {
  286. var snd = this.configuration['sender'];
  287. var max = snd.findName("TimeSlider").Width;
  288. snd.findName("DownloadProgress").Width = Math.round(max*pct/100);
  289. this.delegate('LOAD',[pct]);
  290. },
  291. onMute: function(mut) {
  292. var snd = this.configuration['sender'];
  293. this.configuration['usemute'] = ''+mut;
  294. if(mut) {
  295. snd.findName("VolumeHighlight").Visibility = "Collapsed";
  296. snd.findName("MuteSymbol").Visibility = "Visible";
  297. snd.findName("MuteOffSymbol").Visibility = "Collapsed";
  298. if(this.state == 'Playing') {
  299. snd.findName("MuteIcon").Visibility = "Visible";
  300. }
  301. } else {
  302. snd.findName("VolumeHighlight").Visibility = "Visible";
  303. snd.findName("MuteSymbol").Visibility = "Collapsed";
  304. snd.findName("MuteOffSymbol").Visibility = "Visible";
  305. snd.findName("MuteIcon").Visibility = "Collapsed";
  306. }
  307. this.delegate('MUTE');
  308. },
  309. onState: function(old,stt) {
  310. var snd = this.configuration['sender'];
  311. this.state = stt;
  312. if(stt == 'Buffering' || stt == 'Playing' || stt == 'Opening') {
  313. snd.findName("PlayIcon").Visibility = "Collapsed";
  314. snd.findName("PlaySymbol").Visibility = "Collapsed";
  315. snd.findName("PlayOffSymbol").Visibility = "Visible";
  316. if (stt=='Playing') {
  317. snd.findName("BufferIcon").Visibility = "Collapsed";
  318. snd.findName("BufferText").Visibility = "Collapsed";
  319. if(this.configuration['usemute'] == 'true') {
  320. snd.findName("MuteIcon").Visibility = "Visible";
  321. }
  322. } else{
  323. snd.findName("BufferIcon").Visibility = "Visible";
  324. snd.findName("BufferText").Visibility = "Visible";
  325. }
  326. } else {
  327. snd.findName("MuteIcon").Visibility = "Collapsed";
  328. snd.findName("BufferIcon").Visibility = "Collapsed";
  329. snd.findName("BufferText").Visibility = "Collapsed";
  330. snd.findName("PlayOffSymbol").Visibility = "Collapsed";
  331. snd.findName("PlaySymbol").Visibility = "Visible";
  332. if(this.configuration['linkfromdisplay'] == 'true') {
  333. snd.findName("PlayIcon").Visibility = "Collapsed";
  334. } else {
  335. snd.findName("PlayIcon").Visibility = "Visible";
  336. }
  337. }
  338. try {
  339. if(!(old == 'Completed' && stt == 'Buffering') &&
  340. !(old == 'Buffering' && stt == 'Paused')) {
  341. playerStatusChange(old.toUpperCase(),stt.toUpperCase());
  342. }
  343. } catch (err) {}
  344. this.delegate('STATE',[old,stt]);
  345. },
  346. onTime: function(elp,dur) {
  347. var snd = this.configuration['sender'];
  348. var snd = this.configuration['sender'];
  349. var max = snd.findName("TimeSlider").Width;
  350. if(dur > 0) {
  351. var pos = Math.round(max*elp/dur);
  352. this.configuration['duration'] = dur;
  353. snd.findName("ElapsedText").Text = jeroenwijering.utils.timestring(elp);
  354. snd.findName("RemainingText").Text = jeroenwijering.utils.timestring(dur-elp);
  355. snd.findName("TimeSymbol").Visibility = "Visible";
  356. snd.findName("TimeSymbol")['Canvas.Left'] = pos+4;
  357. snd.findName("TimeHighlight").Width = pos-2;
  358. } else {
  359. snd.findName("TimeSymbol").Visibility = "Collapsed";
  360. }
  361. this.delegate('TIME',[elp,dur]);
  362. },
  363. onVolume: function(pct) {
  364. var snd = this.configuration['sender'];
  365. snd.findName("VolumeHighlight").Width = Math.round(pct/5);
  366. this.delegate('VOLUME',[pct]);
  367. },
  368. assignColorsClicks: function() {
  369. this.display.Cursor = "Hand";
  370. this.display.Background = "#FF"+this.configuration['screencolor'];
  371. if(this.configuration['linkfromdisplay'] == 'false') {
  372. this.display.addEventListener('MouseLeftButtonUp',
  373. jeroenwijering.utils.delegate(this.controller,
  374. this.controller.setPlay));
  375. } else {
  376. this.display.addEventListener('MouseLeftButtonUp',
  377. jeroenwijering.utils.delegate(this.controller,
  378. this.controller.setLink));
  379. this.display.findName("PlayIcon").Visibility = "Collapsed";
  380. }
  381. if(this.configuration['logo'] != '') {
  382. this.display.findName('OverlayCanvas').Visibility = "Visible";
  383. this.display.findName('OverlayLogo').ImageSource =
  384. this.configuration['logo'];
  385. }
  386. this.controlbar.findName("ControlbarBack").Fill =
  387. "#FF"+this.configuration['backcolor'];
  388. this.assignButton('Play',this.controller.setPlay);
  389. this.assignButton('Stop',this.controller.setStop);
  390. this.configuration['sender'].findName('ElapsedText').Foreground =
  391. "#FF"+this.configuration['frontcolor'];
  392. this.assignSlider('Time',this.changeTime);
  393. this.configuration['sender'].findName('DownloadProgress').Fill =
  394. "#FF"+this.configuration['frontcolor'];
  395. this.configuration['sender'].findName('RemainingText').Foreground =
  396. "#FF"+this.configuration['frontcolor'];
  397. this.assignButton('Link',this.controller.setLink);
  398. this.assignButton('Fullscreen',this.controller.setFullscreen);
  399. this.assignButton('Mute',this.controller.setMute);
  400. this.assignSlider('Volume',this.changeVolume);
  401. },
  402. assignButton: function(btn,act) {
  403. var el1 = this.configuration['sender'].findName(btn+'Button');
  404. el1.Cursor = "Hand";
  405. el1.addEventListener('MouseLeftButtonUp',
  406. jeroenwijering.utils.delegate(this.controller,act));
  407. el1.addEventListener('MouseEnter',
  408. jeroenwijering.utils.delegate(this,this.rollOver));
  409. el1.addEventListener('MouseLeave',
  410. jeroenwijering.utils.delegate(this,this.rollOut));
  411. this.configuration['sender'].findName(btn+'Symbol').Fill =
  412. "#FF"+this.configuration['frontcolor'];
  413. try {
  414. this.configuration['sender'].findName(btn+'OffSymbol').Fill =
  415. "#FF"+this.configuration['frontcolor'];
  416. } catch(e) {}
  417. },
  418. assignSlider: function(sld,act) {
  419. var el1 = this.configuration['sender'].findName(sld+'Button');
  420. el1.Cursor = "Hand";
  421. el1.addEventListener('MouseLeftButtonUp',
  422. jeroenwijering.utils.delegate(this,act));
  423. el1.addEventListener('MouseEnter',
  424. jeroenwijering.utils.delegate(this,this.rollOver));
  425. el1.addEventListener('MouseLeave',
  426. jeroenwijering.utils.delegate(this,this.rollOut));
  427. this.configuration['sender'].findName(sld+'Slider').Fill =
  428. "#FF"+this.configuration['frontcolor'];
  429. this.configuration['sender'].findName(sld+'Highlight').Fill =
  430. "#FF"+this.configuration['frontcolor'];
  431. this.configuration['sender'].findName(sld+'Symbol').Fill =
  432. "#FF"+this.configuration['frontcolor'];
  433. },
  434. delegate: function(typ,arg) {
  435. for(var i=0; i<this.listeners.length; i++) {
  436. if(this.listeners[i]['type'].toUpperCase() == typ) {
  437. this.listeners[i]['func'].apply(null,arg);
  438. }
  439. }
  440. },
  441. rollOver: function(sdr) {
  442. var str = sdr.Name.substr(0,sdr.Name.length-6);
  443. this.configuration['sender'].findName(str+'Symbol').Fill =
  444. "#FF"+this.configuration['lightcolor'];
  445. try {
  446. this.configuration['sender'].findName(str+'OffSymbol').Fill =
  447. "#FF"+this.configuration['lightcolor'];
  448. } catch(e) {}
  449. },
  450. rollOut: function(sdr) {
  451. var str = sdr.Name.substr(0,sdr.Name.length-6);
  452. this.configuration['sender'].findName(str+'Symbol').Fill =
  453. "#FF"+this.configuration['frontcolor'];
  454. try {
  455. this.configuration['sender'].findName(str+'OffSymbol').Fill =
  456. "#FF"+this.configuration['frontcolor'];
  457. } catch(e) {}
  458. },
  459. changeTime: function(sdr,arg) {
  460. var tbt = sdr.findName('TimeSlider');
  461. var xps = arg.GetPosition(tbt).X;
  462. var sec = Math.floor(xps/tbt.Width*this.configuration['duration']);
  463. this.controller.setScrub(sec);
  464. },
  465. changeVolume: function(sdr,arg) {
  466. var vbt = sdr.findName('VolumeButton');
  467. var xps = arg.GetPosition(vbt).X;
  468. this.controller.setVolume(xps*5);
  469. },
  470. resizePlayer: function() {
  471. var wid = this.configuration['sender'].getHost().content.actualWidth;
  472. var hei = this.configuration['sender'].getHost().content.actualHeight;
  473. var fss = this.configuration['sender'].getHost().content.FullScreen;
  474. if(this.configuration['shownavigation'] == 'true') {
  475. if(fss == true) {
  476. this.resizeDisplay(wid,hei);
  477. this.controlbar['Canvas.Left'] = Math.round(wid/2-250);
  478. this.resizeControlbar(500,hei-this.controlbar.Height-16);
  479. this.controlbar.findName('ControlbarBack')['Opacity'] = 0.5;
  480. } else {
  481. this.resizeDisplay(wid,hei-20);
  482. this.controlbar['Canvas.Left'] = 0;
  483. this.resizeControlbar(wid,hei-this.controlbar.Height);
  484. this.controlbar.findName('ControlbarBack')['Opacity'] = 1;
  485. }
  486. } else {
  487. this.resizeDisplay(wid,hei);
  488. }
  489. },
  490. resizeDisplay: function(wid,hei) {
  491. this.stretchElement('PlayerDisplay',wid,hei);
  492. this.stretchElement('VideoWindow',wid,hei);
  493. this.stretchElement('PlaceholderImage',wid,hei);
  494. this.centerElement('PlayIcon',wid,hei);
  495. this.centerElement('MuteIcon',wid,hei);
  496. this.centerElement('BufferIcon',wid,hei);
  497. this.centerElement('BufferText',wid,hei);
  498. this.display.findName('OverlayCanvas')['Canvas.Left'] = wid -
  499. this.display.findName('OverlayCanvas').Width - 10;
  500. this.display.Visibility = "Visible";
  501. },
  502. resizeControlbar: function(wid,yps,alp) {
  503. this.controlbar['Canvas.Top'] = yps;
  504. this.stretchElement('PlayerControls',wid);
  505. this.stretchElement('ControlbarBack',wid);
  506. this.placeElement('PlayButton',0);
  507. var lft = 17;
  508. this.placeElement('VolumeButton',wid-24);
  509. this.placeElement('MuteButton',wid-37);
  510. var rgt = 37;
  511. if(this.configuration['showstop'] == 'true') {
  512. this.placeElement('StopButton',lft);
  513. lft += 17;
  514. } else {
  515. this.controlbar.findName('StopButton').Visibility="Collapsed";
  516. }
  517. if(this.configuration['usefullscreen'] == 'true') {
  518. rgt += 18;
  519. this.placeElement('FullscreenButton',wid-rgt);
  520. } else {
  521. this.controlbar.findName('FullscreenButton').Visibility =
  522. "Collapsed";
  523. }
  524. if(this.configuration['link'] != '') {
  525. rgt += 18;
  526. this.placeElement('LinkButton',wid-rgt);
  527. } else {
  528. this.controlbar.findName('LinkButton').Visibility="Collapsed";
  529. }
  530. if(this.configuration['showdigits'] == 'true' && wid-rgt-lft> 160) {
  531. rgt += 35;
  532. this.controlbar.findName('RemainingButton').Visibility="Visible";
  533. this.controlbar.findName('ElapsedButton').Visibility="Visible";
  534. this.placeElement('RemainingButton',wid-rgt);
  535. this.placeElement('ElapsedButton',lft);
  536. lft +=35;
  537. } else {
  538. this.controlbar.findName('RemainingButton').Visibility =
  539. "Collapsed";
  540. this.controlbar.findName('ElapsedButton').Visibility="Collapsed";
  541. }
  542. this.placeElement('TimeButton',lft);
  543. this.stretchElement('TimeButton',wid-lft-rgt);
  544. this.stretchElement('TimeShadow',wid-lft-rgt);
  545. this.stretchElement('TimeStroke',wid-lft-rgt);
  546. this.stretchElement('TimeFill',wid-lft-rgt);
  547. this.stretchElement('TimeSlider',wid-lft-rgt-10);
  548. this.stretchElement('DownloadProgress',wid-lft-rgt-10);
  549. var tsb = this.configuration['sender'].findName('TimeSymbol');
  550. this.stretchElement('TimeHighlight',tsb['Canvas.Left']-5);
  551. this.controlbar.Visibility = "Visible";
  552. },
  553. centerElement: function(nam,wid,hei) {
  554. var elm = this.configuration['sender'].findName(nam);
  555. elm['Canvas.Left'] = Math.round(wid/2 - elm.Width/2);
  556. elm['Canvas.Top'] = Math.round(hei/2 - elm.Height/2);
  557. },
  558. stretchElement: function(nam,wid,hei) {
  559. var elm = this.configuration['sender'].findName(nam);
  560. elm.Width = wid;
  561. if (hei != undefined) { elm.Height = hei; }
  562. },
  563. placeElement: function(nam,xps,yps) {
  564. var elm = this.configuration['sender'].findName(nam);
  565. elm['Canvas.Left'] = xps;
  566. if(yps) { elm['Canvas.Top'] = yps; }
  567. }
  568. }
  569. /****************************************************************************
  570. * The model of the player MVC triad, which stores all playback logic.
  571. ****************************************************************************/
  572. jeroenwijering.Model = function(cfg,ctr,vie) {
  573. this.configuration = cfg;
  574. this.controller = ctr;
  575. this.view = vie;
  576. this.video = this.configuration['sender'].findName("VideoWindow");
  577. this.preview = this.configuration['sender'].findName("PlaceholderImage");
  578. var str = {
  579. 'true':'UniformToFill',
  580. 'false':'Uniform',
  581. 'fit':'Fill',
  582. 'none':'None'
  583. }
  584. this.state = this.video.CurrentState;
  585. this.timeint;
  586. this.video.Stretch = str[this.configuration['overstretch']];
  587. this.preview.Stretch = str[this.configuration['overstretch']];
  588. this.video.BufferingTime =
  589. jeroenwijering.utils.spanstring(this.configuration['bufferlength']);
  590. this.video.AutoPlay = true;
  591. this.video.AddEventListener("CurrentStateChanged",
  592. jeroenwijering.utils.delegate(this,this.stateChanged));
  593. this.video.AddEventListener("MediaEnded",
  594. jeroenwijering.utils.delegate(this,this.mediaEnded));
  595. this.video.AddEventListener("BufferingProgressChanged",
  596. jeroenwijering.utils.delegate(this,this.bufferChanged));
  597. this.video.AddEventListener("DownloadProgressChanged",
  598. jeroenwijering.utils.delegate(this,this.downloadChanged));
  599. if(this.configuration['image'] != '') {
  600. this.preview.Source = this.configuration['image'];
  601. }
  602. }
  603. jeroenwijering.Model.prototype = {
  604. goPause: function(sec) {
  605. this.video.pause();
  606. if(!isNaN(sec)) {
  607. this.video.Position = jeroenwijering.utils.spanstring(sec);
  608. }
  609. this.timeChanged();
  610. },
  611. goStart: function(sec) {
  612. this.video.Visibility = 'Visible';
  613. this.preview.Visibility = 'Collapsed';
  614. if(this.state == "Closed") {
  615. this.video.Source = this.configuration['file'];
  616. } else {
  617. this.video.play();
  618. }
  619. if(!isNaN(sec)) {
  620. this.video.Position = jeroenwijering.utils.spanstring(sec);
  621. }
  622. },
  623. goStop: function() {
  624. this.video.Visibility = 'Collapsed';
  625. this.preview.Visibility = 'Visible';
  626. this.goPause(0);
  627. this.video.Source = 'null';
  628. this.view.onBuffer(0);
  629. clearInterval(this.timeint);
  630. },
  631. goVolume: function(pct) {
  632. this.video.Volume = pct/100;
  633. },
  634. stateChanged: function() {
  635. var stt = this.video.CurrentState;
  636. if(stt != this.state) {
  637. this.controller.setState(this.state,stt);
  638. this.view.onState(this.state,stt);
  639. this.state = stt;
  640. this.configuration['duration'] =
  641. Math.round(this.video.NaturalDuration.Seconds*10)/10;
  642. if(stt != "Playing" && stt != "Buffering" && stt != "Opening") {
  643. clearInterval(this.timeint);
  644. } else {
  645. this.timeint = setInterval(jeroenwijering.utils.delegate(
  646. this,this.timeChanged),100);
  647. }
  648. }
  649. },
  650. mediaEnded: function() {
  651. if(this.configuration['repeat'] == 'true') {
  652. this.goStart(0);
  653. } else {
  654. this.state = 'Completed';
  655. this.view.onState(this.state,'Completed');
  656. this.video.Visibility = 'Collapsed';
  657. this.preview.Visibility = 'Visible';
  658. this.goPause(0);
  659. }
  660. },
  661. bufferChanged: function() {
  662. var bfr = Math.round(this.video.BufferingProgress*100);
  663. this.view.onBuffer(bfr);
  664. },
  665. downloadChanged: function() {
  666. var dld = Math.round(this.video.DownloadProgress*100);
  667. this.view.onLoad(dld);
  668. },
  669. timeChanged: function() {
  670. var pos = Math.round(this.video.Position.Seconds*10)/10;
  671. this.view.onTime(pos,this.configuration['duration']);
  672. }
  673. }
  674. /****************************************************************************
  675. * Some utility functions.
  676. ****************************************************************************/
  677. jeroenwijering.utils.delegate = function(obj,fcn) {
  678. return function() {
  679. return fcn.apply(obj,arguments);
  680. }
  681. }
  682. jeroenwijering.utils.timestring = function(stp) {
  683. var hrs = Math.floor(stp/3600);
  684. var min = Math.floor(stp%3600/60);
  685. var sec = Math.round(stp%60);
  686. var str = "";
  687. sec > 9 ? str += sec: str +='0'+sec;
  688. min > 9 ? str = min+":"+str: str='0'+min+":"+str;
  689. hrs > 0 ? str = hrs+":"+str: null;
  690. return str;
  691. }
  692. jeroenwijering.utils.spanstring = function(stp) {
  693. var hrs = Math.floor(stp/3600);
  694. var min = Math.floor(stp%3600/60);
  695. var sec = Math.round(stp%60*10)/10;
  696. var str = hrs+':'+min+':'+sec;
  697. return str;
  698. }