900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 原生JS实现音乐播放器及歌词滚动

原生JS实现音乐播放器及歌词滚动

时间:2024-08-10 01:40:33

相关推荐

原生JS实现音乐播放器及歌词滚动

话不多说先上效果图,界面没怎么美化,音乐使用的在线链接,图片使用的也是在线链接,歌名和歌词使用的是本地信息

style

* {margin: 0;padding: 0;}body {background-color: #2d2d2d;}#musbox {position: relative;margin: 80px auto;background-color: #fcfcfc;width: 300px;height: 500px;border-radius: 15px;text-align: center;}#musboximg {margin-top: 30px;margin-bottom: 30px;width: 180px;height: 180px;border-radius: 50%;animation: mymove 20s linear infinite;}#musnam {margin-top: 20px;margin-bottom: 10px;}button {width: 30px;height: 30px;border-radius: 50%;border: none;background-color: #fcfcfc;margin-top: 100px;}button:nth-of-type(2) {margin-left: 30px;margin-right: 30px;}button > img {width: 100%;height: 100%;}progress {width: 280px;}@keyframes mymove {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);}}.lyric_area {position: absolute;bottom: 70px;/*歌词显示区域*/height: 80px; /*歌词区域高度*/overflow: hidden;margin-top: 15px;}#lyric {/*歌词列表*/line-height: 25px; /*行高,这个值要用在歌词滚动距离上*/transition-duration: 600ms; /*滚动速度*/}#lyric .lineHigh {/*高亮行*/color: red;}#lyric > li {width: 300px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;}#fanhui {position: absolute;top: -100px;left: 0px;opacity: 0;}

HTML

<div id="musbox"><audio src="" id="auo"></audio><img src="" alt="" id="musboximg" /><h3 id="mustitle"></h3><p id="musnam"></p><progress max="100" value="0" id="progress"></progress><div class="lyric_area"><ul id="lyric" type="none"></ul></div><button id="mustop"><img src="./imgs/上一首.png" alt="" /></button><button id="mussta"><img id="musstaimg" src="./imgs/24gl-play.png" alt="" /></button><button id="musbom"><img src="./imgs/下一首.png" alt="" /></button><button id="fanhui"><img src="./imgs/返回.png" alt="" /></button></div>

JS

var progress = document.querySelector('progress')var index = 0 //当前播放的歌曲//歌曲链接存放地址var music = ['http://dl.stream./C40000306XNI2518qE.m4a?guid=818258907&vkey=3E6B8303FBE637A22F898F3BD451925D312F8953C0418FFA404DCEFCAC06C193639380E063EE275E531D64281BDF20E4743ED960553DBFE2&uin=534808402&fromtag=12','http://dl.stream./C400003jPrhs2i3glx.m4a?guid=4655831370&vkey=927F4B96A239B2BCDCD3E09E265D409257926A77C472107F55C852D3669270EB39D500FE70D608771224340A4D321FF1FA69057FEDB8&uin=534808402&fromtag=12','http://dl.stream./C400002fxyPd03wGST.m4a?guid=9182436588&vkey=74EEE70EA2F83B82CA928A746E8F0C849BF8C86783E9BD9FC9E317D7668410DF735ABD7C718D91BA675303CA67254FC792795E006EA60707&uin=534808402&fromtag=12','http://dl.stream./RS02061DAjhF369Snq.mp3?guid=5910173232&vkey=01D0B205F29E49DDD0832971216E1486C23FE1B8E2A74F9E2DEFDBF835A86176EA1A2D7DE3FA1086F81FF0DA42B9A98371C7F163EF23DA71&uin=534808402&fromtag=12','http://dl.stream./RS02060N8fi64ZBlE1.mp3?guid=7818777342&vkey=432502A6EE64A0330E9FC088A8DBAD57E4FB10DFE792BE102E94ECE4C3D0B60AAEBBCBFA5B99F4E404895258B6FCFC319FDEA062E6F054A8&uin=534808402&fromtag=12','http://dl.stream./C40000182Rsa42ANA9.m4a?guid=6684174472&vkey=531E377E998E8A3716F2FDDFF62E6E61F8F4B2FB5F3F1BA56E92810838046281C74BFCA9EF3DDD6D937E0AC17707084B26028166F4C23F2B&uin=534808402&fromtag=12','http://dl.stream./C400003hkB7p35njTP.m4a?guid=5241292852&vkey=57342D6181907B49C67101A7EEA12482E63663DA83D99315104B74A7F4023BA09EC9C8982A2DA7389304C6E51A7C622EF56421080F5E6063&uin=534808402&fromtag=12',]// 歌曲大图var musicimg = ['/music/photo_new/T002R300x300M000002HRHRB004tH9_1.jpg?max_age=2592000','/music/photo_new/T002R300x300M0000039nM8m1yhEnK_1.jpg?max_age=2592000','/music/photo_new/T002R300x300M000002VxplL2gXAuH_4.jpg?max_age=2592000','/music/photo_new/T002R300x300M000002xoonH2Bk7FR_1.jpg?max_age=2592000','/music/photo_new/T002R300x300M0000039nM8m1yhEnK_1.jpg?max_age=2592000','/music/photo_new/T002R300x300M0000001n7a82gh6IY_1.jpg?max_age=2592000','/music/photo_new/T002R300x300M000003Z53pQ3q9pEo_1.jpg?max_age=2592000',]// 歌曲名称var musicname = ['平凡的一天 (Live) - 毛不易','看得最远的地方 - 毛不易','一荤一素 (Live) - 毛不易','消愁 (Live) - 毛不易','像我这样的人 (Live) - 毛不易','光辉岁月 - BEYOND','舞女 (国语)-韩宝仪.lrc',]// 歌词名称var gcarray = ['01平凡的一天 (Live)-毛不易.lrc','02看得最远的地方-毛不易.lrc','03一荤一素 (Live)-毛不易.lrc','04消愁 (Live)-毛不易.lrc','05像我这样的人 -毛不易.lrc','06光辉岁月-BEYOND.lrc','07舞女 (国语)-韩宝仪.lrc',]!(function () {auo.src = music[0]getLRC(gcarray[0])musboximg.src = musicimg[0]mustitle.innerHTML = `${musicname[0].split('-')[0]}`musnam.innerHTML = `${musicname[0].split('-')[1]}`musboximg.style.animationPlayState = 'paused'})()var sta = 1// 播放暂停事件mussta.onclick = function () {if (sta == 0) {musstaimg.src = './imgs/24gl-play.png'sta = 1auo.pause()musboximg.style.animationPlayState = 'paused'} else {musstaimg.src = './imgs/24gl-pause2.png'sta = 0auo.play()musboximg.style.animationPlayState = 'running'}}// 下一首事件函数function naiods() {index++if (index >= music.length) {index = 0}auo.src = music[index]getLRC(gcarray[index])musboximg.src = musicimg[index]mustitle.innerHTML = `${musicname[index].split('-')[0]}`musnam.innerHTML = `${musicname[index].split('-')[1]}`musstaimg.src = './imgs/24gl-pause2.png'auo.play()musboximg.style.animationPlayState = 'running'}// 下一首点击事件musbom.onclick = function () {naiods()}// 上一首点击事件mustop.onclick = function () {index--if (index < 0) {index = music.length - 1}auo.src = music[index]getLRC(gcarray[index])musboximg.src = musicimg[index]mustitle.innerHTML = `${musicname[index].split('-')[0]}`musnam.innerHTML = `${musicname[index].split('-')[1]}`musstaimg.src = './imgs/24gl-pause2.png'auo.play()musboximg.style.animationPlayState = 'running'}// 自动下一首auo.onended = function () {naiods()}// 滚动条事件 已添加到JS文件中// auo.shouldUpdate = true// auo.ontimeupdate = function () {// var _this = this// if (_this.shouldUpdate) {//_this.shouldUpdate = false//setTimeout(function () {// console.log((auo.currentTime / auo.duration) * 100)// progress.value = (auo.currentTime / auo.duration) * 100// _this.shouldUpdate = true//}, 800)// }// }// 滚动条点击事件progress.onclick = function () {var x = event.offsetXvar w = progress.offsetWidthauo.currentTime = (x / w) * auo.duration}// 点击头像切换歌词显示var lyric_area = document.getElementsByClassName('lyric_area')[0]musboximg.onclick = function () {fanhui.style.opacity = 1musboximg.style.opacity = '0'mustitle.style.opacity = '0'musnam.style.opacity = '0'mustop.style.opacity = '0'mussta.style.opacity = '0'musbom.style.opacity = '0'progress.style.opacity = '0'lyric_area.style.top = '10px'lyric_area.style.height = '450px'}fanhui.onclick = function () {

由于JS代码太多太乱了,我直接把他封装到另一个JS文件中了,直接导入即可

var lrc = ''function getLRC(gct) {var ajax = new XMLHttpRequest()ajax.open('GET', gct)ajax.onreadystatechange = function () {if (ajax.readyState == 4 && ajax.status == 200) {lrc = ajax.responseText// console.log(lrc)var oLRC = {ti: '', //歌曲名ar: '', //演唱者al: '', //专辑名by: '', //歌词制作人offset: 0, //时间补偿值,单位毫秒,用于调整歌词整体位置ms: [], //歌词数组{t:时间,c:歌词}}function createLrcObj(lrc) {if (lrc.length == 0) returnvar lrcs = lrc.split('\n') //用回车拆分成数组for (var i in lrcs) {//遍历歌词数组lrcs[i] = lrcs[i].replace(/(^\s*)|(\s*$)/g, '') //去除前后空格var t = lrcs[i].substring(lrcs[i].indexOf('[') + 1,lrcs[i].indexOf(']')) //取[]间的内容var s = t.split(':') //分离:前后文字if (isNaN(parseInt(s[0]))) {//不是数值for (var i in oLRC) {if (i != 'ms' && i == s[0].toLowerCase()) {oLRC[i] = s[1]}}} else {//是数值var arr = lrcs[i].match(/\[(\d+:.+?)\]/g) //提取时间字段,可能有多个var start = 0for (var k in arr) {start += arr[k].length //计算歌词位置}var content = lrcs[i].substring(start) //获取歌词内容if (content.length > 0) {for (var k in arr) {var t = arr[k].substring(1, arr[k].length - 1) //取[]间的内容var s = t.split(':') //分离:前后文字oLRC.ms.push({//对象{t:时间,c:歌词}加入ms数组t: (parseFloat(s[0]) * 60 + parseFloat(s[1])).toFixed(3),c: content,})}}}}oLRC.ms.sort(function (a, b) {//按时间顺序排序return a.t - b.t})function showLRC() {lyric.innerHTML = ``var s = ''for (var i in oLRC.ms) {//遍历ms数组,把歌词加入列表s += '<li>' + oLRC.ms[i].c + '</li>'}document.getElementById('lyric').innerHTML = s}showLRC()}createLrcObj(lrc)var lineNo = 0 //当前行var C_pos = 1 //C位var offset = -25 //滚动距离(应等于行高)var audio = document.getElementById('auo') //播放器var ul = document.getElementById('lyric') //歌词容器列表//高亮显示歌词当前行及文字滚动控制,行号为lineNofunction lineHigh() {var lis = document.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 lineHigh2() {var lis = ul.getElementsByTagName('li') //歌词数组for (var i = 0; i < lis.length; i++) {var name = lis[i].classNameif (name != null) lis[i].removeAttribute('class') //去掉高亮样式}}//跳跃播放时,歌词回滚到对应位置audio.onseeked = function () {var curTime = audio.currentTime //播放器时间for (i = 0; i < oLRC.ms.length; i++) {if (oLRC.ms[i].t <= curTime) {} else {lineHigh2() //取消之前所有高亮lineNo = ilineHigh() //高亮当前行break}}}//滚回到开头,用于播放结束时function goback() {document.querySelector('#lyric .lineHigh').removeAttribute('class')ul.style.transform = 'translateY(0)'lineNo = 0}//监听播放器的timeupdate事件,实现文字与音频播放同步auo.shouldUpdate = trueaudio.ontimeupdate = function () {var _this = thisif (_this.shouldUpdate) {_this.shouldUpdate = falsesetTimeout(function () {console.log((auo.currentTime / auo.duration) * 100)progress.value = (auo.currentTime / auo.duration) * 100_this.shouldUpdate = true}, 800)}if (lineNo == oLRC.ms.length) returnvar curTime = audio.currentTime //播放器时间if (parseFloat(oLRC.ms[lineNo].t) <= curTime) {lineHigh() //高亮当前行lineNo++}}//监听播放器的ended事件,播放结束时回滚歌词// audio.onended = function () {// goback() //回滚歌词// }}}ajax.send(null)}

对了提醒一下一定要用Live Server打开,因为用了ajax请求本地的歌词,如果各位有在线歌词地址可以直接替换。

总结一下遇到的问题:

当我为滚动条添加进度跟随音乐播放时遇到的问题,直接用ontimeupdate事件会因为加载过快,在切换歌曲时还没加载到下一首歌曲的资源就直接执行了,因此会报错误,这里我们用定时器延迟他的执行速率,调整一下就可以了。

歌词滚动部分主要参考:歌词滚动部分参考链接

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。