lrc.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* ===================================================
  2. * jqlyric.js v0.1
  3. * shawnk@qq.com
  4. * 使用方法
  5. * var $container=$('#lyriccontainer'); //用于显示歌词的容器对象,样式自己定义
  6. * $container.jqlyric({
  7. * lyric:'\
  8. [ti:存在] \
  9. [ar:汪峰] \
  10. [al:存在] \
  11. [by:Love] \
  12. [00:00.00]汪峰 - 存在 \
  13. [00:00.68]多少人走着却困在原地 \
  14. [00:07.93]多少人活着却如同死去', // 歌词字符串,标准lrc文件格式
  15. * speed:1000, // 歌词滚动间隔 (毫秒)
  16. * getPosition:function(){ // 获取当前播放位置的函数(返回秒数), 请定义外部函数,不指定本参数则默认从调用插件开始自动播放
  17. * return position;
  18. * }
  19. * });
  20. * ===================================================
  21. *
  22. * Licensed under the Apache License, Version 2.0 (the "License");
  23. * you may not use this file except in compliance with the License.
  24. * You may obtain a copy of the License at
  25. *
  26. * http://www.apache.org/licenses/LICENSE-2.0
  27. *
  28. * Unless required by applicable law or agreed to in writing, software
  29. * distributed under the License is distributed on an "AS IS" BASIS,
  30. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  31. * See the License for the specific language governing permissions and
  32. * limitations under the License.
  33. * ========================================================== */
  34. (function($) {
  35. var gtime = 0;
  36. var lyric_listener;
  37. $.fn.jqlyric = function(options) {
  38. var opts = $.extend({},
  39. $.fn.jqlyric.defaults, options);
  40. return this.each(function() {
  41. var o = $.meta ? $.extend({},
  42. opts, $this.data()) : opts;
  43. var $this = $(this);
  44. var arrLyric = new Array(); //放存汉字的歌词
  45. var arrTime = new Array(); //存放时间
  46. var currentLine = 0; //当前活动的歌词行号
  47. // 开始解析歌词
  48. //将歌词解析成数组
  49. var arrly = o.lyric.split('\n');
  50. for (var i = 0; i < arrly.length; i++) {
  51. var str = arrly[i];
  52. str = str.substring(str.indexOf("[") + 1, str.indexOf("]"));
  53. if (str.indexOf('ti:') > -1 || str.indexOf('ar:') > -1 || str.indexOf('al:') > -1 || str.indexOf('by:') > -1) {
  54. // 歌曲特征字段
  55. var tmp = str.substring(str.indexOf(':') + 1);
  56. var text = tmp;
  57. //tag=tag.replace(/([ti|ar|al|by])/g,'');
  58. //arrLyric.push(tag+text);
  59. //arrTime.push(toSeconds('00:00:00')); //
  60. } else {
  61. var text = arrly[i].substring(arrly[i].indexOf("]") + 1);
  62. //if(text==''){text='&nbsp;';}
  63. arrLyric.push(text); //放歌词
  64. arrTime.push(toSeconds(str)); //放时间
  65. }
  66. }
  67. // 所有歌词按时间顺序排列
  68. for (var k = 0; k < arrTime.length; k++) {
  69. for (var j = 0; j < arrTime.length - k; j++) {
  70. if (arrTime[j] > arrTime[j + 1]) {
  71. temp = arrTime[j];
  72. arrTime[j] = arrTime[j + 1];
  73. arrTime[j + 1] = temp;
  74. temp = arrLyric[j];
  75. arrLyric[j] = arrLyric[j + 1];
  76. arrLyric[j + 1] = temp;
  77. }
  78. }
  79. }
  80. // 所有歌词封装成歌词对象
  81. var arrLyricObj = new Array();
  82. for (var k = 0; k < arrTime.length; k++) {
  83. var lrcContent = arrLyric[k];
  84. var len = lrcContent.replace(/(^s*)|(s*$)/g, "").length;
  85. if (!lrcContent || len == 0) {
  86. continue;
  87. }
  88. var timeStart = arrTime[k];
  89. var timeEnd = k < arrTime.length - 1 ? arrTime[k + 1] - 0.01 : 99999999999999;
  90. if (timeEnd < 0) {
  91. continue;
  92. }
  93. var lrc = {
  94. timeStart: timeStart,
  95. timeEnd: timeEnd,
  96. lrcContent: lrcContent
  97. };
  98. arrLyricObj.push(lrc);
  99. }
  100. // 显示歌词
  101. var displayLine = function(lineID,num){
  102. var lc = arrLyricObj[num].lrcContent.split("<br/>");
  103. $(lineID+" span:eq(0)").text(lc[0]);
  104. if (lc.length > 1) {
  105. $(lineID+" span:eq(1)").text(lc[1]);
  106. }
  107. if (lc.length > 2) {
  108. $(lineID+" span:eq(2)").text(lc[2]);
  109. }
  110. $(lineID).attr("currentLine", num);
  111. };
  112. clearTimeout(lyric_listener);
  113. var timeFun = function() { // 定时检查当前播放进度,作出滚动动作
  114. var pos = o.getPosition();
  115. for (var k = 0; k < arrLyricObj.length; k++) {
  116. if (pos >= arrLyricObj[k].timeStart && pos <= arrLyricObj[k].timeEnd) {
  117. if ($("#line-current").attr("currentLine") != k) {
  118. if (k > 0) {
  119. displayLine("#line-last",k-1);
  120. }
  121. if (k < arrTime.length - 1) {
  122. displayLine("#line-next",k+1);
  123. }
  124. displayLine("#line-current",k);
  125. break;
  126. }
  127. }
  128. }
  129. lyric_listener = setTimeout(timeFun, o.speed);
  130. };
  131. lyric_listener = setTimeout(timeFun, o.speed);
  132. });
  133. };
  134. $.fn.jqlyric.defaults = {
  135. lyric: '[00:00.00]未找到歌词',
  136. // 歌词字符串 (lrc格式)
  137. speed: 500,
  138. // 歌词进度一首歌间隔(毫秒)
  139. getPosition: function() { // 获取播放器当前播放位置
  140. gtime += 0.5;
  141. return gtime;
  142. }
  143. }
  144. function toSeconds(t) { //把形如:01:25的时间转化成秒;
  145. var m = t.substring(0, t.indexOf(":"));
  146. var s = t.substring(t.indexOf(":") + 1);
  147. s = parseInt(s.replace(/\b(0+)/gi, ""));
  148. if (isNaN(s)) s = 0;
  149. var totalt = parseInt(m) * 60 + s;
  150. //alert(parseInt(s.replace(/\b(0+)/gi,"")));
  151. if (isNaN(totalt)) return 0;
  152. return totalt;
  153. }
  154. })(jQuery);
  155. $(function() {
  156. var audio = document.getElementById("audio");
  157. if (!audio) {
  158. return;
  159. }
  160. var fun_getPosition = function() {
  161. return audio.currentTime;
  162. }
  163. audio.onerror = audio.onabort = audio.onstalled = function(m) {
  164. layer.msg('播放器发生错误:'+m.type,{
  165. type: 1,
  166. title: false,
  167. shade:0,
  168. offset:'b',
  169. time:8000
  170. });
  171. };
  172. var url = audio.currentSrc;
  173. var urlArr = url.split('?');
  174. var k = urlArr[0],
  175. appU = k.split('/');
  176. var srcFileExt = appU[appU.length - 1].split('.')[1];
  177. url = url.replace("." + srcFileExt, ".lrc");
  178. var url = "http://122.114.50.251:8010/getJSON.php?callback=?&url=" + (url);
  179. var $container = $('#lyriccontainer');
  180. var noSleep = new NoSleep();
  181. var enableNoSleep = false;
  182. var isFullScreen = false;
  183. var btn_lyricFullscreen = document.getElementById("lyricFullscreen");
  184. if (btn_lyricFullscreen) {
  185. btn_lyricFullscreen.addEventListener('click',
  186. function(event) {
  187. var element = $container[0];
  188. audio.play();
  189. // 判断浏览器前缀
  190. if (document.fullscreenEnabled) {
  191. if($(btn_lyricFullscreen).html()=='全屏播放'){
  192. if (element.requestFullscreen) {
  193. element.requestFullscreen();
  194. } else if (element.mozRequestFullScreen) {
  195. element.mozRequestFullScreen();
  196. } else if (element.webkitRequestFullscreen) {
  197. element.webkitRequestFullscreen();
  198. } else if (element.msRequestFullscreen) {
  199. element.msRequestFullscreen();
  200. }
  201. }else{
  202. document.exitFullscreen();
  203. }
  204. }
  205. });
  206. }
  207. // 监听全屏事件触发
  208. var fullscreenchange = function() {
  209. isFullScreen = !!(
  210. document.fullscreen ||
  211. document.mozFullScreen ||
  212. document.webkitIsFullScreen ||
  213. document.webkitFullScreen ||
  214. document.msFullScreen
  215. );
  216. if (isFullScreen) {
  217. if(!enableNoSleep){noSleep.enable();}
  218. $(btn_lyricFullscreen).html('退出全屏');
  219. enableNoSleep = true;
  220. } else {
  221. if(enableNoSleep){noSleep.disable();}
  222. $(btn_lyricFullscreen).html('全屏播放');
  223. enableNoSleep = false;
  224. }
  225. $("#lyricSleep").prop("checked",enableNoSleep);
  226. };
  227. ['fullscreenchange','webkitfullscreenchange','mozfullscreenchange'].forEach((item,index) => {
  228. $container[0].addEventListener(item, () => fullscreenchange());
  229. });
  230. $.getJSON(url,
  231. function(data) {
  232. var lrcContent = data.data;
  233. if (!lrcContent || lrcContent == "") {
  234. return;
  235. }
  236. //用于显示歌词的容器对象,样式自己定义
  237. $container.jqlyric({
  238. lyric: lrcContent,
  239. // 歌词字符串,标准lrc文件格式
  240. getPosition: fun_getPosition
  241. });
  242. });
  243. var btn_lyricBigger = document.getElementById("lyricBigger");
  244. //调节字体大小
  245. var adjustFontSize = function (sizeOffset){
  246. var size='',num=0;
  247. if(isFullScreen){
  248. var styleStr=($('#lyriccontainer').attr("style")+"");
  249. var styleArr=$.map(styleStr.split(";"),function(node){
  250. var returnNode=node;
  251. if(node.indexOf("--full-font-size")>-1){
  252. num = $.trim(node.split(":")[1]);
  253. var unit = "vmin";
  254. num = parseFloat(num.substring(0,num.indexOf(unit)));
  255. num += sizeOffset;
  256. size = num + unit;
  257. returnNode="--full-font-size:"+size;
  258. }
  259. return returnNode;
  260. });
  261. $('#lyriccontainer').attr("style",styleArr.join(";"));
  262. }else{
  263. var styleStr=($('#lyriccontainer').attr("style")+"");
  264. var styleArr=$.map(styleStr.split(";"),function(node){
  265. var returnNode=node;
  266. if(node.indexOf("--default-font-size")>-1){
  267. num = $.trim(node.split(":")[1]);
  268. var unit = "rem";
  269. num = parseFloat(num.substring(0,num.indexOf(unit)));
  270. num += sizeOffset;
  271. size = num + unit;
  272. returnNode="--default-font-size:"+size;
  273. }
  274. return returnNode;
  275. });
  276. $('#lyriccontainer').attr("style",styleArr.join(";"));
  277. }
  278. };
  279. if (btn_lyricBigger) {
  280. btn_lyricBigger.addEventListener('click',
  281. function() {
  282. adjustFontSize(1);
  283. },
  284. false);
  285. }
  286. var btn_lyricSmaller = document.getElementById("lyricSmaller");
  287. if (btn_lyricSmaller) {
  288. btn_lyricSmaller.addEventListener('click',
  289. function() {
  290. adjustFontSize(-1);
  291. },
  292. false);
  293. }
  294. var chk_lyricSleep = document.getElementById("lyricSleep");
  295. if (chk_lyricSleep) {
  296. chk_lyricSleep.addEventListener('change',
  297. function(event) {
  298. let isCheck = event.srcElement.checked;
  299. if (isCheck) {
  300. if(!enableNoSleep){noSleep.enable();}
  301. enableNoSleep = true;
  302. } else {
  303. if(enableNoSleep){noSleep.disable();}
  304. enableNoSleep = false;
  305. }
  306. });
  307. }
  308. });