JavaScript-歌词展示与音乐同步

目录

一、歌词数据

1、歌词加载

2、把歌词解析为JS对象

3、把搜集好的歌词信息,展示到页面上

4、整体代码

二、歌词与音乐同步

1、歌词和音乐展示

2、歌词和音乐同步,当前行高亮,随播放滚动

三、最终代码


一、歌词数据

1、歌词加载

我的歌词格式

 使用ajax加载歌词

 	$.ajax({
		type: "get",
		url: "http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=440613&httpsStatus=1",
		success: function(result) {
			//JSON格式的字符串,反序列化成一个JavaScript对象
			lrc = JSON.parse(result);
			console.log(lrc);//打印
		}
	});

2、把歌词解析为JS对象

	var oLRC = {
		offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置
		ms: [] //歌词数组{t:时间,c:歌词}
	};

	function createLrcObj(lrc) {
		var lrc = lrc.data.lrclist;//获取到歌词集合部分,lrclist

		for(var k in lrc) { //遍历lrc 对象的每个key/value对,k为key
			oLRC.ms.push({  //把歌曲信息放入oLRC中
				t: lrc[k].time,
				c: lrc[k].lineLyric
			});
		}
		//console.log(oLRC);
	}
	
    oLRC.ms.sort(function (a, b) {//按时间顺序排序
        return a.t-b.t;
    });

 3、把搜集好的歌词信息,展示到页面上

在页面定义一个div,用于展示

<ul id="lyric"></ul>

歌词遍历,加工成标签,展示到页面

function showLRC() {
    var s="";
    for(var i in oLRC.ms){//遍历ms数组,把歌词加入列表
        s+='<li>'+oLRC.ms[i].c+'</li>';
    }
    document.getElementById("lyric").innerHTML = s;
}

4、整体代码

<html>
	<head>
		<meta charset="UTF-8">
		<title>歌词展示</title>
		<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
		<script>
			$.ajax({
				type: "get",
				url: "http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=440613&httpsStatus=1",
				success: function(result) {
					//JSON格式的字符串,反序列化成一个JavaScript对象
					var lrc = JSON.parse(result);
					//获取歌词部分
					createLrcObj(lrc)
					//展示歌词
					showLRC()
				}
			});

			var oLRC = {
				offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置
				ms: [] //歌词数组{t:时间,c:歌词}
			};

			function createLrcObj(lrc) {
				var lrc = lrc.data.lrclist; //获取到歌词集合部分
				//console.log(lrc);
				for(var k in lrc) { //遍历packJson 对象的每个key/value对,k为key
					//console.log(lrc[k].lineLyric +" "+lrc[k].time )
					oLRC.ms.push({
						t: lrc[k].time,
						c: lrc[k].lineLyric
					});
				}
				console.log(oLRC);
			}

			function showLRC() {
				var s = "";
				for(var i in oLRC.ms) { //遍历ms数组,把歌词加入列表
					s += '<li>' + oLRC.ms[i].c + '</li>';
				}
				document.getElementById("lyric").innerHTML = s;
			}
		</script>
	</head>

	<body>
		<ul id="lyric"></ul>
	</body>

</html>

效果展示:

 

二、歌词与音乐同步

1、歌词和音乐展示

body中主代码

<div class="lyric_area">
	<!-- 歌词 -->
	<ul id="lyric"></ul>
</div>
<!-- 音频 -->
<audio id="bfq" src="http://win.web.ra01.sycdn.kuwo.cn/db5492f42d356582d32ea37f4757f7a4/63352e7d/resource/n3/320/74/27/4113470514.mp3" controls preload="auto" style="position: fixed;left: 42%;top: 22%;" /><br/>

css 样式

<style>
	/*歌词样式*/
	.lyric_area {
		/*歌词区域高度*/
		height: 150px;
		/*隐藏超出部分*/
		overflow: hidden;
		margin-top: 15px;
		text-align: center;
	}
	/*歌词列表*/
	#lyric {
		/*行高,这个值要用在歌词滚动距离上*/
		line-height: 20px;
		/*滚动速度*/
		transition-duration: 600ms;
	}
	
	#lyric .lineHigh {
		/*高亮行*/
		color: #17e883;
	}
	
	#lyric li {
		list-style-type: none;
		/* 去除实心圆 */
	}
