讲解一个基本的播放器,包含基本的功能实现。
播放器制作的成品。代码直接在后面拿,注意歌曲对象的格式。?
1.分析基本结构
我们可以发现这个界面的基本结构可以分为两个部分,一个部分是歌曲的top 一个部分是歌曲的bottom
这边直接使用flex布局进行,划分,上二下一 对上面的内容继续进行划分。使用flex布局完成之后的划分
页面的基本布局代码
我直接放到后面的完整代码里面了,这样我好写文字。
基本布局结束之后,我们这时候需要书写一下播放的基本逻辑,这个文本编辑器字数一高直接就卡的受不了。
我们需要保证,当播放到对应的音乐时,歌词和歌曲背景,歌曲名称,播放的链接都需要进行更改,那么现在我们需要先获取到这些页面元素,获取之后,我们直接进行讲相同功能的模块进行封装,封装之后直接拿给对应逻辑的监听调用即可。
1.播放和暂停
? ? ? ? 注意切换界面的显示和当前播放的音乐对象的内容
2.上一曲和下一曲
????????注意播放到第一首和最后一首的播放情况
? ? ? ? 注意当歌曲没有播放的时候,点击下一首或者上一首的时候,保证歌曲的顺利播放
3.自动播放
? ? ? ? 设置一个函数来监听歌曲的完成,当歌曲完成时,自动切换到下一曲。
4.设置记录上一次
? ? ? ? 我们直接使用本地储存的知识点来进行上一次内容的记录,直接记录下来播放的索引即可。
5.播放进度条的显示
? ? ? ? 根据歌曲的播放进度进行进度条的显示内容
注意这部分内容的切换就行。我感觉可能没人会看这个内容。
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.box {
padding: 10px;
display: flex;
flex-direction: column;
position: fixed;
right: 10px;
bottom: 10px;
width: 200px;
height: 200px;
background-repeat: no-repeat;
background-size: cover;
}
.box::after {
top: 0;
left: 0;
backdrop-filter: blur(5px);
position: absolute;
width: 200px;
height: 200px;
background-color: rgba(0, 0, 0, .4);
content: "";
z-index: -10;
}
.box::before:hover {
color: yellow;
}
.box .top-music {
display: flex;
flex: 2;
flex-direction: column;
background-color: transparent;
}
.box .bottom-music-ci {
display: flex;
color: crimson;
justify-content: center;
align-items: center;
flex: 1;
overflow: hidden;
}
.box .top-music .top-music-name {
background-color: transparent;
display: flex;
flex: 1;
justify-content: center;
align-items: center;
color: orange;
}
.name-font {
font-size: 14px;
}
.box .top-music .top-music-load {
padding-top: 10px;
display: flex;
flex: 1;
justify-content: center;
align-items: center;
}
.box .top-music .top-music-use {
display: flex;
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
}
.box .top-music .top-music-use .font-music {
display: flex;
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
}
.box .top-music .top-music-use .paused-music {
display: flex;
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
}
.box .top-music .top-music-use .next-music {
display: flex;
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
}
#progressBar {
width: 200px;
height: 10px;
}
.hidden {
display: none;
}
.content {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
padding: 5px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="box">
<div class="top-music">
<div class="top-music-name">
<span class="name-font">歌曲-[歌手]</span>
</div>
<div class="top-music-load">
<audio id="audioPlayer"
src="https://m801.music.126.net/20240120222846/c4a039de7557dbc52bf7d266edd82802/jdymusic/obj/wo3DlMOGwrbDjj7DisKw/10563287967/a70c/70ad/0e2b/c921856c6dab06aaa3c663a4932ef7e4.mp3"></audio>
<progress id="progressBar" value="0" max="100"></progress>
</div>
<div class="top-music-use">
<div class="font-music">
<svg t="1705760253968" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="7683" width="32" height="32">
<path d="M512 62.389956c-248.312412 0-449.610044 201.297632-449.610044 449.610044s201.297632 449.610044 449.610044 449.610044 449.610044-201.297632 449.610044-449.610044S760.312412 62.389956 512 62.389956zM786.507004 786.507004c-35.672454 35.672454-77.196173 63.672158-123.416867 83.222423-47.821145 20.22667-98.655927 30.482245-151.09116 30.482245-52.435233 0-103.270015-10.255575-151.09116-30.482245-46.220694-19.549242-87.744413-47.549969-123.416867-83.222423-35.672454-35.672454-63.672158-77.196173-83.222423-123.416867-20.22667-47.821145-30.482245-98.655927-30.482245-151.090137 0-52.435233 10.255575-103.270015 30.482245-151.09116 19.549242-46.220694 47.549969-87.744413 83.222423-123.416867 35.672454-35.672454 77.196173-63.672158 123.416867-83.222423 47.821145-20.22667 98.654904-30.482245 151.09116-30.482245 52.435233 0 103.268992 10.255575 151.09116 30.482245 46.220694 19.549242 87.744413 47.549969 123.416867 83.222423 35.672454 35.672454 63.672158 77.196173 83.222423 123.416867 20.22667 47.821145 30.482245 98.655927 30.482245 151.09116 0 52.435233-10.255575 103.268992-30.482245 151.090137C850.179163 709.310831 822.179458 750.83455 786.507004 786.507004z"
p-id="7684" fill="#e6e6e6"></path>
<path d="M715.830315 305.667701 448.346261 507.980453c-3.094478 1.786693-3.094478 6.252401 0 8.039093l267.484054 202.312752c3.094478 1.786693 6.961552-0.446162 6.961552-4.019547l0-404.625504C722.791867 306.113863 718.924793 303.881009 715.830315 305.667701z"
p-id="7685" fill="#e6e6e6"></path>
<path d="M398.078391 306.049395l-92.229564 0c-2.563382 0-4.640694 2.365884-4.640694 5.28333l0 401.334551c0 2.917446 2.078335 5.28333 4.640694 5.28333l92.229564 0c2.563382 0 4.641717-2.365884 4.641717-5.28333L402.720108 311.332724C402.719084 308.415278 400.641773 306.049395 398.078391 306.049395z"
p-id="7686" fill="#e6e6e6"></path>
</svg>
</div>
<!-- 这个位置设置成点击及播放的效果会更好一点-->
<div class="paused-music">
<svg t="1705760359255" class="icon hidden" id="pause" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="8784" width="32" height="32">
<path d="M512 128a382.6 382.6 0 1 1-149.45 30.15A381.54 381.54 0 0 1 512 128m0-64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.58 448-448S759.42 64 512 64z"
p-id="8785" fill="#e6e6e6"></path>
<path d="M384 320v384-384m0-64a64 64 0 0 0-64 64v384a64 64 0 0 0 64 64 64 64 0 0 0 64-64V320a64 64 0 0 0-64-64zM640 320v384-384m0-64a64 64 0 0 0-64 64v384a64 64 0 0 0 64 64 64 64 0 0 0 64-64V320a64 64 0 0 0-64-64z"
p-id="8786" fill="#e6e6e6"></path>
</svg>
<svg t="1705760529073" class="icon" id="open" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="11757" width="32" height="32">
<path d="M924.5 337.9c-22.6-53.3-54.8-101.2-95.9-142.3-41.1-41.1-89-73.4-142.3-95.9C631.1 76.4 572.4 64.5 512 64.5c-60.4 0-119.1 11.8-174.3 35.2-53.3 22.6-101.2 54.8-142.3 95.9s-73.4 89-95.9 142.3c-23.4 55.2-35.2 113.9-35.2 174.3s11.8 119.1 35.2 174.3c22.6 53.3 54.8 101.2 95.9 142.3s89 73.4 142.3 95.9c55.2 23.4 113.9 35.2 174.3 35.2 60.4 0 119.1-11.8 174.3-35.2 53.3-22.6 101.2-54.8 142.3-95.9 41.1-41.1 73.4-89 95.9-142.3 23.4-55.2 35.2-113.9 35.2-174.3s-11.8-119-35.2-174.3z m-146.8 440c-71 71-165.3 110-265.7 110-100.4 0-194.7-39.1-265.7-110-71-71-110-165.3-110-265.7s39.1-194.7 110-265.7 165.3-110 265.7-110c100.4 0 194.7 39.1 265.7 110s110 165.3 110 265.7-39.1 194.7-110 265.7z"
p-id="11758" fill="#e6e6e6"></path>
<path d="M706.7 464.8L447.6 300.6c-17.3-11-39.2-11.6-57.1-1.8-17.9 9.9-29.1 28.7-29.1 49.2v328c0 20.5 11.1 39.3 29.1 49.2 8.5 4.7 17.8 7 27.1 7 10.4 0 20.9-2.9 30-8.7l259.1-163.8c16.4-10.3 26.1-28.1 26.2-47.5-0.1-19.3-9.9-37.1-26.2-47.4zM433.4 647.3V376.8L647 512.2 433.4 647.3z"
p-id="11759" fill="#e6e6e6"></path>
</svg>
</div>
<div class="next-music">
<svg t="1705760207636" class="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="6527" width="32" height="32">
<path d="M512 62.389956c-248.312412 0-449.610044 201.297632-449.610044 449.610044s201.297632 449.610044 449.610044 449.610044 449.610044-201.297632 449.610044-449.610044S760.312412 62.389956 512 62.389956zM786.507004 786.507004c-35.672454 35.672454-77.196173 63.672158-123.416867 83.222423-47.821145 20.22667-98.655927 30.482245-151.09116 30.482245-52.435233 0-103.270015-10.255575-151.09116-30.482245-46.220694-19.549242-87.744413-47.549969-123.416867-83.222423-35.672454-35.672454-63.672158-77.196173-83.222423-123.416867-20.22667-47.821145-30.482245-98.655927-30.482245-151.090137 0-52.435233 10.255575-103.270015 30.482245-151.09116 19.549242-46.220694 47.549969-87.744413 83.222423-123.416867 35.672454-35.672454 77.196173-63.672158 123.416867-83.222423 47.821145-20.22667 98.654904-30.482245 151.09116-30.482245 52.435233 0 103.268992 10.255575 151.09116 30.482245 46.220694 19.549242 87.744413 47.549969 123.416867 83.222423 35.672454 35.672454 63.672158 77.196173 83.222423 123.416867 20.22667 47.821145 30.482245 98.655927 30.482245 151.09116 0 52.435233-10.255575 103.268992-30.482245 151.090137C850.179163 709.310831 822.179458 750.83455 786.507004 786.507004zM575.653739 507.980453 308.169685 305.667701c-3.094478-1.786693-6.961552 0.446162-6.961552 4.019547l0 404.625504c0 3.572362 3.868097 5.806239 6.961552 4.019547l267.484054-202.312752C578.747193 514.232854 578.747193 509.767146 575.653739 507.980453zM718.151174 306.049395l-92.229564 0c-2.563382 0-4.640694 2.365884-4.640694 5.28333l0 401.334551c0 2.917446 2.078335 5.28333 4.640694 5.28333l92.229564 0c2.563382 0 4.640694-2.365884 4.640694-5.28333L722.791867 311.332724C722.791867 308.415278 720.714556 306.049395 718.151174 306.049395z"
fill="#e6e6e6" p-id="6528"></path>
</svg>
</div>
</div>
</div>
<div class="bottom-music-ci">
<div class="content">
</div>
</div>
</div>
<script>
// 歌曲id
var music_open_now = 0
// 歌曲当前状态
var status = 1
// 初始化
if (!localStorage.getItem('music_open_last')) {
localStorage.setItem('music_open_last', music_open_now)
}
music = [
{
"name": "晨曦 Praying theme",
"artist": "万俟清商",
"url": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=url&id=2065512248",
"pic": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=pic&id=109951166958324596",
"lrc": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=lrc&id=2065512248"
},
{
"name": "在海边",
"artist": "林鹤洋",
"url": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=url&id=1964372498",
"pic": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=pic&id=109951167677740645",
"lrc": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=lrc&id=1964372498"
},
{
"name": "?",
"artist": "周大发",
"url": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=url&id=1430751658",
"pic": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=pic&id=109951165804381199",
"lrc": "https:\/\/api.injahow.cn\/meting\/?server=netease&type=lrc&id=1430751658"
}
]
// 首次应该没问题 这个代码就是用来防止说 上一次播放的记录 超过此时的内容了 没啥用
// if (Math.floor(localStorage.getItem('music_open_last'))>=music.length) {
// localStorage.setItem('music_open_last', 0)
// }
<!-- 歌曲整体内容 用于更换背景 我们可以制作的好看一点 背景主要就是模糊-->
const box = document.querySelector('.box')
// 控制开关 显示
const open = document.querySelector('#open')
const pause = document.querySelector('#pause')
// 获取歌曲的名字
const music_name = document.querySelector('.top-music-name .name-font')
// 音乐播放
const audio = document.getElementById("audioPlayer");
// 进度条内容
const progressBar = document.getElementById("progressBar");
// 上一曲 下一曲
const next_music = document.querySelector('.next-music')
const font_music = document.querySelector('.font-music')
const music_ci = document.querySelector('.bottom-music-ci .content')
// 音乐加载内容
//
function loadLrc(music_open_now) {
const url = music[music_open_now]['lrc'];
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const responseText = xhr.responseText;
// 这个呈递的是歌词部分 由于大部分是纯音乐 这里就不便显示
music_ci.innerHTML = "纯音乐,请欣赏";
}
};
xhr.send();
}
function load(music_open_now) {
audio.src = music[music_open_now]['url'];
music_name.innerHTML = music[music_open_now]['name'] + '-' + music[music_open_now]['artist'];
box.style.backgroundImage = `url(${music[music_open_now]['pic'].toString()})`;
loadLrc(music_open_now)
}
// 获取上一次播放的记录
music_open_now = Math.floor(localStorage.getItem('music_open_last'))
// 加载上一次歌曲的内容
load(music_open_now)
// 歌曲监听
// 这部分内容由于重复较多 我们可以封装称一个函数 但是由于代码量少 这里不采取提取了,如果采取封装,那么我们只需要监听是获取这个点击对象看一下类名进行判断是+还是-即可,较为简单不多赘述
next_music.addEventListener('click', function () {
if (music_open_now == music.length - 1) {
music_open_now = 0
} else {
music_open_now += 1
}
load(music_open_now)
if (status == 1) {
const hidden = document.querySelector('.hidden')
hidden.classList.remove('hidden')
open.classList.add('hidden')
status = 0
}
audio.play()
localStorage.setItem('music_open_last', music_open_now)
})
font_music.addEventListener('click', function () {
console.log(status)
if (music_open_now == 0) {
music_open_now = music.length - 1
} else {
music_open_now -= 1
}
load(music_open_now)
if (status == 1) {
const hidden = document.querySelector('.hidden')
hidden.classList.remove('hidden')
open.classList.add('hidden')
status = 0
}
audio.play()
localStorage.setItem('music_open_last', music_open_now)
})
// 播放监听
open.addEventListener('click', function () {
const hidden = document.querySelector('.hidden')
hidden.classList.remove('hidden')
open.classList.add('hidden')
status = 0
console.log(status)
audio.play()
})
pause.addEventListener('click', function () {
const hidden = document.querySelector('.hidden')
hidden.classList.remove('hidden')
pause.classList.add('hidden')
status = 1
console.log(status)
audio.pause()
})
// // 设置歌曲链接
// audio.style.src = music['url']
// music_name.innerHTML = music['name'] + '-' + music['artist']
// box.style.backgroundImage = `url(${music['pic'].toString()})`;
// 监听进度条拖动事件
progressBar.addEventListener('input', function () {
// 计算当前播放时间
var currentTime = (progressBar.value / 100) * audio.duration;
// 检查是否为非有限值
if (isFinite(currentTime)) {
// 设置音频的当前播放时间
audio.currentTime = currentTime;
}
});
// 监听音频的时间更新事件
audio.addEventListener('timeupdate', function () {
// 更新进度条的值
var progress = (audio.currentTime / audio.duration) * 100;
// 检查是否为非有限值
if (isFinite(progress)) {
progressBar.value = progress;
}
});
// 自动播放
// 监听歌曲播放结束事件
audio.addEventListener('ended', function () {
// 自动切换到下一首歌曲
if (music_open_now == music.length - 1) {
music_open_now = 0;
} else {
music_open_now += 1;
}
load(music_open_now);
audio.play();
localStorage.setItem('music_open_last', music_open_now);
});
</script>
</body>
</html>