lrc.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. var url = audio.currentSrc;
  164. var urlArr = url.split('?');
  165. var k = urlArr[0],
  166. appU = k.split('/');
  167. var srcFileExt = appU[appU.length - 1].split('.')[1];
  168. url = url.replace("." + srcFileExt, ".lrc");
  169. var url = "http://122.114.50.251:8010/getJSON.php?callback=?&url=" + (url);
  170. var $container = $('#lyriccontainer');
  171. var noSleep = new NoSleep();
  172. var enableNoSleep = false;
  173. var btn_lyricFullscreen = document.getElementById("lyricFullscreen");
  174. if (btn_lyricFullscreen) {
  175. btn_lyricFullscreen.addEventListener('click',
  176. function(event) {
  177. var element = $container[0];
  178. audio.play();
  179. // 判断浏览器前缀
  180. if (document.fullscreenEnabled) {
  181. if (element.requestFullscreen) {
  182. element.requestFullscreen();
  183. } else if (element.mozRequestFullScreen) {
  184. element.mozRequestFullScreen();
  185. } else if (element.webkitRequestFullscreen) {
  186. element.webkitRequestFullscreen();
  187. } else if (element.msRequestFullscreen) {
  188. element.msRequestFullscreen();
  189. }
  190. }
  191. });
  192. }
  193. // 监听全屏事件触发
  194. var fullscreenchange = function() {
  195. let isFullScreen = !!(
  196. document.fullscreen ||
  197. document.mozFullScreen ||
  198. document.webkitIsFullScreen ||
  199. document.webkitFullScreen ||
  200. document.msFullScreen
  201. );
  202. if (isFullScreen) {
  203. if(!enableNoSleep){noSleep.enable();}
  204. enableNoSleep = true;
  205. } else {
  206. if(enableNoSleep){noSleep.disable();}
  207. enableNoSleep = false;
  208. }
  209. if(enableNoSleep){
  210. $("#lyricSleep").prop("checked",true);
  211. }
  212. else{
  213. $("#lyricSleep").prop("checked",false);
  214. }
  215. };
  216. ['fullscreenchange','webkitfullscreenchange','mozfullscreenchange'].forEach((item,index) => {
  217. $container[0].addEventListener(item, () => fullscreenchange());
  218. });
  219. $.getJSON(url,
  220. function(data) {
  221. var lrcContent = data.data;
  222. if (!lrcContent || lrcContent == "") {
  223. return;
  224. }
  225. //用于显示歌词的容器对象,样式自己定义
  226. $container.jqlyric({
  227. lyric: lrcContent,
  228. // 歌词字符串,标准lrc文件格式
  229. getPosition: fun_getPosition
  230. });
  231. });
  232. var btn_lyricBigger = document.getElementById("lyricBigger");
  233. //调节字体大小
  234. var adjustFontSize = function (sizeOffset){
  235. var size = getComputedStyle($('#lyriccontainer')[0], false)['font-size'];
  236. var num = parseInt(size.substring(0, size.indexOf("px")));
  237. num += sizeOffset;
  238. var unit = "px";
  239. size = num + unit;
  240. $('#lyriccontainer')[0].style.fontSize = size;
  241. };
  242. if (btn_lyricBigger) {
  243. btn_lyricBigger.addEventListener('click',
  244. function() {
  245. adjustFontSize(2);
  246. },
  247. false);
  248. }
  249. var btn_lyricSmaller = document.getElementById("lyricSmaller");
  250. if (btn_lyricSmaller) {
  251. btn_lyricSmaller.addEventListener('click',
  252. function() {
  253. adjustFontSize(-2);
  254. },
  255. false);
  256. }
  257. var chk_lyricSleep = document.getElementById("lyricSleep");
  258. if (chk_lyricSleep) {
  259. chk_lyricSleep.addEventListener('change',
  260. function(event) {
  261. let isCheck = event.srcElement.checked;
  262. if (isCheck) {
  263. if(!enableNoSleep){noSleep.enable();}
  264. enableNoSleep = true;
  265. } else {
  266. if(enableNoSleep){noSleep.disable();}
  267. enableNoSleep = false;
  268. }
  269. });
  270. }
  271. });