HTML5 for MoeFM

萌否电台 HTML5 脚本

  1. // ==UserScript==
  2. // @name HTML5 for MoeFM
  3. // @version 1.0.15
  4. // @description 萌否电台 HTML5 脚本
  5. // @match http://moe.fm/listen*
  6. // @include http://moe.fm/listen*
  7. // @author 864907600cc
  8. // @icon http://nyan.moefou.org/avatar_group/00/00/000074.jpg
  9. // @grant none
  10. // @namespace http://ext.ccloli.com
  11. // ==/UserScript==
  12.  
  13. // HTML5 for MoeFM
  14. // 萌否电台 HTML5 脚本
  15. // 适用于有 Flash 强迫症或平台不支持 Flash 的萌否电台用户 o(* ̄▽ ̄*)ブ
  16. // 脚本在 Chrome 32、Firefox 25、IE 11 下测试通过
  17. // 本脚本基于 GPLv3 协议开源 http://www.gnu.org/licenses/gpl.html‎
  18. // (c) 86497600cc. Some Rights Reserved.
  19.  
  20. var audio_pretest=document.createElement('audio');
  21. if(audio_pretest.canPlayType('audio/mpeg')==''){
  22. alert('很抱歉,看起来您的浏览器不支持 MPEG (MP3) 文件……\n支持 MPEG 编码的浏览器请参考 http://caniuse.com/#feat=mpeg4');
  23. throw 'It seems that the browser doesn\'t support MPEG media...';
  24. }
  25.  
  26. var user,user_panel;
  27. if(typeof is_login!='undefined'&&is_login==true){
  28. user=document.getElementsByClassName('navi-panel-button')[0].innerHTML;
  29. user_panel=document.getElementsByClassName('navi-panel-content')[0].innerHTML;
  30. }
  31.  
  32. var stylesheet=document.createElement('style');
  33. stylesheet.textContent='@font-face{font-family:moefm-html5-icomoon;src:url(data:;base64,AAEAAAALAIAAAwAwT1MvMg6RrIMAAAC8AAAAYGNtYXD3FtuvAAABHAAAAJRnYXNwAAAAEAAAAbAAAAAIZ2x5ZnroKBEAAAG4AAAHjGhlYWQC2F0JAAAJRAAAADZoaGVhCAIEEAAACXwAAAAkaG10eC5AAQAAAAmgAAAAPGxvY2EK2gyiAAAJ3AAAACBtYXhwABQAjgAACfwAAAAgbmFtZSU42yMAAAocAAABpXBvc3QAAwAAAAALxAAAACAAAwQAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABCAAAAAAAAAAAAAAAAAAAAABAAACXWQPA/8D/wAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEAIAAAAAcABAAAwAMAAEAIE4LTi1Oq1BcWSdcD18DZK2Fz5dZ//3//wAAAAAAIE4KTi1Oq1BcWSdcD18DZK2Fz5dZ//3//wAB/+Ox+rHZsVyvrKbio/uhCJtfej5otQADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQCAAEADgANAAAsAADcRMxEBEQERAREBEYCAAUABQP7A/sBAAwD+oAFA/sABQP1AAUD+wAFA/qAAAAAAAQCAAEADgANAAAsAAAERIxEBEQERAREBEQOAgP7A/sABQAFAA0D9AAFg/sABQP7AAsD+wAFA/sABYAAAAwAAAA8DcANxACgATABdAAAlIi4CJy4BNDY3PgE0JicuATQ2Nz4BMhYXHgMVFA4CBw4DIyciLgInLgE0Njc+ATQmJy4BNDY3PgEyFhceARQGBw4DIwM+AR4BFREUDgEmLwEjETM3AtAFCQkIAwcHBwcxMTExBwcHBwcRExEHHy8gEREgLx8DCAkJBKsFCQgIBAcHBwceHx8eBwcHBwcSEhIHLC0tLAQICAkFlAoRDQcHDREK8aCg8YACBAUEBxETEQcye4J7MgcRExEHBwgIBx5HTVQrK1RNRx4EBQQCWwIDBgMHEhISBx5NUE0eBxISEgcHBwcHLHF0cSwDBgMCApYKBwYQDvzEDhAGBwrxAYDxAAAAAQAA/8AEAAPAAFQAAAEiDgIHJTQ+ATQ1PAEuATUlHgMzMj4CNTQuAiMiDgIVHAEeARUFLgMjIg4CFRQeAjMyPgI3BRQOARQVFB4CMzI+AjU0LgIjA2ARIB0aC/5RAQEBAQGvCxodIBEhOiwZGSw6ISE6LBkBAf5RCxodIBEhOiwZGSw6IREgHRoLAa8BARksOiEhOiwZGSw6IQEABwwTC9gDBgYHAwMHBgYD2AsTDAcZLDohITosGRksOiEDBwYGA9gLEwwHGSw6ISE6LBkHDBML2AMGBgcDITosGRksOiEhOiwZAAAAAAQAAP/ABAADwAAUACkALQAxAAABIg4CFRQeAjMyPgI1NC4CIxEiLgI1ND4CMzIeAhUUDgIjAzMRIwEzESMCAGq7i1BQi7tqaruLUFCLu2pWmHFBQXGYVlaYcUFBcZhWwICAAQCAgAPAUIu7amq7i1BQi7tqaruLUPxgQXGYVlaYcUFBcZhWVphxQQJg/oABgP6AAAAEAAAADwRAA3EALQBWAHoAiwAAJSIuAicuATQ2Nz4DNTQuAicuATQ2Nz4BMhYXHgMVFA4CBw4DIyciLgInLgE0Njc+ATQmJy4BNDY3PgEyFhceAxUUDgIHDgMjJyIuAicuATQ2Nz4BNCYnLgE0Njc+ATIWFx4BFAYHDgMjAz4BHgEVERQOASYvASMRMzcDegUJCAgEBwcHByEzIhISIjMhBwcHBwcSEhIHKD0pFhYpPSgECAgJBaoFCQkIAwcHBwcxMTExBwcHBwcRExEHHy8gEREgLx8DCAkJBKsFCQgIBAcHBwceHx8eBwcHBwcSEhIHLC0tLAQICAkFlAoRDQcHDREK8aCg8SYCAwYDBxISEgchTFNaLi5aU0whBxISEgcHBwcHKFtlbDg4bGVbKAMGAwJaAgQFBAcRExEHMnuCezIHERMRBwcICAceR01UKytUTUceBAUEAlsCAwYDBxISEgceTVBNHgcSEhIHBwcHByxxdHEsAwYDAgKWCgcGEA78xA4QBgcK8QGA8QACAAAADwJHA3EAIwA0AAAlIi4CJy4BNDY3PgE0JicuATQ2Nz4BMhYXHgEUBgcOAyMDPgEeARURFA4BJi8BIxEzNwIlBQkICAQHBwcHHh8fHgcHBwcHEhISBywtLSwECAgJBZQKEQ0HBw0RCvGgoPHbAgMGAwcSEhIHHk1QTR4HEhISBwcHBwcscXRxLAMGAwIClgoHBhAO/MQOEAYHCvEBgPEAAAEAAAAABAADgAAxAAABFA4CBxUBDgMHLgMnAS4DNTQ+Ahc2HgIXBxcDASc3PgMXNh4CFQQADRojFv7ADBgYGAwMGBgYDP7AFiMaDS5Qaz0VKCYkEV7ggAFg4E8JEhMTCj1rUC4CWiA+NjITAf7BDRYTCgEBChMWDQE/FTA4PCI8bE8vAQEHCREJl3/+vwGBf3cCBAICAQEvT2w8AAMAAP/ABAADwAAUACkALAAAASIOAhUUHgIzMj4CNTQuAiMRIi4CNTQ+AjMyHgIVFA4CIwMNAQIAaruLUFCLu2pqu4tQUIu7alaYcUFBcZhWVphxQUFxmFaAAYD+gAPAUIu7amq7i1BQi7tqaruLUPxgQXGYVlaYcUFBcZhWVphxQQKA4OAAAAABAAAAAAQAA4AAKwAAARQOAgcVAQ4DBy4DJwEuAzU0PgIXNh4CFz4DFzYeAhUEAA0aIxb+wAwYGBgMDBgYGAz+wBYjGg0uUGs9IT03MRQUMTc9IT1rUC4CWiA+NjITAf7BDRYTCgEBChMWDQE/FTA4PCI8bE8vAQEOGSQVFSQZDgEBL09sPAAAAgAAAA8DwANxABAAIAAAAT4BHgEVERQOASYvASMRMzcBFSMnByM1Nyc1Mxc3MxUHAZEKEQ0HBw0RCvGgoPECL1Vra1Vra1Vra1VrA3EKBwYQDvzEDhAGBwrxAYDx/eRVa2tVa2tVa2tVawAAAQAAAAEZmmqL7bJfDzz1AAsEAAAAAADPvH95AAAAAM+8f3kAAP/ABEADwAAAAAgAAgAAAAAAAAABAAADwP/AAAAEQAAAAAAEQAABAAAAAAAAAAAAAAAAAAAADwAAAAAAAAAAAAAAAAIAAAAEAACABAAAgAQAAAAEAAAABAAAAARAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAACgAUAB4APABaAOQBWAGiAmgCugMIA0wDkAPGAAEAAAAPAIwABAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAK4AAQAAAAAAAQAmAAAAAQAAAAAAAgAOAJsAAQAAAAAAAwAmADwAAQAAAAAABAAmAKkAAQAAAAAABQAWACYAAQAAAAAABgATAGIAAQAAAAAACgAoAM8AAwABBAkAAQAmAAAAAwABBAkAAgAOAJsAAwABBAkAAwAmADwAAwABBAkABAAmAKkAAwABBAkABQAWACYAAwABBAkABgAmAHUAAwABBAkACgAoAM8AbQBvAGUAZgBtAC0AaAB0AG0AbAA1AC0AaQBjAG8AbQBvAG8AbgBWAGUAcgBzAGkAbwBuACAAMQAuADEAbQBvAGUAZgBtAC0AaAB0AG0AbAA1AC0AaQBjAG8AbQBvAG8Abm1vZWZtLWh0bWw1LWljb21vb24AbQBvAGUAZgBtAC0AaAB0AG0AbAA1AC0AaQBjAG8AbQBvAG8AbgBSAGUAZwB1AGwAYQByAG0AbwBlAGYAbQAtAGgAdABtAGwANQAtAGkAYwBvAG0AbwBvAG4ARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABJAGMAbwBNAG8AbwBuAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=)}html,body{width:100%;height:100%;margin:0;padding:0;overflow:hidden}html,.cover{background-size:cover;background-position:center center;background-repeat:no-repeat no-repeat}html{background-attachment:fixed;transition:background 0.5s linear}body{background:rgba(255,255,255,0.5);user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;font-family:"Hiragino Sans GB","Microsoft Yahei","WenQuanYi Micro Hei",Arial,Tahoma,sans-serif}::selection{background:rgba(0,0,0,0.5)}::-moz-selection{background:rgba(0,0,0,0.5)}section{width:600px;height:600px;position:absolute;left:0;right:0;top:0;bottom:0;font-size:16px;margin:auto;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;text-shadow:0 0 1px rgba(50,50,50,0.75)}.cover{width:400px;height:400px;background-color:rgba(50,50,50,.75);margin:10px auto;border:solid 2px #fff;box-shadow:0 0 5px #000;-webkit-transition:0.25s width linear,0.25s height linear;-o-transition:0.25s width linear,0.25s height linear;transition:0.25s width linear,0.25s height linear;margin:20px auto 10px}.cover_preload,.background_preload{position:absolute}.info ul{list-style:none;padding:0;margin:0;text-align:center}.info ul li{padding:5px 0;user-select:text;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;line-height:1em;overflow:hidden;height:1em;white-space:nowrap;text-overflow:ellipsis;transition:0.25s all linear}.title{font-size:2em}.control{font-size:3em;text-align:center;font-family:moefm-html5-icomoon;/*pointer-events:none*/}.control>span:not([hidden]){cursor:pointer;pointer-events:auto;display:inline-block;width:1.1em;height:1.1em;line-height:1.1em;text-align:left;overflow:hidden;white-space:nowrap;padding:0 5px;letter-spacing:0.1em;transition:0.25s all linear}.control>span:hover{text-shadow:0 0 2px #000}.control>span[meow]{color:#F00}.control>span.c_volume:hover{width:3.5em}.control>span.c_volume:hover .c_volume_range{width:100px;opacity:1}.control>span.c_volume_icon{display:inline-block;width:1.1em}.control2{text-align:center;font-family:moefm-html5-icomoon;position:absolute;z-index:1;cursor:pointer}.control2>span{opacity:0;font-size:200px;padding:100px;background:rgba(0,0,0,0.5);position:absolute;transition:0.25s all linear;text-shadow:0 0 5px #FFF}.control2:hover>span{opacity:1}.control2>span.c_play{opacity:1}.c_volume_range{height:20px;width:0px;margin:0;padding:0;opacity:0;-webkit-appearance:none;-webkit-transition:0.25s all linear;-o-transition:0.25s all linear;transition:0.25s all linear;outline:none;position:absolute;margin-left:5px;margin-top:15px;background:none}.c_volume_range::-webkit-slider-container{-webkit-appearance:none;height:2em}.c_volume_range::-webkit-slider-runnable-track{-webkit-appearance:none;background:#000;box-shadow:0 0 1px #000}.c_volume_range::-webkit-slider-thumb{-webkit-appearance:none;background:#FFF;border:1px #000 solid;border-radius:0;width:10px;height:20px}.c_volume_range::-moz-range-track{background:#000;height:20px;box-shadow:0 0 1px #000}.c_volume_range::-moz-range-thumb{background:#FFF;border-radius:0;width:10px;height:20px}.c_volume_range::-ms-track{background:#000;height:20px;box-shadow:0 0 1px #000}.c_volume_range::-ms-thumb{background:#FFF;border-radius:0;width:10px;height:20px}.c_volume_range::-ms-fill-lower{background:#000}.c_volume_range[disabled]{opacity:0.75;pointer-events:none}.timeline{position:fixed;top:0;left:0;width:100%;height:20px;font-size:12px;line-height:20px;background:rgba(0,0,0,0.5);color:#fff;z-index:100;-webkit-transition:0.25s all linear;-o-transition:0.25s all linear;transition:0.25s all linear;box-shadow:0 0 2px rgba(0,0,0,0.5)}.timeline_current_time,.timeline_duration_time{z-index:105;position:fixed;pointer-events:none;transition:0.25s all linear}.timeline_current_time{left:5px}.timeline_duration_time{right:5px}.timeline_current,.timeline_duration{left:0px;height:20px;position:fixed;top:0;-webkit-transition:0.25s all linear;-o-transition:0.25s all linear;transition:0.25s all linear;pointer-events:none}.timeline_duration{background:rgba(255,255,255,0.5);z-index:101}.timeline_current{background:rgba(0,0,0,0.5);z-index:102}footer{background:rgba(0,0,0,0.5);position:fixed;bottom:0;left:0;width:100%;height:20px;font-size:12px;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;color:#FFF;/*pointer-events:none;*/text-shadow:0 0 2px #000;-webkit-transition:0.25s all linear;-o-transition:0.25s all linear;transition:0.25s all linear;box-shadow:0 0 2px rgba(0,0,0,0.5)}footer a,footer span{display:inline-block;padding:0 5px;color:#FFF;text-decoration:none;cursor:pointer;pointer-events:auto;transition:0.25s all ease-out}footer a:hover,footer span:hover{background-color:rgba(255,255,255,0.5);color:#FFF;transition:0.25s all ease-out}.link_left{position:fixed;height:20px;line-height:20px;padding-left:10px;left:0;bottom:0;transition:0.25s all linear}.link_right{position:fixed;height:20px;line-height:20px;padding-right:10px;right:0;bottom:0;transition:0.25s all linear}.link_right_user{display:inline}.link_right_user_btn>div a{display:block;height:16.66667px;line-height:16.66667px}aside{width:200px;font-size:12px;position:fixed;height:100px;right:-180px;top:50%;margin-top:-50px;/*top:0;bottom:0;left:auto;margin:auto;*/background-color:rgba(0,0,0,0.5);-webkit-transition:0.25s all ease-in;-o-transition:0.25s all ease-in;transition:0.25s all ease-in;box-shadow:0 0 2px rgba(0,0,0,0.5)}aside:hover{right:0;-webkit-transition:0.25s all ease-out;-o-transition:0.25s all ease-out;transition:0.25s all ease-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}aside ul{margin:0;padding:0;opacity:0;;-webkit-transition:0.25s all ease-in;-o-transition:0.25s all ease-in;transition:0.25s all ease-in;pointer-events:none}aside:hover ul{opacity:1;-webkit-transition:0.25s all ease-out;-o-transition:0.25s all ease-out;transition:0.25s all ease-out;pointer-events:auto}aside li{height:25px;line-height:25px;list-style:none;padding-left:24px;color:#FFF;-webkit-transition:0.25s all ease-in;-o-transition:0.25s all ease-in;transition:0.25s all ease-in;cursor:pointer;background-repeat:no-repeat no-repeat;background-position:4px center;background-image:none;margin-left:200px}aside:hover li{margin-left:0px}aside li:hover{background-color:rgba(255,255,255,0.5);transition:0.25s all ease-out;-webkit-transition:0.25s all ease-out;-o-transition:0.25s all ease-out}aside .aside_album{background-image:url(http://moe.fm/public/images/fm/fav_music_gray.png)}aside .aside_song{background-image:url(http://moe.fm/public/images/fm/fav_love_gray.png)}aside .aside_radio{background-image:url(http://moe.fm/public/images/fm/fav_star_gray.png)}aside .aside_random{background-image:url(http://moe.fm/public/images/fm/fav_magnifier_gray.png)}.share_panel,.setting_background_panel{background:rgba(255,255,255,0.5);box-shadow:0 0 0 5000px rgba(0,0,0,0.5);border-radius:2px;padding:20px;width:200px;height:100px;position:absolute;top:0;bottom:0;left:0;right:0;z-index:201;margin:auto;text-align:center;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;max-width:90%;max-height:90%}.setting_background_panel{width:600px;height:400px}.share_panel button,.setting_background_panel button{margin:6px;font-size:14px}.setting_background_panel textarea{width:100%;height:350px;background-color:rgba(255,255,255,0.5)}.share_panel_background,.setting_background_panel_background{width:100%;height:100%;position:fixed;z-index:200}.share_buttons{display:block;margin:5px}.share_buttons .share-button{opacity:0.6;-webkit-transition:0.25s opacity ease-in;-o-transition:0.25s opacity ease-in;transition:0.25s opacity ease-in;display:inline-block}.share_buttons .share-button:hover{opacity:1;-webkit-transition:0.25s opacity ease-out;-o-transition:0.25s opacity ease-out;transition:0.25s opacity ease-out;}.error_notification{position:fixed;right:10px;padding:5px;bottom:0px;box-shadow:0 0 1px 5px rgba(0,0,0,0.5);background:rgba(0,0,0,0.5);font-size:12px;color:#fff;opacity:0;-webkit-transition:0.25s all linear;-o-transition:0.25s all linear;transition:0.25s all linear;pointer-events:none}.cover_loading_notification{width:100%;height:100%;background:rgba(0,0,0,0.5);color:#FFF;opacity:0;text-shadow:0 0 2px #FFF;pointer-events:none;transition:0.25s all linear}a{color:#000}@media all and (min-width:500px) and (max-width:600px),all and (min-height:450px) and (max-height:600px){section{width:500px;height:400px;font-size:14px}.cover{width:250px;height:250px;margin:5px auto}.info ul{margin:5px 0}.c_volume_range{max-width:80px;height:20px;margin-top:8px}.control2>span{font-size:150px;padding:50px}}@media all and (min-width:500px) and (min-height:200px) and (max-height:450px),all and (max-width:500px) and (max-height:299px){section{width:500px;height:165px;font-size:14px}.cover{width:150px;height:150px;float:left;margin:5px}.info ul{margin:1em 0}.c_volume{max-width:3em}.c_volume_range{max-width:50px;height:14px;margin-top:10px}.c_volume_range::-webkit-slider-container,.c_volume_range::-webkit-slider-runnable-track,.c_volume_range::-webkit-slider-thumb{height:1em}.c_volume_range::-moz-range-track,.c_volume_range::-moz-range-thumb{height:1em}.control>span{font-size:32px}.control2>span{font-size:90px;padding:30px}}@media all and (max-height:200px){section{width:400px;height:105px;font-size:12px}.cover{width:100px;height:100px;margin:0;float:left}.info ul{margin:0}.info ul li{padding:4px 2px}.c_volume{max-width:3em}.c_volume_range{max-width:40px;height:14px;margin-top:5px}.c_volume_range::-webkit-slider-container,.c_volume_range::-webkit-slider-runnable-track,.c_volume_range::-webkit-slider-thumb{height:1em}.c_volume_range::-moz-range-track,.c_volume_range::-moz-range-thumb{height:1em}.control>span{font-size:24px}.control2>span{font-size:50px;padding:25px}}@media all and (max-height:150px){.timeline,.timeline>*{top:-20px!important}footer,footer>*{bottom:-20px!important}aside{right:-200px}aside,footer,.timeline{box-shadow:none}}@media all and (max-width:500px) and (min-height:300px){section{width:300px;height:330px;font-size:12px}.cover{width:200px;height:200px;margin:5px auto}.control>span{font-size:24px}.c_volume_range{max-width:50px;height:14px;margin-top:0px}.control{font-size:1em}.control2>span{font-size:120px;padding:40px}.c_volume_range::-webkit-slider-container,.c_volume_range::-webkit-slider-runnable-track,.c_volume_range::-webkit-slider-thumb{height:1em}.c_volume_range::-moz-range-track,.c_volume_range::-moz-range-thumb{height:1em}.link_left{-webkit-transform:translateX(-300px);transform:translateX(-300px)}}@media all and (max-width:500px) and (max-height:380px) and (min-height:300px){section{height:270px}.cover{width:150px;height:150px}.control2>span{font-size:90px;padding:30px}.info ul li{padding:4px}}@media all and (-ms-high-contrast: active), (-ms-high-contrast: none){.c_volume_range{margin-left:-10px;box-shadow:0 0 1px #000}}';
  34. document.head.appendChild(stylesheet);
  35. document.body.innerHTML='<section><audio autoplay="true" class="audio"></audio><div class="cover"><div class="control2"><span class="c_play" title="播放" hidden="hidden">播</span><span class="c_pause" title="暂停">停</span></div><img class="cover_preload" width="0" height="0"><div class="cover_loading_notification"></div></div><div class="info"><ul><li class="title">Title</li><li class="artist">Artist</li><li class="album">Album</li></ul></div><div class="control"><span class="c_previous" title="上一曲">上</span><span class="c_next" title="下一曲">下</span><span class="c_like" title="喜欢">藏</span><span class="c_dislike" title="抛弃">弃</span><span class="c_volume" title="音量"><span class="c_volume_icon">大</span><input class="c_volume_range" type="range"></span><span class="c_share" title="分享">享</span></div><div class="timeline"><div class="timeline_duration"></div><div class="timeline_current"></div><div class="timeline_duration_time"></div><div class="timeline_current_time"></div></div></section><aside><ul><li class="aside_album">我收藏的专辑</li><li class="aside_song">我喜欢的曲目</li><li class="aside_radio">我收藏的电台</li><li class="aside_random">魔力播放</li></ul></aside><footer><div class="link_left"><a href="http://moe.fm/" target="_blank">电台首页</a><a href="http://moe.fm/listen">开始聆听</a><a href="http://moe.fm/explore" target="_blank">发现音乐</a><a href="http://moe.fm/about/client" target="_blank">客户端</a><a href="http://moefou.org/group/moefm" target="_blank">电台小组</a></div><div class="link_right"><!--<span class="link_setting">设置</span>--><span class="link_setting_background">设置背景</span><div class="link_right_user"></div></div><img class="background_preload" width="0" height="0" alt=""></footer>';
  36.  
  37. var setting=JSON.parse(localStorage.getItem('moefm-html5-setting'))||{},
  38. audio=document.getElementsByClassName('audio')[0],
  39. cover=document.getElementsByClassName('cover')[0],
  40. cover_preload=document.getElementsByClassName('cover_preload')[0],
  41. cover_loading_notification=document.getElementsByClassName('cover_loading_notification')[0],
  42. title=document.getElementsByClassName('title')[0],
  43. artist=document.getElementsByClassName('artist')[0],
  44. album=document.getElementsByClassName('album')[0],
  45. c_play=document.getElementsByClassName('c_play')[0],
  46. c_pause=document.getElementsByClassName('c_pause')[0],
  47. c_previous=document.getElementsByClassName('c_previous')[0],
  48. c_next=document.getElementsByClassName('c_next')[0],
  49. c_like=document.getElementsByClassName('c_like')[0],
  50. c_dislike=document.getElementsByClassName('c_dislike')[0],
  51. c_volume=document.getElementsByClassName('c_volume')[0],
  52. c_volume_icon=document.getElementsByClassName('c_volume_icon')[0],
  53. c_volume_range=document.getElementsByClassName('c_volume_range')[0],
  54. c_share=document.getElementsByClassName('c_share')[0],
  55. timeline=document.getElementsByClassName('timeline')[0],
  56. timeline_duration=document.getElementsByClassName('timeline_duration')[0],
  57. timeline_current=document.getElementsByClassName('timeline_current')[0],
  58. timeline_duration_time=document.getElementsByClassName('timeline_duration_time')[0],
  59. timeline_current_time=document.getElementsByClassName('timeline_current_time')[0],
  60. link_right_user=document.getElementsByClassName('link_right_user')[0],
  61. aside_album=document.getElementsByClassName('aside_album')[0],
  62. aside_song=document.getElementsByClassName('aside_song')[0],
  63. aside_radio=document.getElementsByClassName('aside_radio')[0],
  64. aside_random=document.getElementsByClassName('aside_random')[0],
  65. background_preload=document.getElementsByClassName('background_preload')[0],
  66. link_setting_background=document.getElementsByClassName('link_setting_background')[0],
  67. playlist=[],
  68. playlist_fetching=0,
  69. count=-1,
  70. volume=setting.volume||80,
  71. next=0,
  72. url_data,
  73. cover_retry=0,
  74. p=0,
  75. background_list=setting.background||[],
  76. background_count_time,
  77. background_count_time_value=0;
  78.  
  79. function audio_play(c){
  80. if(c==null)c=1;
  81. if(count<playlist.length-1){
  82. count+=c;
  83. audio.src=playlist[count].url;
  84. update_info();
  85. if(count>playlist.length-5)update_playlist(null,false);
  86. }
  87. else update_playlist(null,false);
  88. }
  89. function update_info(){
  90. cover_retry=0;
  91. if(cover_preload.src!=playlist[count].cover.large){
  92. cover_loading_notification.style.opacity=1;
  93. }
  94. cover_preload.src=playlist[count].cover.large;
  95. if(c_like.hasAttribute('meow'))c_like.removeAttribute('meow');
  96. if(c_dislike.hasAttribute('meow'))c_dislike.removeAttribute('meow');
  97. if(location.search.indexOf('music=')>=0?location.search.split('music=')[1].split('&')[0].indexOf(playlist[count].wiki_id)<0:
  98. (location.search.indexOf('song=')>=0?location.search.split('song=')[1].split('&')[0].indexOf(playlist[count].sub_id)<0:
  99. location.search.indexOf('radio=')<0)){
  100. window.history.replaceState(null,'','/listen?song='+playlist[count].sub_id);
  101. }
  102. if(playlist[count].sub_title){
  103. title.setAttribute('title',playlist[count].sub_title);
  104. title.innerHTML=playlist[count].sub_title;
  105. document.title=playlist[count].sub_title+' | 萌否电台';
  106. }
  107. else{
  108. title.innerHTML='';
  109. document.title='收听音乐 | 萌否电台';
  110. }
  111. if(playlist[count].artist){
  112. artist.innerHTML=playlist[count].artist;
  113. artist.setAttribute('title',playlist[count].artist);
  114. }
  115. else artist.innerHTML='';
  116. if(playlist[count].wiki_title){
  117. album.innerHTML=playlist[count].wiki_title;
  118. album.setAttribute('title',playlist[count].wiki_title);
  119. }
  120. else album.innerHTML='';
  121. if(playlist[count].fav_sub){
  122. if(playlist[count].fav_sub.fav_type==1)c_like.setAttribute('meow','1');
  123. else c_dislike.setAttribute('meow','1');
  124. }
  125. if(playlist[count].fav_wiki){
  126. if(playlist[count].fav_wiki.fav_type==1)album.innerHTML='(♥) '+playlist[count].wiki_title||'&nbsp;';
  127. }
  128. }
  129. function update_error(t,c){
  130. var div=document.createElement('div');
  131. div.className='error_notification';
  132. switch(t){
  133. case 'audio':
  134. context='播放音频时发生错误<br>'+c;
  135. case 'log':
  136. context='记录播放历史失败<br>'+c;
  137. break;
  138. case 'fav':
  139. context='添加收藏/抛弃记录失败<br>'+c;
  140. break;
  141. case 'playlist':
  142. context='获取播放列表失败<br>'+c;
  143. break;
  144. case 'cover':
  145. context='获取专辑图片失败<br>'+c;
  146. break;
  147. case 'background':
  148. context='获取背景图片失败<br>'+c;
  149. break;
  150. default:
  151. context=c;
  152. }
  153. div.innerHTML=context;
  154. document.body.appendChild(div);
  155. div.style.opacity=1;
  156. div.style.bottom='30px';
  157. setTimeout(function(){
  158. div.style.opacity=0;
  159. div.style.bottom='0px';
  160. setTimeout(function(){
  161. div.parentElement.removeChild(div);
  162. },1000);
  163. },5000);
  164. }
  165. function update_log(){
  166. if(typeof is_login!='undefined'&&is_login==true){
  167. var xhr=new XMLHttpRequest();
  168. xhr.onreadystatechange=function(){
  169. if(xhr.readyState==4){
  170. if(xhr.status==200){
  171. if(JSON.parse(xhr.responseText).status==false){
  172. update_error('log',JSON.parse(xhr.responseText).msg);
  173. }
  174. }
  175. else if(xhr.responseText){
  176. update_error('log',JSON.parse(xhr.responseText).response.error.message);
  177. }
  178. else{
  179. update_error('log','XHR Ready State: '+xhr.readyState+'<br>XHR Status: '+xhr.statusText);
  180. }
  181. }
  182. }
  183. xhr.open('GET','http://moe.fm/ajax/log?log_obj_type=sub&log_type=listen&obj_type=song&obj_id='+playlist[count].sub_id+'&_='+new Date().getTime());
  184. xhr.send();
  185. }
  186. else update_error('log','您尚未登录,请先登录......');
  187. }
  188. function update_fav(t,d){
  189. if(typeof is_login!='undefined'&&is_login==true){
  190. var xhr=new XMLHttpRequest(),
  191. f=new FormData();
  192. xhr.onreadystatechange=function(){
  193. if(xhr.readyState==4){
  194. if(xhr.status==200){
  195. if(JSON.parse(xhr.responseText).status==false){
  196. update_error('fav',JSON.parse(xhr.responseText).msg);
  197. }
  198. else{
  199. switch(t){
  200. case 1:
  201. switch (d){
  202. case 1:
  203. c_like.removeAttribute('meow');
  204. playlist[count].fav_sub=null;
  205. break;
  206. case 0:
  207. c_like.setAttribute('meow','1');
  208. playlist[count].fav_sub={};
  209. playlist[count].fav_sub.fav_type=1;
  210. break;
  211. }
  212. break;
  213. case 2:
  214. switch (d){
  215. case 1:
  216. c_dislike.removeAttribute('meow');
  217. playlist[count].fav_sub=null;
  218. break;
  219. case 0:
  220. c_dislike.setAttribute('meow','1');
  221. playlist[count].fav_sub={};
  222. playlist[count].fav_sub.fav_type=2;
  223. break;
  224. }
  225. break;
  226. }
  227. }
  228. }
  229. else if(xhr.responseText){
  230. update_error('fav',JSON.parse(xhr.responseText).response.error.message);
  231. }
  232. else{
  233. update_error('fav','XHR Ready State: '+xhr.readyState+'<br>XHR Status: '+xhr.statusText);
  234. }
  235. }
  236. }
  237. f.append('fav_data[fav_type]',t);
  238. f.append('fav_data[obj_id]',playlist[count].sub_id);
  239. f.append('fav_data[obj_type]','song');
  240. f.append('fav_data[delete]',d);
  241. xhr.open('POST','http://moe.fm/ajax/fav?_='+new Date().getTime());
  242. xhr.send(f);
  243. }
  244. else update_error('fav','您尚未登录,请先登录......');
  245. }
  246. function update_playlist(d,k){
  247. if(playlist_fetching==0){
  248. var is_update=1;
  249. if(d!=null){
  250. url_data=d;
  251. is_update=0;
  252. count=-1;
  253. if(/\d+/.test(d))p=1;
  254. }
  255. playlist_fetching=1;
  256. var xhr=new XMLHttpRequest();
  257. xhr.onreadystatechange=function(){
  258. if(xhr.readyState==4){
  259. if(xhr.status==200){
  260. if(JSON.parse(xhr.responseText).playlist){
  261. playlist_fetching=0;
  262. //count=-1;
  263. if(k==false&&is_update==1){
  264. for(var i=0,j=JSON.parse(xhr.responseText).playlist;i<j.length;i++){playlist.push(j[i]);}
  265. if(JSON.parse(xhr.responseText).info.may_have_next==true)p++;
  266. else{
  267. p=0;
  268. url_data=null;
  269. }
  270. }
  271. else{
  272. playlist=JSON.parse(xhr.responseText).playlist;
  273. if(JSON.parse(xhr.responseText).info.may_have_next==true)p++;
  274. else{
  275. p=0;
  276. url_data=null;
  277. }
  278. }
  279. if(k!=false){
  280. audio_play();
  281. }
  282. }
  283. else if(JSON.parse(xhr.responseText).response.error){
  284. update_error('playlist',JSON.parse(xhr.responseText).response.error.message);
  285. }
  286. }
  287. else if(xhr.responseText){
  288. update_error('playlist',JSON.parse(xhr.responseText).response.error.message);
  289. }
  290. else{
  291. update_error('playlist','XHR Ready State: '+xhr.readyState+'<br>XHR Status: '+xhr.statusText);
  292. }
  293. }
  294. }
  295. if(url_data==null)xhr.open('GET','http://moe.fm/listen/playlist?share_buttons=1&perpage=30&_='+new Date().getTime());
  296. else xhr.open('GET','http://moe.fm/listen/playlist?share_buttons=1&perpage=30&page='+p+'&'+url_data+'&_='+new Date().getTime());
  297. xhr.send();
  298. }
  299. }
  300. function update_volume_icon(v){
  301. if(v>66)c_volume_icon.innerHTML='大';
  302. else if(v>33)c_volume_icon.innerHTML='中';
  303. else c_volume_icon.innerHTML='小';
  304. }
  305. function update_background(){
  306. if(background_list.length==0){
  307. var xhr=new XMLHttpRequest();
  308. xhr.onreadystatechange=function(){
  309. if(xhr.readyState==4){
  310. if(xhr.status==200){
  311. background_list=JSON.parse(xhr.responseText).background_list;
  312. update_background();
  313. }
  314. else{
  315. update_error('background','获取背景图片列表失败<br>XHR Ready State: '+xhr.readyState+'<br>XHR Status: '+xhr.statusText);
  316. }
  317. }
  318. }
  319. xhr.open('GET','http://ext.ccloli.com/moe-fm/html5/background/');
  320. xhr.send();
  321. }
  322. else{
  323. var num=parseInt(Math.random()*(background_list.length-1));
  324. background_preload.src=background_list[num];
  325. //setTimeout(function(){update_background()},60000);
  326. }
  327. }
  328. function update_background_count(v){
  329. if(v==1){
  330. background_count_time=setInterval(function(){
  331. if(background_count_time_value>=60){
  332. update_background();
  333. background_count_time_value=0;
  334. }
  335. else{
  336. background_count_time_value++;
  337. }
  338. },1000);
  339. }
  340. else clearInterval(background_count_time);
  341. }
  342. function share(){
  343. var div=document.createElement('div'),
  344. div2=document.createElement('div');
  345. div.className='share_panel';
  346. div2.className='share_panel_background';
  347. div2.title='点击黑色区域以退出';
  348. div.innerHTML='<button onclick="var p=prompt(\'请按下 Ctrl + C 以复制,点击确定可跳转至该页面,点击取消返回。\',\''+playlist[count].sub_url+'#'+playlist[count].sub_title+' | 萌否电台\');if(p!=null)window.open(\''+playlist[count].sub_url+'\',\'_blank\')">复制当前曲目地址</button><button onclick="var p=prompt(\'请按下 Ctrl + C 以复制,点击确定可跳转至该页面,点击取消返回。\',\''+playlist[count].wiki_url+'#'+playlist[count].wiki_title+' | 萌否电台\');if(p!=null)window.open(\''+playlist[count].wiki_url+'\',\'_blank\')">复制当前专辑地址</button><span class="share_buttons">'+playlist[count].share_buttons+'</span>';
  349. document.body.appendChild(div);
  350. document.body.appendChild(div2);
  351. div2.addEventListener('click',function(){
  352. div.parentElement.removeChild(div);
  353. div2.parentElement.removeChild(div2);
  354. })
  355. }
  356.  
  357. audio.addEventListener('play',function(){
  358. c_play.setAttribute('hidden','hidden');
  359. c_pause.removeAttribute('hidden');
  360. update_info();
  361. })
  362. audio.addEventListener('pause',function(){
  363. c_pause.setAttribute('hidden','hidden');
  364. c_play.removeAttribute('hidden');
  365. })
  366. audio.addEventListener('timeupdate',function(){
  367. if(!isNaN(audio.duration)){
  368. timeline_current.style.width=(audio.currentTime/audio.duration)*100+'%';
  369. if(audio.buffered.length>0)timeline_duration.style.width=(audio.buffered.end(audio.buffered.length-1).toFixed(2))/(audio.duration.toFixed(2))*100+'%';
  370. timeline_current_time.innerHTML=parseInt(audio.currentTime/60)+':'+(parseInt(audio.currentTime)%60<10?'0'+parseInt(audio.currentTime)%60:parseInt(audio.currentTime)%60);
  371. timeline_duration_time.innerHTML=parseInt(audio.duration/60)+':'+(parseInt(audio.duration)%60<10?'0'+parseInt(audio.duration)%60:parseInt(audio.duration)%60);
  372. }
  373. })
  374. audio.addEventListener('error',function(){
  375. var context;
  376. switch (audio.error.code){
  377. case 1:
  378. context='MEDIA_ERR_ABORTED(文件在取回时被用户中止)';
  379. break;
  380. case 2:
  381. context='MEDIA_ERR_NETWORK(文件在下载时发生错误)';
  382. break;
  383. case 3:
  384. context='MEDIA_ERR_DECODE(文件在解码时发生错误)';
  385. break;
  386. case 4:
  387. context='MEDIA_ERR_SRC_NOT_SUPPORTED(不支持的音频格式)';
  388. break;
  389. default:
  390. context='MEDIA_ERR_UNKNOWN(未知错误,错误代码:'+audio.error.code+')';
  391. }
  392. switch (audio.networkState){
  393. case 0:
  394. context+='<br>NETWORK_EMPTY(音频尚未初始化)';
  395. break;
  396. case 1:
  397. context+='<br>NETWORK_IDLE(音频已缓存)';
  398. break;
  399. case 2:
  400. context+='<br>NETWORK_LOADING(浏览器正在下载数据)';
  401. break;
  402. case 3:
  403. context+='<br>NETWORK_NO_SOURCE(未找到音频来源)';
  404. break;
  405. default:
  406. context+='<br>NETWORK_UNKNOWN(未知错误,错误代码:'+audio.error.code+')';
  407. }
  408. update_error('audio',context);
  409. audio_play();
  410. })
  411. audio.addEventListener('ended',function(){
  412. if(next==0)update_log();
  413. else next=0;
  414. audio_play();
  415. })
  416. cover_preload.addEventListener('load',function(){
  417. cover.style.backgroundImage='url('+playlist[count].cover.large+')';
  418. cover_loading_notification.style.opacity=0;
  419. })
  420. cover_preload.addEventListener('error',function(){
  421. if(cover_retry<3){
  422. update_error('cover','正在重试加载......');
  423. cover_preload.src=playlist[count].cover.large;
  424. cover_retry++;
  425. }
  426. else{
  427. update_error('cover','超过最大重新加载次数限制');
  428. cover_retry=0;
  429. }
  430. })
  431. c_play.addEventListener('click',function(){audio.play();})
  432. c_pause.addEventListener('click',function(){audio.pause();})
  433. c_previous.addEventListener('click',function(){
  434. if(count>0){
  435. next=1;
  436. count-=2;
  437. audio_play();
  438. }
  439. })
  440. c_next.addEventListener('click',function(){
  441. next=1;
  442. audio_play();
  443. })
  444. c_like.addEventListener('click',function(){
  445. if(c_like.hasAttribute('meow')){
  446. update_fav(1,1);
  447. }
  448. else{
  449. update_fav(1,0);
  450. }
  451. })
  452. c_dislike.addEventListener('click',function(){
  453. if(c_dislike.hasAttribute('meow')){
  454. update_fav(2,1);
  455. }
  456. else{
  457. update_fav(2,0);
  458. }
  459. })
  460. c_volume_icon.addEventListener('click',function(){
  461. if(c_volume_range.hasAttribute('disabled')){
  462. c_volume_range.removeAttribute('disabled');
  463. c_volume_range.style.opacity=1;
  464. audio.volume=volume/100;
  465. update_volume_icon(volume);
  466. }
  467. else{
  468. volume=audio.volume*100;
  469. c_volume_icon.innerHTML='静';
  470. c_volume_range.setAttribute('disabled','disabled');
  471. c_volume_range.style.opacity=0.75;
  472. audio.volume=0;
  473. }
  474. })
  475. c_volume_range.addEventListener('change',function(){
  476. volume=c_volume_range.value;
  477. audio.volume=volume/100;
  478. update_volume_icon(volume);
  479. setting.volume=volume;
  480. localStorage.setItem('moefm-html5-setting',JSON.stringify(setting));
  481. })
  482. c_share.addEventListener('click',function(){share();})
  483. timeline.addEventListener('mouseup',function(event){
  484. audio.currentTime=(event.clientX/document.body.clientWidth)*audio.duration;
  485. })
  486. aside_album.addEventListener('click',function(){p=0;update_playlist('fav=music');})
  487. aside_song.addEventListener('click',function(){p=0;update_playlist('fav=song');})
  488. aside_radio.addEventListener('click',function(){p=0;update_playlist('fav=radio');})
  489. aside_random.addEventListener('click',function(){p=0;url_data=null;update_playlist();})
  490. background_preload.addEventListener('load',function(){document.documentElement.style.backgroundImage='url('+background_preload.src+')';})
  491. background_preload.addEventListener('error',function(){
  492. update_error('background','获取图片时发生错误');
  493. update_background();
  494. })
  495. link_setting_background.addEventListener('click',function(){
  496. var div=document.createElement('div'),
  497. div2=document.createElement('div'),
  498. t=document.createElement('textarea'),
  499. b=document.createElement('button');
  500. div.className='setting_background_panel';
  501. div2.className='setting_background_panel_background';
  502. div2.title='点击黑色区域以退出';
  503. b.innerHTML='确定';
  504. t.setAttribute('title','请在文本框内输入图片地址,以回车间隔,一行一个');
  505. t.setAttribute('autofocus','autofocus');
  506. div.appendChild(t);
  507. div.appendChild(b);
  508. if(background_list.length!=0)t.value=background_list.join('\n');
  509. document.body.appendChild(div);
  510. document.body.appendChild(div2);
  511. div2.addEventListener('click',function(){
  512. div.parentElement.removeChild(div);
  513. div2.parentElement.removeChild(div2);
  514. })
  515. b.addEventListener('click',function(){
  516. var l=t.value.split('\n'),
  517. r=[];
  518. for(var i=0;i<l.length;i++){
  519. if(l!='')r.push(l[i]);
  520. }
  521. background_list=r;
  522. div2.click();
  523. update_background();
  524. setting.background=r;
  525. localStorage.setItem('moefm-html5-setting',JSON.stringify(setting));
  526. })
  527. })
  528.  
  529. if(location.search.indexOf('song')>=0)update_playlist(location.search.match(/song=[0-9,]*/)[0]);
  530. else if(location.search.indexOf('music')>=0)update_playlist(location.search.match(/music=[0-9,]*/)[0]);
  531. else if(location.search.indexOf('radio')>=0)update_playlist(location.search.match(/radio=[0-9,]*/)[0]);
  532. else update_playlist();
  533. c_volume_range.value=volume;
  534. audio.volume=volume/100;
  535. update_volume_icon(volume);
  536. update_background();
  537. update_background_count(1);
  538. window.addEventListener('keydown',function(e){
  539. switch(e.keyCode){
  540. case 32:
  541. audio.paused==false?audio.pause():audio.play();
  542. break;
  543. case 39:
  544. next=1;
  545. audio_play();
  546. break;
  547. case 38:
  548. c_like.click();
  549. break;
  550. case 40:
  551. c_dislike.click();
  552. break;
  553. case 37:
  554. next=1;
  555. count-=2;
  556. audio_play();
  557. break;
  558. }
  559. })
  560. window.addEventListener('focus',function(){
  561. update_background_count(1);
  562. })
  563. window.addEventListener('blur',function(){
  564. update_background_count(0);
  565. })
  566.  
  567. if(typeof is_login!='undefined'&&is_login==true){
  568. var user_btn=document.createElement('span');
  569. user_btn.innerHTML=user;
  570. user_btn.className='link_right_user_btn';
  571. link_right_user.appendChild(user_btn);
  572. var user_pan=document.createElement('div');
  573. user_pan.innerHTML=user_panel;
  574. user_pan.style.cssText='position:fixed;background:rgba(0,0,0,0.5);bottom:0px;right:10px;opacity:0';
  575. user_pan.setAttribute('hidden','hidden');
  576. user_btn.appendChild(user_pan);
  577. user_btn.addEventListener('mouseover',function(){
  578. user_pan.removeAttribute('hidden');
  579. user_pan.style.opacity=1;
  580. user_pan.style.bottom='20px';
  581. })
  582. user_btn.addEventListener('mouseout',function(){
  583. user_pan.setAttribute('hidden','hidden');
  584. user_pan.style.opacity=0;
  585. user_pan.style.bottom='0px';
  586. })
  587. }
  588. else{
  589. link_right_user.innerHTML='<a class="right" target="_blank" href="http://moefou.org/register?redirect=http%3A%2F%2Fmoe.fm%2Flogin">注册</a><a class="right" href="http://moe.fm/login">登入</a>';
  590. document.getElementsByTagName('aside')[0].setAttribute('hidden','hidden');
  591. }