JavaScript实现视频播放器
实现效果如下
音乐播放器
准备工作
代码模块
1. index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>音乐播放器</title>
<link rel="shortcut icon" href="./assets/icon.jpg" type="image/x-icon" />
<link rel="stylesheet" href="./assets/index.css" />
</head>
<body>
<div class="contain">
<audio src="./assets/爱要坦荡荡.mp3" controls></audio>
<div class="music-contain">
<ul></ul>
</div>
<script src="./js/lrc.js"></script>
<script src="./js/index.js"></script>
</div>
</body>
</html>
2. index.css
* {
margin: 0;
padding: 0;
}
body {
color: #fff;
text-align: center;
background-color: black;
}
.contain {
height: 500px;
width: 50%;
margin: 20px auto;
}
.contain audio {
width: 80%;
margin: 20px;
}
.contain .music-contain {
height: 450px;
overflow: hidden;
}
.music-contain ul {
transition: 0.5s;
list-style: none;
}
.music-contain li {
height: 30px;
line-height: 30px;
transition: 0.5s;
}
.music-contain li.active {
color: aqua;
transform: scale(1.5);
}
3. lrc.js 歌词数据
//歌词滚动
var lrc = `[00:00.000] 作词 : 许常德
[00:00.017] 作曲 : Rungroth Pholwa
[00:00.34]Da La La La…
[00:17.04]天色是有点暗
[00:18.81]气氛是有点蓝
[00:20.81]皎洁的月光显得特别亮
[00:24.59]对白是很简单
[00:26.63]像是精致装扮
[00:28.29]显得通俗不堪
[00:32.39]你不必太紧张
[00:34.29]诚实会有点难
[00:36.25]也许完美对我反而是假象
[00:40.15]过去我不想谈
[00:42.10]有缺憾也无妨
[00:43.83]我要你的自然
[00:47.67]爱要坦荡荡
[00:51.03]不要装模作样到天长
[00:55.38]要你很善良
[00:58.70]就算对我说谎也温暖
[01:03.06]请你坦荡荡
[01:06.46]世上没有满分的浪漫
[01:10.88]人们口中说的誓言
[01:13.68]真实的可怜
[01:15.50]你难道没有被爱背叛的绝望
[01:19.17]你不必太紧张
[01:20.77]诚实会有点难
[01:22.69]也许完美对我反而是假象
[01:26.50]过去我不想谈
[01:28.60]有缺憾也无妨
[01:30.26]我要你的自然
[01:34.41]Da La La La…
[02:05.16]爱要坦荡荡
[02:08.40]不要装模作样到天长
[02:12.75]要你很善良
[02:16.17]就算对我说谎也温暖
[02:20.47]请你坦荡荡
[02:23.94]世上没有满分的浪漫
[02:28.26]人们口中说的誓言
[02:30.93]真实的可怜
[02:32.85]你难道没有被爱背叛的绝望
[02:36.44]你不必太紧张
[02:38.21]诚实会有点难
[02:40.17]也许完美对我反而是假象
[02:43.99]过去我不想谈
[02:45.95]有缺憾也无妨
[02:47.72]我要你的自然
[02:51.86]Da La La La…`;
4. index.js
//定义需要获取的元素组
const domList = {
audio: document.querySelector("audio"),
music_contain: document.querySelector(".music-contain"),
ul: document.querySelector(".music-contain ul"),
};
/**
* 把lrc字符串转换成lrc对象形式,便于后续操作
*/
function lrcStrToObj() {
let dataList = [];
//计算歌词行数
const lines = lrc.split("\n");
for (let i = 0; i < lines.length; i++) {
//计算出每一行歌词内容
const str = lines[i];
//转换成对象类型,方便后续对数据的操作
const parse = str.split("]");
const time = parse[0].substring(1);
const obj = {
time: changeTimeStr(time),
content: parse[1],
};
dataList.push(obj);
}
return dataList;
}
/**
* 把时间字符串转换为时间,方便操作 如:'00:00.000'转换为0
*/
function changeTimeStr(timeStr) {
const timeArr = timeStr.split(":");
const endTime = +timeArr[0] * 60 + +timeArr[1];
return endTime;
}
//获取歌词对象数据
let lcrDataList = lrcStrToObj();
console.log(lcrDataList);
/**
* 计算当前播放时间下显示歌词的下标,用于计算高亮显示播放的歌词
*/
function findIndex() {
//获取当前播放器时间
const currentPlayTime = domList.audio.currentTime;
for (let i = 0; i < lcrDataList.length; i++) {
if (currentPlayTime < lcrDataList[i].time) {
return i - 1;
}
}
//如果找到最后没有找到,则返回最后一句
return lcrDataList.length - 1;
}
/**
* 动态创建li
*/
function createLi() {
//优化(减少频繁改变dom树)
var frag = document.createDocumentFragment(); //创建文档片段
for (let i = 0; i < lcrDataList.length; i++) {
const element = document.createElement("li");
element.textContent = lcrDataList[i].content;
frag.appendChild(element);
}
domList.ul.appendChild(frag);
}
createLi();
/**
* 设置ul的偏移量(高亮歌词居中显示)
* 需要获取容器高度,每个li的高度
*/
//容器高度
let containHeight = domList.music_contain.clientHeight;
//li高度
let liHeight = domList.ul.children[0].clientHeight;
//最大高度
let maxHeight = domList.ul.clientHeight - containHeight;
function setOffset() {
//下标
let index = findIndex();
let offset = liHeight * index + liHeight / 2 - containHeight / 2;
if (offset < 0) {
offset = 0;
}
if (offset > maxHeight) {
offset = maxHeight;
}
//偏移量
domList.ul.style.transform = `translateY(-${offset}px)`;
//高亮显示
let liActive = domList.ul.querySelector(".active");
if (liActive) {
liActive.classList.remove("active");
}
liActive = domList.ul.children[index];
if (liActive) {
liActive.classList.add("active");
}
}
domList.audio.addEventListener("timeupdate", setOffset);