网易云歌词解析(配合audio标签实现本地歌曲播放,歌词同步)

本文展示了如何利用JavaScript解析网易云歌词,并结合audio标签实现本地歌曲播放时的歌词同步。通过创建Lyric类并调用getCurPlayLyric方法,可以轻松获取当前播放时间对应的歌词内容。
摘要由CSDN通过智能技术生成

先看下效果

github上做的一个音乐播放器: https://github.com/SorrowX/electron-music

中文歌曲

英文歌曲(如果有翻译的中文给回返回出去)

韩文歌曲

来看下解析歌词的类

class Lyric {
            constructor(data) {
                this.data = data
                this.lrc = data['lrc']['lyric']
                this.tlyric = data['tlyric']['lyric']

                this.lrcMap = this.getLyricMap(this.lrc)
                this.finalLrcMap = this.convertProp(Object.assign({}, this.lrcMap))

                this.tlyricMap = this.getLyricMap(this.tlyric)
                this.finalTlyricMap = this.convertProp(Object.assign({}, this.tlyricMap))
            }

            getLyricMap(lrc) {
                let key, value, sIdx, eIdx, nsIdx
                let ret = {}
                if (!lrc || (typeof lrc !== 'string')) return ret

                while(lrc) {
                    sIdx = lrc.indexOf('[')
                    eIdx = lrc.indexOf(']') + 1
                    if (sIdx !== -1 && eIdx !== -1) {
                        key = lrc.slice(sIdx, eIdx)
                        advance(eIdx)
                        nsIdx = lrc.indexOf('[')
                        value = lrc.slice(0, nsIdx)
                        ret[key] = value.trim()
                        advance(nsIdx)
                    } else {
                        break
                    }
                }

                function advance (n) {
                    lrc = lrc.substring(n)
                }
                return ret
            }

            convertProp(obj) {
                Object.keys(obj).forEach((str) => {
                    if (!obj[str]) {
                        delete obj[str]
                    } else {
                        let prop = f(str)
                        obj[prop] = obj[str]
                        delete obj[str]
                    }
                })

                function f(str) {
                    str = str.match(/^\[(\d+):(\d+)\.(\d+)/)
                    return Number(str[1]) * 60 * 1000 +  Number(str[2]) * 1000 +  Number(str[3])
                }
                return obj
            }

            getCurPlayLyric(audioCurTime) {
                let audioCurTimeMs = audioCurTime * 1000
                let arrTime = Object.keys(this.finalLrcMap)
                
                let i = 0, len = arrTime.length, idx
                let hasTranslate = Object.keys(this.finalTlyricMap).length > 0

                if (audioCurTimeMs === 0) {
                    return g.call(this, arrTime[0])
                }
                if (audioCurTimeMs >= Number(arrTime[len - 1])) {
                    return g.call(this, arrTime[len - 1])
                }
                for (; i < len; i++) {
                    if (
                        audioCurTimeMs >= Number(arrTime[i - 1]) && 
                        audioCurTimeMs < Number(arrTime[i])
                    ) {
                        idx = i - 1
                        break
                    }
                }
                return g.call(this, arrTime[idx])

                function g(prop) {
                    return hasTranslate 
                        ? v(this.finalLrcMap[prop]) + ('\n') + v(this.finalTlyricMap[prop])
                        : v(this.finalLrcMap[prop])
                }
                function v(val) {
                    return typeof val === 'undefined' ? '' : val
                }
            }
        }

使用姿势超级简单
new Lyric(data)
data就是歌词文件中的对象
使用实例 getCurPlayLyric 方法就ok,参数为 audio.currentTime 单位秒 时间

看下完整demo

let arrData = [
    {
        "sgc":false,
        "sfy":false,
        "qfy":false,
        "path": "D:\\SorrowX\\2018\\xhl-live-01\\trunk\\web-page\\歌词\\十年.mp3",
        "name": "十年",
        "lrc":{
            "version":4,
            "lyric":`[00:00.00] 作曲 : 陈小霞
                [00:01.00] 作词 : 林夕
                [00:03.700]编曲:唐汉霄
                [00:
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值