</style>

页面整体效果:

 

2、歌词和音乐同步,当前行高亮,随播放滚动

	/* 播放音乐时让当前行高亮显示并向上滚动 */
	var lineNo = 0; //当前行
	var C_pos = 3; //C位 
	var offset = -20; //滚动距离(应等于行高)
	var audio = document.getElementById("bfq"); //播放器
	var ul = document.getElementById("lyric"); //歌词容器列表

	//高亮显示歌词当前行及文字滚动控制,行号为lineNo
	function lineHigh() {
		var lis = ul.getElementsByTagName("li"); //歌词数组
		if(lineNo > 0) {
			lis[lineNo - 1].removeAttribute("class"); //去掉上一行的高亮样式
		}
		lis[lineNo].className = "lineHigh"; //高亮显示当前行

		//文字滚动
		if(lineNo > C_pos) {
			ul.style.transform = "translateY(" + (lineNo - C_pos) * offset + "px)"; //整体向上滚动一行高度
		}
	}

	//滚回到开头,用于播放结束时
	function goback() {
		document.querySelector("#lyric .lineHigh").removeAttribute("class");
		ul.style.transform = "translateY(0)";
		lineNo = 0;
	}

	//监听播放器的timeupdate事件,实现文字与音频播放同步(正常播放 )
	audio.ontimeupdate = function() {
		if(lineNo == oLRC.ms.length)
			return;
		var curTime = audio.currentTime; //播放器时间
		if(parseFloat(oLRC.ms[lineNo].t) <= curTime) {
			lineHigh(); //高亮当前行
			lineNo++;
		}
	};

	//跳跃播放时,歌词回滚到对应位置
	audio.onseeked = function() {
		var curTime = audio.currentTime; //播放器时间
		for(i = 0; i < oLRC.ms.length; i++) {
			if(oLRC.ms[i].t <= curTime) { /*播放器往回拖*/
				if(i == oLRC.ms.length - 1) { //歌词已经播放完,只剩音乐,直接跳到最后一句歌词
					lineNo = i; //需要高亮的行
					break;
				}
				if(oLRC.ms[i + 1].t < curTime) { //如果前一个时间也小于播放器时间,就继续循环
					continue;
				} else {
					if(i < C_pos * 2) { //当前行,小于最初展示的数据,直接跳到展示到开头
						ul.style.transform = "translateY(0)";
					}
					lineNo = i; //需要高亮的行
					break;
				}
				/*播放器往前拖*/
			} else {
				lineNo = i; //需要高亮的行
				break;
			}
		}
		document.querySelector("#lyric .lineHigh").removeAttribute("class"); //消除之前的高亮
		lineHigh(); //高亮当前行
	};

	//监听播放器的ended事件,播放结束时回滚歌词
	audio.onended = function() {
		goback(); //回滚歌词
	};

三、最终代码

