A modified version of a good lrc player.

本文介绍了一个适用于周杰伦歌曲《霍元甲》的LRC歌词播放器,该播放器由李国强设计并经Stefli改进,能够显示多达8行歌词,支持HTML与JavaScript实现歌词与音乐同步播放。
This is a good lrc player which is designed by 李国强.
There is a requirement in csdn forum that somebody wants to modify this program,then it can show 8 lines lrc in the player.So i just make a little modification of it.

the latest version is in the http://www.stefli.com/

The source code as below:
  1. <!DOCTYPE html PUBLIC "-///www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  5. <title>播放器字幕类</title>
  6. </head>
  7. <style>
  8. #my div{font-size:20px;font-family:"楷体_GB2312"; white-space: pre;}
  9. </style>
  10. <body>
  11. <span id="lrcdata">
  12. <!--
  13. [ti:霍元甲]
  14. [ar:周杰伦]
  15. [al:SBLXK]
  16. [00:55]吓命有几回合擂台等着
  17. [00:57]生死状赢了什么冷笑着
  18. [00:59]天下谁的第一又如何止
  19. [01:02]干戈我辈尚武德
  20. [01:04]我的拳脚了得
  21. [01:06]却奈何徒增虚名一个
  22. [01:09]江湖难测谁是强者
  23. [01:11]谁争一统武林的资格
  24. [01:14]小城里岁月流过去
  25. [01:18]清澈的勇气
  26. [01:22]洗涤过的回忆
  27. [01:25]我记得你
  28. [01:28]骄傲的活下去
  29. [01:34]霍霍霍霍霍霍霍霍
  30. [01:35]霍家拳的套路招式灵活
  31. [01:38]我我我我我我我
  32. [01:40]我活着生命就该完整渡过
  33. [01:43]我我我我我我我
  34. [01:45]我过错软弱从来不属于我
  35. [01:48]霍霍霍霍霍霍霍霍
  36. [01:50]我们精武出手无人能躲
  37. [01:57]吓命有几回合擂台等着
  38. [02:04]生死状赢了什么冷笑着
  39. [02:08]天下谁的第一又如何止
  40. [02:10]干戈我辈尚武德
  41. [02:13]我的拳脚了得
  42. [02:15]却奈何徒增虚名一个
  43. [02:17]江湖难测谁是强者
  44. [02:19]谁争一统武林的资格
  45. [02:22]小城里岁月流过去
  46. [02:27]清澈的勇气
  47. [02:31]洗涤过的回忆
  48. [02:33]我记得你
  49. [02:36]骄傲的活下去
  50. [02:42]霍霍霍霍霍霍霍霍
  51. [02:44]霍家拳的套路招式灵活
  52. [02:46]我我我我我我我
  53. [02:49]我活着生命就该完整渡过
  54. [02:51]我我我我我我我
  55. [02:54]我过错软弱从来不属于我
  56. [02:56]霍霍霍霍霍霍霍霍
  57. [02:58]我们精武出手无人能躲
  58. [03:04]music
  59. [03:31]霍霍霍霍霍霍霍霍
  60. [03:33]霍家拳的套路招式灵活
  61. [03:35]我我我我我我我
  62. [03:38]我活着生命就该完整渡过
  63. [03:40]我我我我我我我
  64. [03:43]我过错软弱从来不属于我
  65. [03:45]霍霍霍霍霍霍霍霍
  66. [03:47]我们精武出手无人能躲
  67. [03:50]霍霍霍霍霍霍霍霍
  68. [03:53]霍家拳的套路招式灵活
  69. [03:55]我我我我我我我
  70. [03:57]我活着生命就该完整渡过
  71. [04:00]我我我我我我我
  72. [04:02]我过错软弱从来不属于我
  73. [04:04]霍霍霍霍霍霍霍霍
  74. [04:07]我们精武出手无人能躲
  75. [04:14]李国强制作(end) Stefli稍作改动
  76. [04:33]谢谢使用-->
  77. </span>
  78. <object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6" id="mediaPlayerObj" 
  79.   width="330" height="68">
  80.     <param name="url" value="http://p1.5nd.com/20060919/2006/Z/20061234871621/48717941.wma">
  81.     <param name="rate" value="1">
  82.     <param name="balance" value="0">
  83.     <param name="currentPosition" value="0">
  84.     <param name="playCount" value="1">
  85.     <param name="autoStart" value="-1">
  86.     <param name="volume" value="100">
  87.     <param name="currentMarker" value="0">
  88.     <param name="invokeURLs" value="-1">
  89.     <param name="stretchToFit" value="-1">
  90.     <param name="windowlessVideo" value="0">
  91.     <param name="enabled" value="-1">
  92.     <param name="enableContextMenu" value="0">
  93.     <param name="fullScreen" value="0">
  94.     <param name="enableErrorDialogs" value="0">
  95. </object>
  96.     </p>
  97. <div style="white-space: pre; width:322px; height: 200px; background: #000; padding: 4px;" id="my"></div>
  98. <pre id="msg">
  99. </pre>
  100. <script language="javascript">
  101. /*=============================================================
  102. 入口参数说明:
  103.  1.lrc歌词
  104.  2.歌词显示所需的容器,CSS字体、字号同时应用于字幕
  105.  3.播放器的ID
  106.  4.字幕本底色
  107.  5.字幕同步色
  108. ===============================================================*/
  109. function LRC(s,divo2,m_id,c1,c2)
  110. {

  111.     LrcT=new Array();
  112.     this.msg="";
  113.     this.END=false;
  114.     function FormatLrcText(s)
  115.     {
  116.         var s1="";
  117.         ss=s.replace(/<[^<>]+/:[^<>]+>/g,"");//暂时不支持尖括号的歌词
  118.         var ss2=s.replace(//[[^/[/]]+/:[^/[/]]+/]/g,"");
  119.         while(//[[^/[/]]+/:[^/[/]]+/]/.test(s))//拆分成多行歌词
  120.         {
  121.             ss=s.replace(/(/[[^/[/]]+/:[^/[/]]+/])(.*)/,"$2");
  122.             s1+=RegExp.$1+s2+"/n"
  123.         }
  124.         return s1;
  125.     }
  126.     function delnotes(s)        ////删除注释
  127.     {
  128.         ss=s.replace(//[/:/][^$/n]*(/n|$)/g,"$1");
  129.         ss=s.replace(//[[^/[/]]*/]/g,function(s){return (/^/[[/d/:/.]+/]$/.test(s))?s:"";});
  130.         return s.replace(/<[^<>]*>/g,function(s){return (/^<[/d/:/.]+>$/.test(s))?s:""});
  131.     }
  132.     function addLrcObj(s)
  133.     {
  134.         var msg="歌手:~1~<br>曲名:~2~<br>专辑:~3~<br>编者:~4~";;
  135.         msgmsg = msg.replace("~1~",(//[ar:([^/[/]:]+)/]/i.test(s))?RegExp.$1:"----");
  136.         msgmsg = msg.replace("~2~",(//[ti:([^/[/]:]+)/]/i.test(s))?RegExp.$1:"----");
  137.         msgmsg = msg.replace("~3~",(//[al:([^/[/]:]+)/]/i.test(s))?RegExp.$1:"----");
  138.         msgmsg = msg.replace("~4~",(//[by:([^/[/]:]+)/]/i.test(s))?RegExp.$1:"----");
  139.         var oTime=0;
  140.         if(//[offset/:(/-?/d+)/]/i.test(s))        ////取offset余补时间
  141.         oTime = RegExp.$1/1000;
  142.         s=delnotes(s)//删除注释
  143.         ss=s.replace(//[[^/[/]]+/:[^/[/]]+/]+.*[/n/x0d/x0a]*/g,FormatLrcText);//拆分多重[]行
  144.         var tmp=//[(/d+)/:([/d/.]+)/](.*)/;
  145.         while(tmp.test(s))//压入歌词对象数组
  146.         {
  147.             ss=s.replace(tmp,"/n");
  148.             LrcT[LrcT.length]={time:parseInt(RegExp.$1,10)*60+parseFloat(RegExp.$2)-oTime,text:RegExp.$3.toString()};
  149.         }
  150.         LrcT[LrcT.length]={time:10000,text:"无歌词"};
  151.         LrcTLrcT=LrcT.sort(function(a1,a2){return a1.time-a2.time;});////排序
  152.         return msg;
  153.     }
  154.     this.ShowObjInit=  function ()
  155.     {
  156.         var top,bk,showLeft,ShowLength;
  157.         var s="<div style=/"position: absolute; z-index:53 ;overflow-y :hidden ;overflow-x:hidden;color:#ffffff;filter : Glow(Color=#ff00ff,Strength=2) Chroma(color=#ff00ff);/" id=/"showIdText/"><//div>";
  158.         s+="<div style=/"position: absolute; z-index:51;overflow-y :hidden ;overflow-x:hidden;white-space: pre;color:"+c1+"/" id=/"showIdBack/"><//div>";
  159.         s+="<div style=/"position: absolute; z-index: 52;overflow-y :hidden ; overflow-x:hidden;white-space: pre;filter : Glow(Color='red',Strength='3');color:"+c2+"/" id=/"showIdTextBottom/"><//div>";
  160.         s+="<div style=/"position: absolute; visibility:hidden;z-index: 50;/" id=/"showIdTmp/"><//div>";
  161.         document.getElementById(divo2).style.whiteSpace="pre";
  162.         document.getElementById(divo2).innerHTML=s;
  163.     }
  164.     this.ShowObjInit();//初始化显示控件
  165.     this.msg=addLrcObj(s);//构造歌词数组
  166.     var MediaObj=document.getElementById(m_id);
  167.     var CurIndex=1;//当前行索引
  168.     if(LrcT.length>1)setText();
  169.     var ol=LrcT.length-1;
  170.     var lrcTextWidth=0;
  171.     function setText()
  172.     {
  173.         var lrc="";
  174.         for(var i=0;i<7;i++) {
  175.             if(CurIndex+i>LrcT.length-1) {
  176.                 break;
  177.             } else {
  178.                 lrc+="<br/>" + LrcT[CurIndex+i].text;
  179.             }
  180.         }
  181.         document.getElementById("showIdText").innerHTML=LrcT[CurIndex-1].text + lrc;
  182.         document.getElementById("showIdTextBottom").innerHTML=LrcT[CurIndex-1].text;
  183.         document.getElementById("showIdBack").innerHTML=LrcT[CurIndex-1].text;
  184.         document.getElementById("showIdTmp").innerHTML=LrcT[CurIndex-1].text;
  185.         lrcTextWidth=parseInt(document.getElementById("showIdTmp").offsetWidth);
  186.         lrcTextWidthlrcTextWidth=lrcTextWidth/(LrcT[CurIndex].time-LrcT[CurIndex-1].time);
  187.     }
  188.     this.run = function()
  189.     {

  190.         var CurTime=MediaObj.controls.currentPosition;
  191.         var l;
  192.         while(CurTime<LrcT[CurIndex-1].time && CurIndex>1)
  193.         {
  194.             CurIndex--;
  195.             setText();
  196.         }
  197.         while(CurTime>LrcT[CurIndex].time)
  198.         {
  199.             if( CurIndex<ol)
  200.             {
  201.                 CurIndex++;
  202.                 setText();
  203.             }
  204.             else
  205.             {
  206.                 this.END=true;
  207.             }
  208.         }
  209.         l=Math.round(lrcTextWidth*(CurTime-LrcT[CurIndex-1].time));
  210.         if(l>=0)document.getElementById("showIdTextBottom").style.width=l;
  211.     }
  212.     this.newLrc=function(ss)
  213.     {
  214.             LrcT.splice(0,LrcT.length);
  215.             this.msg=addLrcObj(ss);
  216.             CurIndex=1;
  217.             setText();
  218.             ol=LrcT.length-1;
  219.             lrcTextWidth=0;
  220.             this.END=false;
  221.             return this.msg;
  222.     }

  223. }
  224. /////////////////////////////////////////////////////////////////////////////////////////////////////

  225. document.body.onload=function(){
  226.      oo=new LRC(lrcdata.innerHTML.slice(4,-3),"my","mediaPlayerObj","#ff00ff","#00ffff");
  227.     setInterval('oo.run();if(oo.END)alert("end");',30);

  228. }
  229. </script>
  230. </body>
  231. </html>

这种情况下可以合并了吗? git status On branch lqn/feat/aio-v1.0-device All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: ../../../../../.env modified: ../../../../../omada-central-env.config.js modified: ../../../../../package.json modified: ../../../../../pnpm-lock.yaml modified: ../../../../../rsbuild.config.ts modified: ../../../../api/auth.ts modified: ../../../../api/video.ts modified: ../../../../assets/icons/package-near-expire.svg modified: ../../../../components/AppAiFreeTrial.vue modified: ../../../../components/eptz/Index.vue modified: ../../../../components/live/PreviewPlayer.vue modified: ../../../../components/live/use-live-tool.ts modified: ../../../../components/navigator/Index.vue new file: ../../../../config-env/common-util.ts modified: ../../../../config-env/index.ts new file: ../../../../config-env/log/index.ts new file: ../../../../config-env/nav/index.ts modified: ../../../../config-env/system-settings/index.ts modified: ../../../../config-env/user/index.ts modified: ../../../../config-env/video/index.ts modified: ../../../../constants/custom-role.ts new file: ../../../../constants/errors/device.ts new file: ../../../../constants/errors/index.ts new file: ../../../../constants/errors/player.ts modified: ../../../../constants/navigator.ts modified: ../../../../hooks/use-preview.ts modified: ../../../../i18n/locales/en_US.json modified: ../../../../index.ts modified: ../../../../player/interface.ts modified: ../../../../player/media-player.ts modified: ../../../../player/plugins/instances/timeline/TimeSpanSlider.vue modified: ../../../../player/preview/preview-player.ts new file: ../../../../player/stream/base.ts new file: ../../../../player/stream/direct-stream.ts new file: ../../../../player/stream/https-relay-stream.ts new file: ../../../../player/stream/index.ts new file: ../../../../player/stream/local-media-stream.ts new file: ../../../../player/stream/multipart-conversion.ts new file: ../../../../player/stream/p2p-stream.ts new file: ../../../../player/stream/racing-stream.ts new file: ../../../../player/stream/relay-stream-base.ts new file: ../../../../player/stream/relay-stream.ts modified: ../../../../store/modules/auth.ts modified: ../../../../styles/application/var.less modified: ../../../../utils/device-pre-connect.ts modified: ../../../../utils/rsa-encode.ts modified: ../../../../utils/video.ts modified: ../../../account-settings/uid-account/Index.vue modified: ../../../auth/login-redirect/uid-cloud-redirect/Index.vue modified: ../../Index.vue modified: ../../ai-search/face/hooks/use-face.ts modified: ../../ai-search/hooks/use-first-empty-guide.ts modified: ../../ai-search/hooks/utils.ts modified: ../../ai-search/human/const.ts modified: ../../ai-search/human/hooks/use-human.ts modified: ../../ai-search/vehicle/hooks/use-vehicle.ts modified: ../../alarm/events/components/event-menu/Recipients.vue modified: ../../alarm/events/custom-alerts/custom-alerts-content/Index.vue modified: ../../alarm/events/device-event/Index.vue modified: ../../billing-account/order-history/Index.vue modified: ../../billing-account/order-history/hooks/use-order.ts modified: ../../components/video-batch-select/Index.vue modified: ../../dashboard/line-chart/hooks/use-line.ts modified: ../components/delete-device-modal/delete-aio-device/Index.vue modified: ../components/delete-device-modal/delete-device-ability.ts modified: ../components/device.less modified: ../components/edit-device-nvr/Index.vue modified: ../components/edit-device-nvr/alarm-info/hotzone-detection/use-device.ts modified: ../components/edit-device-nvr/alarm-info/pet-detection/Index.vue modified: ../components/edit-device-nvr/alarm-info/pet-detection/use-pet-detection.ts modified: ../components/edit-device-nvr/camera-info/device-access/use-table.ts modified: ../components/edit-device-nvr/storage-info/array-management/AddHarddriveModal.vue modified: ../components/edit-device-nvr/storage-info/array-management/CreateRAIDModal.vue modified: ../components/edit-device-nvr/storage-info/array-management/CreateRAIDOnceModal.vue modified: ../components/edit-device-nvr/storage-info/array-management/EditRAIDModal.vue modified: ../components/edit-device-nvr/storage-info/array-management/Index.vue modified: ../components/edit-device-nvr/storage-info/recording-manager/hooks/constants.ts modified: ../components/edit-device-nvr/storage-info/recording-manager/hooks/use-columns.tsx modified: ../components/edit-device-nvr/storage-info/storage-manager/components/storage-status/Index.vue modified: ../components/edit-device-nvr/storage-info/storage-manager/components/storage-status/hooks/use-storage-status.ts modified: ../components/edit-device/Index.vue modified: ../components/edit-device/cloud-storage/Index.vue modified: ../components/edit-device/network-settings/ddns/Index.vue modified: ../components/edit-device/network-settings/ddns/hooks/useAction.ts modified: ../components/edit-device/smart-analysis/people-counting/use-device.ts modified: ../components/edit-device/smart-event/pet-detection/Index.vue modified: ../components/edit-device/smart-event/pet-detection/use-pet-detection.ts modified: ../components/edit-device/smart-event/queue-detection/use-queue-detection.ts modified: ../components/edit-device/system-manager/capture-management/Index.vue modified: ../components/edit-device/system-manager/certificate-management/Index.vue modified: ../components/edit-solar-drawer/Index.vue modified: ../components/information-display/components/IpcInformation.vue modified: ../components/local-upgrade/Index.vue modified: Index.vue modified: components/TableFilter.vue modified: ../hooks/use-columns-cloud.tsx modified: ../hooks/use-columns-local.tsx modified: ../../license/license-manage/Index.vue modified: ../../log/components/SystemTable.vue modified: ../../log/hooks/system-table/use-log.ts modified: ../../map/device-map/components/LiveViewList.vue modified: ../../organization/hooks/index.ts deleted: ../../organization/hooks/use-actions.ts modified: ../../passenger-flow/components/passenger-flow-quick-settings/components/SingleLiveView.vue modified: ../../plan/Index.vue modified: ../../rules/event-rules/Index.vue modified: ../../rules/event-rules/hooks/use-actions.tsx modified: ../../rules/event-rules/hooks/use-event-rule.tsx modified: ../../system-setting/Index.vue modified: ../../user/ReinviteIcon.vue modified: ../../video/video-common/VideoToolTip.vue modified: ../../video/video-common/use-get-videoInfo.ts modified: ../../video/video-surveillance/component/time-span/Index.vue modified: ../../video/video-surveillance/hooks/utils.ts modified: ../../video/video-surveillance/live-view/Index.vue modified: ../../video/video-surveillance/live-view/hooks/preview-port.ts modified: ../../video/video-surveillance/live-view/plugins/ratio.vue modified: ../../video/video-surveillance/playback/Playback.vue modified: ../../video/video-surveillance/playback/event/hook/use-image-cloud.ts modified: ../../video/video-surveillance/playback/main/const/playback-player.ts new file: ../../video/video-surveillance/playback/main/const/retry-white-list.ts modified: ../../video/video-surveillance/playback/main/error-hander/use-playback-error.ts modified: ../../video/video-surveillance/playback/main/playback-manage.ts modified: ../../video/video-surveillance/playback/main/playback-player/device-player.ts modified: ../../video/video-surveillance/playback/main/playback-player/hooks/use-decryption.ts Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) deleted: ../components/add-device-modal/transfer/transfer.d.ts Untracked files: (use "git add <file>..." to include in what will be committed) ../../../../../dist.7z
最新发布
11-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值