微信小程序播放音乐并同步一次显示一行歌词

您所在的位置:网站首页 微信小程序的音乐怎么关教程功能 微信小程序播放音乐并同步一次显示一行歌词

微信小程序播放音乐并同步一次显示一行歌词

2024-07-03 15:30:08| 来源: 网络整理| 查看: 265

主要是对于歌词部分的描述 gitee项目仓库地址 https://gitee.com/manster1231/master-cloud-music(点个star哦!)

1.总体思路 先在加载页面时异步获取歌词,根据 musicId 我们可以获取到该歌曲的歌词对歌词进行切分并以对象的形式放入数组中,将每个时间段获得的歌词存起来方便页面渲染判定该显示那句歌词。将歌词数组进行遍历,如果当前歌曲播放时间等于歌词数组中歌词的时间,就将当前歌词换为这一句;这样当改到下一句时就会等到上一句完全唱完再进行切换

直接看效果

播放样例

2.详细分析

先在加载页面时异步获取歌词,根据 musicId 我们可以获取到该歌曲的歌词

//获取歌词 async getLyric(musicId){ let lyricData = await request("/lyric", {id: musicId}); let lyric = this.formatLyric(lyricData.lrc.lyric); },

我可以得到的歌词样式 http://localhost:3000/lyric?id=1815684465

{ "lrc": { "version": 7, "lyric": "[00:00.000] 作词 : TetraCalyx\n[00:01.000] 作曲 : 蔡近翰Zoe(HOYO-MiX)\n[00:02.000] 编曲 : 宫奇Gon(HOYO-MiX)/杨启翔Frex(HOYO-MiX)\n[00:03.08]Life blooms like a flower\n[00:07.00]far away or by the road\n[00:10.15]waiting for the one\n[00:13.22]to find the way back home\n[00:17.15]Rain falls a thousand times\n[00:21.02]No footprints of come-and-go\n[00:24.14]You who once went by\n[00:28.05]where will you belong\n[00:30.10]I feel your sigh and breath\n[00:33.24]In the last blow of wind\n[00:38.08]Not yet for the story on the last page\n[00:42.18]It's not the end\n[00:45.17]Life blooms like a flower\n[00:49.07]far away or by the road\n[00:52.23]waiting for the one\n[00:56.04]to find the way back home\n[00:59.22]Time flows across the world\n[01:03.09]There is always a longer way to go\n[01:07.21]Till I reach your arms\n[01:10.07]a Madder there for you\n[01:13.24]Up against the stream\n[01:17.15]waterways will join as one\n[01:21.00]Tracing to the source\n[01:24.17]No more strayed or lost\n[01:26.22]You will see petals fly\n[01:30.10]when lament becomes carol\n[01:34.19]Could you please hear my voice\n[01:37.11]that hungers for a duo\n[01:43.69]Life blooms like a flower\n[01:45.18]far away or by the road\n[01:49.08]waiting for the one\n[01:52.16]to find the way back home\n[01:56.09]Time flows across the world\n[01:59.21]There is always a longer way to go\n[02:04.08]Till I reach your arms\n[02:06.19]a Madder there for you\n[02:37.00]Life blooms like a flower\n[02:40.11]far away or by the road\n[02:44.01]waiting for the one\n[02:47.08]to find the way back home\n[02:51.00]Time flows across the world\n[02:54.15]There is always a longer way to go\n[02:59.01]Till I reach your arms\n[03:01.11]a Madder there for you\n[03:03.720] 人声录音 Recording:徐威Aaron Xu\n[03:06.429] 混音/母带 Mixing&Mastering Engineer:宫奇Gon(HOYO-MiX)\n[03:09.138] 制作人 Producer:蔡近翰Zoe(HOYO-MiX)\n[03:11.847] 特别鸣谢 Special Thanks:周深工作室\n[03:14.556] 出品 Produced by:HOYO-MiX\n" } }

但是歌词只是文本,我们需要将其进行切割,并以对象的形式放入数组中,将每个时间段获得的歌词存起来方便页面渲染