<html>

	<head>
		<meta charset="UTF-8">
		<title>歌词展示</title>
		<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
		<script>
			$.ajax({
				type: "get",
				url: "http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=440613&httpsStatus=1",
				success: function(result) {
					//JSON格式的字符串,反序列化成一个JavaScript对象
					var lrc = JSON.parse(result);
					//获取歌词部分
					createLrcObj(lrc);
					//展示歌词
					showLRC();
				}
			});

			var oLRC = {
				offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置
				ms: [] //歌词数组{t:时间,c:歌词}
			};

			function createLrcObj(lrc) {
				var lrc = lrc.data.lrclist; //获取到歌词集合部分
				//console.log(lrc);
				for(var k in lrc) { //遍历packJson 对象的每个key/value对,k为key
					//console.log(lrc[k].lineLyric +" "+lrc[k].time )
					oLRC.ms.push({
						t: lrc[k].time,
						c: lrc[k].lineLyric
					});
				}
				//console.log(oLRC);
			}

			function showLRC() {
				var s = "";
				for(var i in oLRC.ms) { //遍历ms数组,把歌词加入列表
					s += '<li>' + oLRC.ms[i].c + '</li>';
				}
				document.getElementById("lyric").innerHTML = s;
			}
		</script>
		<style>
			/*歌词样式*/
			
			.lyric_area {
				/*歌词区域高度*/
				height: 150px;
				/*隐藏超出部分*/
				overflow: hidden;
				margin-top: 15px;
				text-align: center;
			}
			/*歌词列表*/
			
			#lyric {
				/*行高,这个值要用在歌词滚动距离上*/
				line-height: 20px;
				/*滚动速度*/
				transition-duration: 600ms;
			}
			
			#lyric .lineHigh {
				/*高亮行*/
				color: #17e883;
			}
			
			#lyric li {
				list-style-type: none;
				/* 去除实心圆 */
			}
		</style>
	</head>

	<body>
		<div class="lyric_area">
			<!-- 歌词 -->
			<ul id="lyric"></ul>
		</div>
		<!-- 音频 -->
		<audio id="bfq" src="http://win.web.ra01.sycdn.kuwo.cn/db5492f42d356582d32ea37f4757f7a4/63352e7d/resource/n3/320/74/27/4113470514.mp3" controls preload="auto" style="position: fixed;left: 42%;top: 22%;" /><br/>

	</body>
	<script>
		/* 播放音乐时让当前行高亮显示并向上滚动 */
		var lineNo = 0; //当前行
		var C_pos = 3; //C位 
		var offset = -20; //滚动距离(应等于行高)
		var audio = document.getElementById("bfq"); //播放器
		var ul = document.getElementById("lyric"); //歌词容器列表

		//高亮显示歌词当前行及文字滚动控制,行号为lineNo
		function lineHigh() {
			var lis = ul.getElementsByTagName("li"); //歌词数组
			if(lineNo > 0) {
				lis[lineNo - 1].removeAttribute("class"); //去掉上一行的高亮样式
			}
			lis[lineNo].className = "lineHigh"; //高亮显示当前行

			//文字滚动
			if(lineNo > C_pos) {
				ul.style.transform = "translateY(" + (lineNo - C_pos) * offset + "px)"; //整体向上滚动一行高度
			}
		}

		//滚回到开头,用于播放结束时
		function goback() {
			document.querySelector("#lyric .lineHigh").removeAttribute("class");
			ul.style.transform = "translateY(0)";
			lineNo = 0;
		}

		//监听播放器的timeupdate事件,实现文字与音频播放同步(正常播放 )
		audio.ontimeupdate = function() {
			if(lineNo == oLRC.ms.length)
				return;
			var curTime = audio.currentTime; //播放器时间
			if(parseFloat(oLRC.ms[lineNo].t) <= curTime) {
				lineHigh(); //高亮当前行
				lineNo++;
			}
		};

		//跳跃播放时,歌词回滚到对应位置
		audio.onseeked = function() {
			var curTime = audio.currentTime; //播放器时间
			for(i = 0; i < oLRC.ms.length; i++) {
				if(oLRC.ms[i].t <= curTime) { /*播放器往回拖*/
					if(i == oLRC.ms.length - 1) { //歌词已经播放完,只剩音乐,直接跳到最后一句歌词
						lineNo = i; //需要高亮的行
						break;
					}
					if(oLRC.ms[i + 1].t < curTime) { //如果前一个时间也小于播放器时间,就继续循环
						continue;
					} else {
						if(i < C_pos * 2) { //当前行,小于最初展示的数据,直接跳到展示到开头
							ul.style.transform = "translateY(0)";
						}
						lineNo = i; //需要高亮的行
						break;
					}
					/*播放器往前拖*/
				} else {
					lineNo = i; //需要高亮的行
					break;
				}
			}
			document.querySelector("#lyric .lineHigh").removeAttribute("class"); //消除之前的高亮
			lineHigh(); //高亮当前行
		};

		//监听播放器的ended事件,播放结束时回滚歌词
		audio.onended = function() {
			goback(); //回滚歌词
		};
	</script>

</html>

效果展示:

感谢博主:fenglin247 【分享的知识】

参考资料:用JS实现歌词与播放音乐同步_fenglin247的博客-CSDN博客_js歌词

 

 

 

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白要努力变黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值