首页 > 其他分享 >JS实现播放音乐时歌词同步展示

JS实现播放音乐时歌词同步展示

时间:2023-08-15 22:55:06浏览次数:39  
标签:lyrics currentTime text 歌词 JS let time 播放

效果如下:

实现过程:

监听音频播放时间,使用歌词的出现时间与其比较,展示对应时间歌词内容,代码如下

<audio id="audio-player" src="每个眼神都只身荒野.m4a" controls></audio>

<div class="lyrics-container">
    <div id="lyrics"></div>
</div>

<script>
    document.addEventListener('DOMContentLoaded', function() {
        var audio = document.getElementById('audio-player');
        var lyricsContainer = document.getElementById('lyrics');

        // 歌词内容与时间
        var lyrics = [
            { time: 3, text: "在每个眼神都只身荒野那瞬间" },
            { time: 10, text: "你和我面对面如此地安慰" },
            { time: 18, text: "如果我能发现" },
            { time: 22, text: "动情的灵魂终将在前夜告别" },
            { time: 26, text: "我也不愿停下仅有时间" },
            { time: 29, text: "让我忘了我是谁" },
            // 歌词时间和文本继续添加
        ];

        // 更新歌词
        function updateLyrics(currentTime) {
            for (var i = 0; i < lyrics.length; i++) {
                if (currentTime >= lyrics[i].time && (!lyrics[i + 1] || currentTime < lyrics[i + 1].time)) {
                    lyricsContainer.innerText = lyrics[i].text;
                    break;
                }
            }
        }

        // 监听频播放时间更新事件
        audio.addEventListener('timeupdate', function() {
            var currentTime = audio.currentTime;
            updateLyrics(currentTime);
        });
    });
</script>

这样将歌词在js里面固定了,可以将歌词抽出成一个Irc文件,将该文件放在服务器上面,使其能用http访问到。

同时在js中获取Irc文件的内容,并沿用上面的实现,整个html文件如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Music歌词同步展示</title>
    <style>
        .lyrics-container {
            text-align: left;
            height: 30px;
        }

        #lyrics {
            margin-top: 5px;
            font-size: 20px;
            line-height: 1.5;
        }
    </style>
</head>
<body>
<audio id="audio-player" src="http://服务器IP/每个眼神都只身荒野.m4a" controls></audio>

<div class="lyrics-container">
    <div id="lyrics" src="http://服务器IP/每个眼神都只身荒野.lrc"></div>
</div>

<script>
    let audio = document.getElementById('audio-player');
    let lyricsContainer = document.getElementById('lyrics');
    let lyricsPath = lyricsContainer.getAttribute('src');
    console.log(lyricsPath);

    // 创建一个空数组来存储歌词数据
    let ircArray = [];
    // 匹配时间和文本的正则表达式模式
    const pattern = /\[(\d+:\d+.\d+)\](.+)/g;

    document.addEventListener('DOMContentLoaded', function() {
        // 更新展示的歌词
        function updateLyrics(currentTime) {
            for (var i = 0; i < ircArray.length; i++) {
                if (currentTime >= ircArray[i].time && (!ircArray[i + 1] || currentTime < ircArray[i + 1].time)) {
                    lyricsContainer.innerText = ircArray[i].text;
                    break;
                }
            }
        }

        // 监听频播放时间更新事件
        audio.addEventListener('timeupdate', function() {
            var currentTime = audio.currentTime;
            updateLyrics(currentTime);
        });
    });

    const xhr = new XMLHttpRequest();
    xhr.open('GET', lyricsPath);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === XMLHttpRequest.DONE) {
            if (xhr.status === 200) {
                console.log(xhr.responseText);
                // 在数据中匹配正则表达式模式并提取时间和文本
                let match;
                while ((match = pattern.exec(xhr.responseText)) !== null) {
                    let time = match[1]; // 获取时间
                    let text = match[2]; // 获取文本

                    // 将时间转换为秒数,格式为 mm:ss.xxxx
                    let [minutes, seconds] = time.split(':');
                    let [secondsPart, milliseconds] = seconds.split('.');
                    let timeInSeconds = parseInt(minutes) * 60 + parseInt(secondsPart) + parseFloat(`0.${milliseconds}`);

                    // 创建包含 time 和 text 属性的对象
                    let ircObject = {
                        time: timeInSeconds,
                        text: text
                    };

                    // 将对象添加到数组中
                    ircArray.push(ircObject);
                }
                console.log(ircArray); // 在请求成功且数据处理完毕后打印数组内容
            } else {
                // 处理错误
                console.error('请求出错:', xhr.status);
            }
        }
    };
    xhr.send();