首先我们以换行符进行切分 \n ,切分后数组元素为 [00:00.000] 作词 : TetraCalyx然后我们再以 ] 进行切分,我们可以得到 [00:00.000 和 作词 : TetraCalyx,对这个数组使用 pop() 方法可以得到 作词 : TetraCalyx 这样的歌词了然后我们就需要获取歌词对应出现的时间了 通过 element.substr(1, element.length - 1) 我们可以得到 00:00.000然后我们再使用 split(":") 就可以得到分钟和秒的时间(即 00 和 00.000)然后我们在使其转换为以秒作单位的时间,parseInt(time_arr[0]) * 60 + Math.ceil(time_arr[1]);,为了方便计算我们就不计秒的小数点以后的时间了,直接使用整秒最后我们将歌词与秒当做一个对象,传到我们的歌词对象数组中 //传入初始歌词文本text formatLyric(text) { let result = []; let arr = text.split("\n"); //原歌词文本已经换好行了方便很多,我们直接通过换行符“\n”进行切割 let row = arr.length; //获取歌词行数 for (let i = 0; i let obj = {}; let time_arr = element.substr(1, element.length - 1).split(":");//先把多余的“[”去掉,再分离出分、秒 let s = parseInt(time_arr[0]) * 60 + Math.ceil(time_arr[1]); //把时间转换成与currentTime相同的类型,方便待会实现滚动效果 obj.time = s; obj.text = text; result.push(obj); //每一行歌词对象存到组件的lyric歌词属性里 }); } result.sort(this.sortRule) //由于不同时间的相同歌词我们给排到一起了,所以这里要以时间顺序重新排列一下 this.setData({ lyric: result }) },

其中我们需要按照歌词出现的时间来进行排序

sortRule(a, b) { //设置一下排序规则 return a.time - b.time; },

现在我们的数组中的数据就变成了一个一个的对象

lyric[ { text: " 作词 : TetraCalyx", time: 0 }, { text: " 作曲 : 蔡近翰Zoe(HOYO-MiX)", time: 1 }, { text: " 编曲 : 宫奇Gon(HOYO-MiX)/杨启翔Frex(HOYO-MiX)", time: 2 }, { text: "Life blooms like a flower", time: 4 }, { text: "far away or by the road", time: 7 }, { text: "waiting for the one", time: 11 },{ text: "to find the way back home", time: 14 }, ... ] 判定该显示哪句歌词。将歌词数组进行遍历,如果当前歌曲播放时间等于歌词数组中歌词的时间,就将当前歌词换为这一句;这样当该到下一句时就会等到上一句完全唱完再进行切换 //控制歌词播放 getCurrentLyric(){ let j; for(j=0; j this.setData({ currentLyric : this.data.lyric[j].text }) } } },

songDetail.wxml

{{currentLyric}}

songDetail.wxss

/* 歌词显示 */ .scrollLrc { position: absolute; bottom: 280rpx; width: 640rpx; height: 120rpx; line-height: 120rpx; text-align: center; }

songDetail.js

首先增加了 lyric: [] 用来存放所有的歌词对象(以 {time:0, text:'歌词'} 的形式)

然后增加 lyricTime 来对歌曲进行与歌词一样样式的时间来方便进行判断,单位为秒

然后每次对 currentLyric 进行操作,放边 wxml 渲染歌词

data: { isPlay: false,//标识播放状态 song: {},//歌曲详情对象 musicId: '',//歌曲Id currentTime: '00:00',//当前时长 durationTime:'00:00',//总时长 currentWidth: 0,//实时进度条宽度 lyric: [],//歌词 lyricTime: 0,//歌词对应的时间 currentLyric: "",//当前歌词对象 }, onLoad: function (options) { this.getLyric(musicId); //音乐播放自然结束 this.backgroundAudioManager.onEnded(()=>{ //切歌 PubSub.publish('switchMusic','next'); this.setData({ currentWidth: 0, currentTime: '00:00', lyric: 0, lyricTime: 0, }) }) //监听音乐实时播放的进度 this.backgroundAudioManager.onTimeUpdate(() => { let lyricTime = Math.ceil(this.backgroundAudioManager.currentTime);//获取歌词对应时间 let currentTime = moment(this.backgroundAudioManager.currentTime * 1000).format('mm:ss'); let currentWidth = (this.backgroundAudioManager.currentTime/this.backgroundAudioManager.duration) * 450; this.setData({ lyricTime, currentTime, currentWidth }) //跟随歌曲播放进度来进行歌词的调控 this.getCurrentLyric(); }) }, //获取歌词 async getLyric(musicId){ let lyricData = await request("/lyric", {id: musicId}); let lyric = this.formatLyric(lyricData.lrc.lyric);//存储整理好的歌词对象 }, //传入初始歌词文本text对歌词进行处理 formatLyric(text) { let result = []; let arr = text.split("\n"); //原歌词文本已经换好行了方便很多,我们直接通过换行符“\n”进行切割 let row = arr.length; //获取歌词行数 for (let i = 0; i let obj = {}; let time_arr = element.substr(1, element.length - 1).split(":");//先把多余的“[”去掉,再分离出分、秒 let s = parseInt(time_arr[0]) * 60 + Math.ceil(time_arr[1]); //把时间转换成与currentTime相同的类型,方便待会实现滚动效果 obj.time = s; obj.text = text; result.push(obj); //每一行歌词对象存到组件的lyric歌词属性里 }); } result.sort(this.sortRule) //由于不同时间的相同歌词我们给排到一起了,所以这里要以时间顺序重新排列一下 this.setData({ lyric: result }) }, sortRule(a, b) { //设置一下排序规则 return a.time - b.time; }, //控制歌词播放 getCurrentLyric(){ let j; for(j=0; j this.setData({ currentLyric : this.data.lyric[j].text }) } } }, 3.所有代码 songDetail.wxml {{song.ar[0].name}}


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