embedded.html 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. <!DOCTYPE html>
  2. <meta name="apple-mobile-web-app-capable" content="yes" />
  3. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
  4. <html>
  5. <head>
  6. <meta charset="UTF-8">
  7. <meta name="theme-color" content="#232324">
  8. <link rel="stylesheet" href="../script/semantic/semantic.min.css">
  9. <link rel="icon" type="image/png" href="./img/small_icon.png">
  10. <script src="../script/jquery.min.js"></script>
  11. <script src="../script/semantic/semantic.min.js"></script>
  12. <script src="../script/ao_module.js"></script>
  13. <style>
  14. body{
  15. padding:0px !important;
  16. overflow: hidden;
  17. height:100%;
  18. background-color: transparent !important;
  19. }
  20. .coloredBackground{
  21. background: rgb(253,255,254);
  22. background: linear-gradient(321deg, rgba(253,255,254,1) 29%, rgba(240,250,255,1) 100%);
  23. }
  24. html, body { height: 100%; width: 100%; margin: 0; }
  25. .playerInterface{
  26. background-color:rgba(226, 221, 220,0.95);
  27. height:150px !important;
  28. width:100%;
  29. }
  30. #playerUI{
  31. margin-left:0px !important;
  32. margin-right:0px !important;
  33. width:100% !important;
  34. position: relative;
  35. color: #404147;
  36. background-color: #f9f9f9 !important;
  37. overflow: hidden;
  38. }
  39. .parkLeft{
  40. position:absolute !important;
  41. top:70px;
  42. left:5px;
  43. margin-left:-30px;
  44. }
  45. .rotateNinetyDegree{
  46. -webkit-transform: rotate(-90deg);
  47. -moz-transform: rotate(-90deg);
  48. -o-transform: rotate(-90deg);
  49. -ms-transform: rotate(-90deg);
  50. transform: rotate(-90deg);
  51. }
  52. .roundbtn{
  53. border-radius: 40px !important;
  54. box-shadow: 2px 2px 2px 2px #bfbfbf;
  55. }
  56. .playBtn{
  57. color: white !important;
  58. transition: opacity 0.1s;
  59. }
  60. #playpauseBtn{
  61. width: 66px;
  62. height: 66px;
  63. }
  64. .playerControlWrapper .sidebuttons{
  65. background-color: white !important;
  66. }
  67. .playerControlWrapper .white.icon.button:hover{
  68. opacity: 0.6;
  69. }
  70. .playerControlWrapper{
  71. text-align: center;
  72. position:absolute;
  73. margin-top: 3rem;
  74. width:100% !important;
  75. }
  76. .rightPaddedOprButtons{
  77. position:absolute;
  78. right:3px;
  79. top:3px;
  80. }
  81. .modeEnabled{
  82. background-color: #186ed2 !important;
  83. color:white !important;
  84. border: 0px solid transparent !important;
  85. }
  86. #volControlOverlay{
  87. background-color: rgba(255,255,255,0.01);
  88. z-index:999;
  89. position:absolute;
  90. width:14px;
  91. height:120px;
  92. top:17px;
  93. left:28px;
  94. }
  95. .songlabel{
  96. padding-right:3px;
  97. position:absolute;
  98. display:inline-box;
  99. left:5px;
  100. top:5px;
  101. color:#77767b;
  102. height:22px;
  103. text-overflow: ellipsis;
  104. overflow: hidden;
  105. width: 100%;
  106. white-space: nowrap;
  107. font-weight: bold;
  108. }
  109. .durationDisplay{
  110. position:absolute;
  111. right:0px;
  112. bottom:0px;
  113. padding-right:5px;
  114. padding-bottom:5px;
  115. margin: 0px !important;
  116. color: #77767b;
  117. }
  118. .bottomBackground{
  119. background-color: white;
  120. position:relative;
  121. height:58px;
  122. width:100%;
  123. }
  124. .sameDirFileList{
  125. width:100%;
  126. height:calc(100% - 220px) !important;
  127. background-color:rgba(243, 243, 243, 0.95);
  128. overflow-y:auto;
  129. overflow-x:hidden;
  130. }
  131. @supports ((-webkit-backdrop-filter: blur(2em)) or (backdrop-filter: blur(2em))) {
  132. .sameDirFileList {
  133. background-color:rgba(240, 240, 240, 0.5);
  134. -webkit-backdrop-filter: blur(2em);
  135. backdrop-filter: blur(2em);
  136. }
  137. }
  138. .listitem{
  139. border-bottom: 1px solid #404040;
  140. padding: 12px;
  141. color:rgb(43, 43, 43);
  142. font-size:120%;
  143. cursor:pointer;
  144. }
  145. .listitem:hover{
  146. background-color:#eff1f3;
  147. }
  148. .listitem.selected{
  149. background-color:#eff1f3;
  150. }
  151. .noradius{
  152. border-radius: 0px !important;
  153. }
  154. </style>
  155. </head>
  156. <body>
  157. <div id="playerUI" class="playerInterface ui container">
  158. <img id="Albumnart" class="ui fluid image" src="img/nothumb.png" style="position: absolute; top: -75px; opacity: 0.3; pointer-events: none; user-select: none;">
  159. <div class="parkLeft">
  160. <div class="ui primary small progress rotateNinetyDegree" style="width:120px !important; background-color: white;">
  161. <div id="volControl" class="bar" style="min-width: 0%; width: 60%;background-color:#4576c5;"></div>
  162. </div>
  163. </div>
  164. <div id="volControlOverlay"></div>
  165. <div class="playerControlWrapper" align="center">
  166. <button class="ui white huge icon button sidebuttons roundbtn playlistStepBtn" onClick="lastSong();"><i class="step backward icon"></i></button>
  167. <button id="playpauseBtn" style="background-color:#186ed2;" class="ui white massive icon button roundbtn playBtn" onClick="togglePlay(this);"><i class="pause icon"></i></button>
  168. <button class="ui huge white icon button sidebuttons roundbtn playlistStepBtn" onClick="nextSong();"><i class="step forward icon"></i></button>
  169. </div>
  170. <div class="rightPaddedOprButtons">
  171. <button id="repeatModeBtn" class="ui icon button" style="margin-bottom:5px;" onClick="toggleRepeat(this);"><i class="retweet icon"></i></button><br>
  172. <button id="showListBtn" class="ui icon button" onClick="showRelatedFileList();"><i class="content icon"></i></button>
  173. <!-- <button class="ui icon button"><i class="exchange icon"></i></button> -->
  174. </div>
  175. <!-- Adding in some labels for the progress bars and song information-->
  176. <p class="rotateNinetyDegree" style="position:absolute;top:65px;left:8px; font-weight: lighter;"><i class="small minus icon"></i> Volume <i class="small plus icon"></i></p>
  177. <p class="durationDisplay">0:00 / 0:00</p>
  178. </div>
  179. <div id="progressControl" class="ui attached small progress" style="height: 0.8rem; background: rgba(255,255,255,0.8);">
  180. <div id="playbackProgress" class="bar" style="min-width: 0%; width: 0%;background-color: #4576c5; "></div>
  181. </div>
  182. <div class="bottomBackground" >
  183. <!-- Song Title at the bottom black area-->
  184. <div id="songtitle" class="songlabel">Loading Song Information</div>
  185. <div id="fileSize" style="position:absolute;bottom:5px;left:5px;color:#77767b;"><i class="file outline icon"></i> 0.0 MB</div>
  186. <div style="position:absolute;right:3px;bottom:3px;color:#77767b;"><i class='leaf icon'></i>AirMusic</div>
  187. </div>
  188. <!-- The sections below are for mobile interfaces -->
  189. <div id="nearbyFilelist" class="sameDirFileList">
  190. <div class="listitem" onClick="playThis(this);"><div style="width: 100%; text-align: center;"><i class="ui loading spinner icon"></i></div></div>
  191. </div>
  192. <!-- autoplay -->
  193. <audio id="mainPlayer" style="display:none;" preload="auto" autoplay></audio>
  194. <div style="display:none;">
  195. <div id="meta_dirSongList"></div>
  196. <div id="meta_playingSong"></div>
  197. </div>
  198. <script>
  199. //Define global variables
  200. var player = $("#mainPlayer")[0];
  201. var mediaExchanging = false;
  202. var listShown = true;
  203. if (ao_module_virtualDesktop){
  204. listShown = false;
  205. }else{
  206. $("#showListBtn").hide();
  207. }
  208. player.volume = getCurrentGlobVol();
  209. //Init ao_module window events
  210. ao_module_setFixedWindowSize();
  211. //Do things if it is not run under desktop mode
  212. if (!ao_module_virtualDesktop){
  213. $("#nearbyFilelist").addClass("coloredBackground");
  214. }
  215. //Ignore all other input files.
  216. var playingFileInfo = ao_module_loadInputFiles()[0];
  217. //Get the song title and meta data from server
  218. var songInfo = [];
  219. var songList = [];
  220. if (playingFileInfo.filepath != undefined){
  221. player.src = "../media?file=" + encodeURIComponent(playingFileInfo.filepath);
  222. }
  223. if (playingFileInfo.filename != undefined){
  224. ao_module_setWindowTitle(playingFileInfo.filename);
  225. }
  226. ao_module_agirun("Music/functions/getMeta.js", {
  227. file: encodeURIComponent(playingFileInfo.filepath)
  228. }, function(data){
  229. songList = data;
  230. for (var i = 0; i < data.length; i++){
  231. if (data[i][0] == playingFileInfo.filename){
  232. songInfo = data[i];
  233. //Set the audio element src
  234. //player.src = "../media?file=" + encodeURIComponent(data[i][1]);
  235. //Update window title
  236. //ao_module_setWindowTitle(data[i][0]);
  237. updatePlayerThemeAndBackground(data[i][1]);
  238. }
  239. }
  240. if (data.length == 0){
  241. //Error occured
  242. player.src = "../media?file=" + encodeURIComponent(playingFileInfo.filepath);
  243. }
  244. //Load song title into the display area
  245. updateDisplayInformation(songInfo[0],songInfo[3]);
  246. //Create the playlist for all the files in the same directory
  247. createPlayList();
  248. //Initiate the current playSong in the songList
  249. updatePlayingSongSelection();
  250. });
  251. /*
  252. $.get("../Music/getMeta?file=" + encodeURIComponent(playingFileInfo.filepath),function(data){
  253. //console.log(data);
  254. songList = data;
  255. for (var i = 0; i < data.length; i++){
  256. if (data[i][0] == playingFileInfo.filename){
  257. songInfo = data[i];
  258. //Set the audio element src
  259. player.src = "../media?file=" + encodeURIComponent(data[i][1]);
  260. //Update window title
  261. ao_module_setWindowTitle(data[i][0]);
  262. }
  263. }
  264. //Load song title into the display area
  265. updateDisplayInformation(songInfo[0],songInfo[3]);
  266. //Create the playlist for all the files in the same directory
  267. createPlayList();
  268. //Initiate the current playSong in the songList
  269. updatePlayingSongSelection();
  270. });
  271. */
  272. //Get the song title from meta data
  273. //var songInfo = JSON.parse($("#meta_playingSong").text().trim());
  274. //var songList = JSON.parse($("#meta_dirSongList").text().trim());
  275. //ao_module_setWindowTitle(ao_module_codec.decodeUmFilename(songInfo[0]));
  276. //Define supporting function for trunc.
  277. String.prototype.trunc = String.prototype.trunc ||
  278. function(n){
  279. return (this.length > n) ? this.substr(0, n-1) + '&hellip;' : this;
  280. };
  281. //Setup listen events to global volume
  282. setInterval(function(){
  283. var globvol = getCurrentGlobVol();
  284. updateVolControlDisplay(globvol);
  285. player.volume = globvol;
  286. if (player.paused == true){
  287. //Check if anytime that the button UI is not in sync with the current playing status. Update it if found.
  288. $(".playBtn").html("<i class='play icon'></i>");
  289. }else{
  290. $(".playBtn").html("<i class='pause icon'></i>");
  291. }
  292. },1000);
  293. updateVolControlDisplay(getCurrentGlobVol());
  294. //Add volume bar change event listener
  295. $("#volControlOverlay").on("click",function(e){
  296. var x = e.pageX - $('#volControlOverlay').offset().left;
  297. var y = e.pageY - $('#volControlOverlay').offset().top;
  298. var height = $('#volControlOverlay').height();
  299. var newvol = Math.round(((height - y) / height)*20)/20;
  300. localStorage.setItem("global_volume",newvol);
  301. player.volume = newvol;
  302. updateVolControlDisplay(newvol);
  303. });
  304. //Also add draging bar for mouse operations
  305. player.onended = function(){
  306. if (!repeatMode){
  307. $(".playBtn").html("<i class='play icon'></i>");
  308. }
  309. }
  310. var dragging = false;
  311. $("#volControlOverlay").on("mousedown",function(){
  312. dragging = true;
  313. });
  314. $("#volControlOverlay").on("mousemove",function(e){
  315. if (dragging){
  316. var y = e.pageY - $('#volControlOverlay').offset().top;
  317. var height = $('#volControlOverlay').height();
  318. var newvol = Math.round(((height - y) / height)*100)/100;
  319. //console.log(newvol);
  320. localStorage.setItem("global_volume",newvol);
  321. player.volume = newvol;
  322. updateVolControlDisplay(newvol);
  323. }
  324. });
  325. $("#volControlOverlay").on("mouseup",function(){
  326. if (dragging){
  327. dragging = false;
  328. }
  329. });
  330. $("body").on("mouseup",function(){
  331. if (dragging){
  332. dragging = false;
  333. }
  334. });
  335. //Audio element custom UI listeners
  336. document.getElementById("progressControl").addEventListener("click",function(e){
  337. //Click on the progress control bar, update the audio playing location
  338. var x = e.pageX - $('#progressControl').offset().left;
  339. var w = $("#progressControl").width();
  340. var alength = player.duration;
  341. var targetPos = (x / w * alength);
  342. player.currentTime = targetPos;
  343. });
  344. player.addEventListener("timeupdate", function(){
  345. var currentTime = player.currentTime;
  346. var duration = player.duration;
  347. var progressPercentage = currentTime / duration * 100 + "%";
  348. $("#playbackProgress").css("width",progressPercentage);
  349. if (!mediaExchanging){
  350. updateDurationDisplay(currentTime,duration);
  351. }
  352. });
  353. //Load repeat mode from storage
  354. var repeatMode = false;
  355. repeatMode = loadStorage("repeatModeEmbedded");
  356. if (repeatMode != ""){
  357. repeatMode = (repeatMode == "true");
  358. }
  359. if (repeatMode){
  360. $("#repeatModeBtn").addClass("modeEnabled");
  361. player.loop = true;
  362. }
  363. //End of startup seuqence
  364. function updatePlayingSongSelection(){
  365. $(".listitem.selected").removeClass("selected");
  366. $(".listitem").each(function(){
  367. if ($(this).attr("filename") == songInfo[0]){
  368. $(this).addClass("selected");
  369. }
  370. });
  371. }
  372. function showRelatedFileList(){
  373. if (ao_module_virtualDesktop){
  374. if (listShown){
  375. ao_module_setWindowSize(360,254);
  376. listShown = false;
  377. }else{
  378. ao_module_setWindowSize(360,540);
  379. listShown = true;
  380. }
  381. }
  382. }
  383. function lastSong(){
  384. //Switch to the next song in list
  385. player.pause();
  386. mediaExchanging = true;
  387. $(".durationDisplay").html('<i class="clock icon"></i> Loading Media');
  388. var nextSong = -1; //There is no next song in the current directory
  389. for (var i =0; i < songList.length; i++){
  390. if (songList[i][0] == songInfo[0]){
  391. //Filename are the same
  392. if (i-1 < 0){
  393. //This is the last song in list
  394. nextSong = songList[songList.length - 1]
  395. }else{
  396. //Play previous song
  397. nextSong = songList[i-1]
  398. }
  399. }
  400. }
  401. if (nextSong == -1){
  402. //There is no more similar file with similar extensions or there are no other supported files in the same directory.
  403. player.currentTime = 0;
  404. updateDisplayInformation(ao_module_codec.decodeUmFilename(songInfo[0]),songInfo[3]);
  405. player.play();
  406. setTimeout(function(){
  407. mediaExchanging = false;
  408. },300);
  409. return;
  410. }
  411. loadSongFromSongInfo(nextSong);
  412. player.play();
  413. setTimeout(function(){
  414. mediaExchanging = false;
  415. },300);
  416. updatePlayingSongSelection();
  417. }
  418. function uuidv4() {
  419. return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
  420. (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  421. );
  422. }
  423. function createPlayList(){
  424. $(".sameDirFileList").html("");
  425. for (var i = 0; i < songList.length; i++){
  426. //console.log(box);
  427. let thisFileItemID = "thumb_" + uuidv4();
  428. $(".sameDirFileList").append(`<div class="listitem" filename="${songList[i][0]}" onClick="playThis(this);">
  429. <div class="ui unstackable grid">
  430. <div class="three wide column" align="right">
  431. <img id="${thisFileItemID}" class="ui image noradius" style="height: 2rem;" src="img/eq.svg">
  432. </div>
  433. <div class="thirteen wide column">
  434. ${ao_module_codec.decodeUmFilename(songList[i][0])} (${songList[i][3]})
  435. </div>
  436. </div>
  437. </div>`);
  438. ao_module_agirun("Music/functions/getThumbnail.js", {
  439. file: songList[i][1],
  440. }, function(data){
  441. if (data.error !== undefined){
  442. }else{
  443. $("#" + thisFileItemID).attr("src","data:image/jpg;base64," + data);
  444. }
  445. });
  446. }
  447. }
  448. function playThis(object){
  449. var songName = $(object).attr("filename");
  450. $(".listitem.selected").removeClass("selected");
  451. $(object).addClass("selected");
  452. for (var i =0; i < songList.length; i++){
  453. if (songList[i][0] == songName){
  454. //This is the song that the user request to play.
  455. player.pause();
  456. mediaExchanging = true;
  457. $(".durationDisplay").html('<i class="clock icon"></i> Loading Media');
  458. loadSongFromSongInfo(songList[i]);
  459. player.play();
  460. setTimeout(function(){
  461. mediaExchanging = false;
  462. },300);
  463. break;
  464. }
  465. }
  466. }
  467. function nextSong(){
  468. //Switch to the next song in list
  469. player.pause();
  470. mediaExchanging = true;
  471. $(".durationDisplay").html('<i class="clock icon"></i> Loading Media');
  472. var nextSong = -1; //There is no next song in the current directory
  473. for (var i =0; i < songList.length; i++){
  474. if (songList[i][0] == songInfo[0]){
  475. //Filename are the same
  476. if (i+1 >= songList.length){
  477. //This is the last song in list
  478. nextSong = songList[0]
  479. }else{
  480. //Play next song
  481. nextSong = songList[i+1]
  482. }
  483. }
  484. }
  485. if (nextSong == -1){
  486. //There is no more similar file with similar extensions or there are no other supported files in the same directory.
  487. player.currentTime = 0;
  488. updateDisplayInformation(ao_module_codec.decodeUmFilename(songInfo[0]), songInfo[3]);
  489. player.play();
  490. setTimeout(function(){
  491. mediaExchanging = false;
  492. },300);
  493. return;
  494. }
  495. loadSongFromSongInfo(nextSong);
  496. player.play();
  497. setTimeout(function(){
  498. mediaExchanging = false;
  499. },300);
  500. updatePlayingSongSelection();
  501. }
  502. function blobToDataURL(blob, callback) {
  503. var a = new FileReader();
  504. a.onload = function(e) {callback(e.target.result);}
  505. a.readAsDataURL(blob);
  506. }
  507. function loadSongFromSongInfo(playSongInfo){
  508. var songName = ao_module_codec.decodeUmFilename(playSongInfo[0]);
  509. var songPath = playSongInfo[1];
  510. var fileSize = playSongInfo[3];
  511. $(player).attr('src',"/media?file=" + encodeURIComponent(songPath));
  512. ao_module_setWindowTitle(songName);
  513. songInfo = playSongInfo;
  514. updateDisplayInformation(ao_module_codec.decodeUmFilename(songInfo[0]),songInfo[3]);
  515. updatePlayerThemeAndBackground(songPath);
  516. }
  517. //Update the player background and theme color
  518. function updatePlayerThemeAndBackground(songPath){
  519. ao_module_agirun("Music/functions/getThumbnail.js", {
  520. file: songPath,
  521. }, function(data){
  522. if (data.error == undefined){
  523. let imageSrc = "data:image/jpg;base64," + data;
  524. $("#Albumnart").attr("src",imageSrc);
  525. //Get theme color and update the player theme color
  526. let themeColor = getAverageRGB($("#Albumnart")[0]);
  527. updateThemeColor(themeColor);
  528. }else{
  529. //No thumbnail. Restore to default theme color
  530. updateThemeColor({r:24, g: 110, b: 210});
  531. $("#Albumnart").attr("src","img/nothumb.png");
  532. }
  533. }
  534. );
  535. }
  536. //Update the theme color, require something like { r: 231, g: 159, b: 140 }
  537. function updateThemeColor(newRGBColor){
  538. let colorText = `rgb(${newRGBColor.r} ,${newRGBColor.g} ,${newRGBColor.b})`
  539. $("#playbackProgress").css("background-color", colorText);
  540. $("#playpauseBtn").css("background-color", colorText);
  541. $("#volControl").css("background-color", colorText);
  542. $(".modeEnabled")[0].style.setProperty( "background-color", colorText, 'important' );
  543. //$(".sameDirFileList").css("background-color", `rgba(${newRGBColor.r}, ${newRGBColor.g}, ${newRGBColor.b}, 0.1)`);
  544. }
  545. function updateDisplayInformation(songname, filesize){
  546. $("#songtitle").html("<i class='music icon'></i>" + songname)
  547. $("#fileSize").html("<i class='file outline icon'></i> " + filesize);
  548. }
  549. function updateDurationDisplay(pos,dur){
  550. pos = secondsToHMS(pos);
  551. dur = secondsToHMS(dur);
  552. $(".durationDisplay").html(pos.trim() + " / " + dur.trim());
  553. }
  554. function secondsToHMS(sec){
  555. let totalSeconds = sec;
  556. let hours = Math.floor(totalSeconds / 3600);
  557. totalSeconds %= 3600;
  558. let minutes = Math.floor(totalSeconds / 60);
  559. let seconds = totalSeconds % 60;
  560. if (hours > 0){
  561. hours = String(hours).padStart(2, "0");
  562. }else{
  563. hours = 0;
  564. }
  565. seconds = Math.round(seconds);
  566. minutes = String(minutes).padStart(2, "0");
  567. seconds = String(seconds).padStart(2, "0");
  568. if (hours != 0){
  569. return hours + ":" + minutes + ":" + seconds;
  570. }else{
  571. return minutes + ":" + seconds;
  572. }
  573. }
  574. function togglePlay(object){
  575. if (player.paused == true){
  576. player.play();
  577. $(object).html("<i class='pause icon'></i>");
  578. }else{
  579. player.pause();
  580. $(object).html("<i class='play icon'></i>");
  581. }
  582. }
  583. function toggleRepeat(object){
  584. if ($(object).hasClass("modeEnabled")){
  585. $(object).removeClass("modeEnabled");
  586. repeatMode = false;
  587. setStorage("repeatModeEmbedded","false");
  588. player.loop = false;
  589. }else{
  590. $(object).addClass("modeEnabled");
  591. repeatMode = true;
  592. setStorage("repeatModeEmbedded","true");player.loop = true;
  593. }
  594. }
  595. function updateVolControlDisplay(percentage){
  596. var adjWidth = percentage * 100 + "%";
  597. $("#volControl").css("width",adjWidth);
  598. $("#volControl").attr("vol",percentage);
  599. }
  600. function getCurrentGlobVol(){
  601. //console.log(localStorage.getItem("global_volume"));
  602. if (localStorage.getItem("global_volume") === null || localStorage.getItem("global_volume") == ""){
  603. return 0;
  604. }
  605. return parseFloat(localStorage.getItem("global_volume"));
  606. }
  607. function setStorage(configName,configValue){
  608. $.ajax({
  609. type: 'GET',
  610. url: "/system/file_system/preference",
  611. data: {key: "Music/" + configName,value:configValue},
  612. success: function(data){},
  613. async:true
  614. });
  615. return true;
  616. }
  617. function loadStorage(configName){
  618. var result = "";
  619. $.ajax({
  620. type: 'GET',
  621. url: "/system/file_system/preference",
  622. data: {key: "Music/" + configName},
  623. success: function(data){
  624. if (data.error !== undefined){
  625. result = "";
  626. }else{
  627. result = data;
  628. }
  629. },
  630. error: function(data){result = "";},
  631. async:false,
  632. timeout: 3000
  633. });
  634. return result;
  635. }
  636. function getAverageRGB(imgEl) {
  637. var blockSize = 5,
  638. defaultRGB = {r:0,g:0,b:0},
  639. canvas = document.createElement('canvas'),
  640. context = canvas.getContext && canvas.getContext('2d'),
  641. data, width, height,
  642. i = -4,
  643. length,
  644. rgb = {r:0,g:0,b:0},
  645. count = 0;
  646. if (!context) {
  647. return defaultRGB;
  648. }
  649. height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
  650. width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;
  651. context.drawImage(imgEl, 0, 0);
  652. try {
  653. data = context.getImageData(0, 0, width, height);
  654. } catch(e) {
  655. /* security error, img on diff domain */
  656. return defaultRGB;
  657. }
  658. length = data.data.length;
  659. while ( (i += blockSize * 4) < length ) {
  660. ++count;
  661. rgb.r += data.data[i];
  662. rgb.g += data.data[i+1];
  663. rgb.b += data.data[i+2];
  664. }
  665. // ~~ used to floor values
  666. rgb.r = ~~(rgb.r/count);
  667. rgb.g = ~~(rgb.g/count);
  668. rgb.b = ~~(rgb.b/count);
  669. return rgb;
  670. }
  671. </script>
  672. </body>
  673. </html>