</script>

</body>
</html>

 

TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
  TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back

标签:lyrics,currentTime,text,歌词,JS,let,time,播放
From: https://www.cnblogs.com/xiaomaju/p/17630903.html

相关文章

  • JScript 操作文本文件 练习代码
     varTextStream=function(){this.handle=null;this.create=function(filename,overwrite){varfso=newActiveXObject("scripting.filesystemobject");this.handle=fso.CreateTextFile(filename,overwrite);}th......
  • next.js 源码解析 - getStaticProps、getStaticPaths 篇
    ......
  • @JsonComponent注解自定义JSON序列化与反序列化
    1.概述本篇教程将聚焦于如何使用SpringBoot中的@JsonComponent通过使用这个注解,我们不需要手动引用ObjectMapper对象就可以将一个类暴露为Jackson的serializer与deserializer。由于这是SpringBoot提供的功能,所以我们不需要添加额外的依赖,我们可以直接在SpringBoot程序中使用它......
  • vue.js框架的iframe页面计时器无法销毁的解决方法
    同学试过使用生命周期等方式都不能清除计时器;因而改用这个方法;1,首先vue页面上随便写个有高度的div如下:用refs获取高度<divclass="hub-fixed-box":style="{width:fixedWidth+'px'}"ref="fixedTop"></div>2.定时器定义在data内data:{timer:null,//计时器}3,初始......
  • JSCRIPT连接ado
    //JavaScriptsourcecode//JScriptsourcecodevarconsole={log:function(txt){WScript.Echo(txt);}}functionRecordset(h){this.commandText="";this.activeConnection=null;this.handle=h;this.open=fun......
  • 在Angular项目中如何读取json文件呢?
    直接进入主题,我们的最终目得是要读取文件,那么首先我们需要先创建文件,第一步:创建我们今天所需要在assets创建需要读取的文件Message.json,如下:[{"id":"E0001","msg":"{0}の取得に失敗しました。"},{"id":"E0002",&quo......
  • [LitCTF 2023]1zjs
    [LitCTF2023]1zjs题目来源:nssctf题目类型:web涉及考点:信息搜集1.题目给了一个魔方游戏,检查源代码:在/dist/index.umd.js里发现线索:直接访问看看:经查询发现是JSFuck编码,特征为[]+!(),对其解码得到:将[]去掉即可得到flag:NSSCTF{11c9e8fe-03f7-4bc1-bfed-b8277cd55964}......
  • 国标GB28181视频平台EasyGBS视频监控平台无法播放,抓包返回ICMP排查过程
    国标GB28181视频平台EasyGBS是基于国标GB/T28181协议的行业内安防视频流媒体能力平台,可实现的视频功能包括:实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。国标GB28181视频监控平台部署简单、可拓展性强,支持将接入的视频流进行全终端、全平台分发,分发......
  • JS逆向实战21——某查查webpack密码加密
    声明本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!网站aHR0cHM6Ly93d3cucWNjLmNvbS8=前言阅读前请先阅读下我的另一篇文章看看别的webpack打包的网站......
  • Asp.net WebAPI中Controller的方法在接受到json时序列化都为null的问题
    原因是,webapi默认不序列化字段,只序列化属性只需要把字段改成属性即可 ------------------改成---------------- ......