js、jQuery 仿酷狗音乐
很久之前做的仿酷狗音乐播放器,有需要的同学可以借鉴下,希望对您有些许帮助,存在一些bug,完成后没做太多修改,毕竟是练练手,工作之余做的,您可以将存在的需要解决的问题写在评论里,我会及时回复,望见谅。
分辨率问题导致画质模糊,凑活着看吧先,溜了溜了。。。。。
1 <!-- created by Lyy 2018/8/27 --> 2 <!DOCTYPE html> 3 <html lang="en"> 4 5 <head> 6 <meta charset="UTF-8"> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 8 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 9 <title>webmusic</title> 10 <link rel="stylesheet" type="text/css" href="./css/webmusic.css" /> 11 <style type="text/css"> 12 </style> 13 </head> 14 15 <body> 16 <div class="panelContent"> 17 <div class="content"> 18 <div class="posterContent fl"> 19 <div class="poster"> 20 <div class="posterNull"></div> 21 <!--<img src="./images/music.png" class="posterImg" style="width: 100px; height: 100px;">--> 22 </div> 23 </div> 24 <div class="lrcContent fl"> 25 <div class="lrcName">歌曲名</div> 26 <div class="lrcDetail"> 27 <p class="albumName"> 28 <span class="fontColor">专辑:</span> 29 <span class="blank albumContent">专辑名</span> 30 </p> 31 <p class="singerName"> 32 <span class="fontColor">歌手:</span> 33 <span class="blank singerContent">歌手名</span> 34 </p> 35 </div> 36 <div class="lrc" id="m-con"> 37 38 </div> 39 </div> 40 </div> 41 42 <div id="bg"></div> 43 44 <div class="musicControl"> 45 <div class="controlBg"></div> 46 <div class="playerControl"> 47 <div class="controlLeft"> 48 <span class="icon playLast"></span> 49 <span class="playOrPauseContent"><span class="icon playOrPause play"></span></span> 50 <span class="icon playNext"></span> 51 </div> 52 <div class="controlPoster"> 53 <!-- <img src="" alt="海报" class="controlPosterImg"> --> 54 <div class="controlPosterImg"></div> 55 </div> 56 <div class="controlCenter"> 57 <div class="songMsg"> 58 <span class="songMsgLeft">歌曲名</span> 59 <span><span class="getCurrentTime">00</span> / <span class="getduration">00</span></span> 60 </div> 61 <div class="controlCenterBottom"> 62 <div class="progressBg"></div> 63 <div class="progressBar"></div> 64 <div class="Ball"> 65 <div class="icon progressBall"></div> 66 </div> 67 </div> 68 </div> 69 <div class="controlRight"> 70 <span class="each-control"> 71 <span class="icon each-controlIcon changeVolume volume"></span> 72 <div class="volumeControl"> 73 <div class="volume-barHome"> 74 <div class="volume-bar"></div> 75 </div> 76 <div class="volumeBallHome"> 77 <div class="icon volume-ball"></div> 78 </div> 79 </div> 80 </span> 81 <span class="each-control"> 82 <span class="icon each-controlIcon changePlayMode palyModeLoop"></span> 83 </span> 84 <span class="each-control"> 85 <a href="" download="music" id="downHref"> 86 <span class="icon each-controlIcon changeDownloadThis downloadThis"></span> 87 </a> 88 </span> 89 <span class="each-control"> 90 <span class="icon each-controlIcon changeShare share"></span> 91 </span> 92 <div class="playStyleList"> 93 <div class="ul"> 94 <div class="li"> 95 <span class="icon iconOne"></span> 96 <span>列表循环</span> 97 </div> 98 <div class="li"> 99 <span class="icon iconTwo"></span> 100 <span>单曲循环</span> 101 </div> 102 <div class="li"> 103 <span class="icon iconThree"></span> 104 <span>随机播放</span> 105 </div> 106 </div> 107 </div> 108 </div> 109 <div class="controlList"> 110 <div class="icon listIcon"> 111 <span class="listNum">0</span> 112 </div> 113 <div class="playList"> 114 <div class="playListHeader"> 115 <div>播放队列 / 116 <span class="playListLength">0</span> 117 </div> 118 <div class="header-control"> 119 <div class="icon icon-trash"></div> 120 <div class="line"></div> 121 <div class="icon icon-close"></div> 122 </div> 123 </div> 124 <div class="playContent"> 125 126 <div class="playContentNull"> 127 队列中没有歌曲 128 </div> 129 </div> 130 </div> 131 </div> 132 </div> 133 134 <div class="cMusicControl"> 135 <span class="icon showOrHideControl hideControl"></span> 136 </div> 137 </div> 138 139 140 <!-- 控制器 --> 141 <div style="position: absolute;top: 0;left: 0; display: inline-flex; display: none;"> 142 <div class="control"></div> 143 <select id="selectData"></select> 144 </div> 145 </div> 146 147 148 <script type="text/javascript" src="js/jquery-1.8.3.min.js"></script> 149 <script> 150 $(function() { 151 var clickToLast = false; 152 var thisNum = 0; 153 var audioDom; 154 var playMode = 0; //播放方式 155 var setMutsed = false; //设置静音 156 var mutsedValue = 1; 157 // data = [{ 158 // song_name: '再见只是陌生人', 159 // hash: 'B507808B800A5413C0E8C165AC52DE68', 160 // album_id: 553952, 161 // _: 1532159298122 162 // }, { 163 // song_name: '追光者', 164 // hash: '332D8257716EFD86D075809E61CFD5D5', 165 // album_id: 2706911, 166 // _: 1532159298114 167 // }, { 168 // song_name: '哪一站', 169 // hash: '1045530EF672ECF32DBE39D1940241A4', 170 // album_id: 39561602, 171 // _: 1532159298114 172 // }]; 173 var data = []; 174 getList(); 175 function getList() { 176 $.ajax({ 177 type: "GET", 178 url: 'http://songsearch.kugou.com/song_search_v2', 179 success: function(res) { 180 var r = JSON.parse(res); 181 data = r.data.lists; 182 console.log(data); 183 } 184 }) 185 } 186 // var options = ''; 187 // for (var i = 0; i < data.length; i++) { 188 // options += "<option value=" + i + ">" + data[i].song_name + "</option>" 189 // } 190 // 191 // $("#selectData").html(options); 192 // $("#selectData").change(function () { 193 // getData(parseInt($("#selectData").val())); 194 // }); 195 setTimeout(function() { 196 $(".playListLength").html(data.length); 197 $(".listNum").html(data.length); 198 var list = ''; 199 for (var i = 0; i < data.length; i++) { 200 $(".playContent").append("<div class='eachSong'>" + 201 "<div class='serial-number'>" + (i + 1) + "</div>" + 202 "<div class='song-name'>" + 203 "<span>" + data[i].SongName + "</span>" + 204 "<span></span>" + 205 "</div>" + 206 "<div class='author-name'>XXX</div>" + 207 "<div class='song-duration'>03:00</div>" + 208 "</div>") 209 } 210 $(".playStyleList .ul .li:first span").addClass("newIconOne"); 211 }, 400) 212 $(".playStyleList .ul .li").click(function() { 213 playMode = $(this).index(); 214 console.log("播放方式:" + playMode); 215 changeThisNum(); 216 if (playMode == 0) { 217 $(this).children(0).addClass("newIconOne").parent().siblings().children().removeClass("newIconTwo newIconThree"); 218 $(".changePlayMode").addClass("palyModeLoop"); 219 $(".changePlayMode").removeClass("palyModeSingle palyModeRandom"); 220 } else if (playMode == 1) { 221 $(this).children(1).addClass("newIconTwo").parent().siblings().children().removeClass("newIconOne newIconThree"); 222 $(".changePlayMode").addClass("palyModeSingle"); 223 $(".changePlayMode").removeClass("palyModeLoop palyModeRandom"); 224 } else if (playMode == 2) { 225 $(this).children(2).addClass("newIconThree").parent().siblings().children().removeClass("newIconOne newIconTwo"); 226 $(".changePlayMode").addClass("palyModeRandom"); 227 $(".changePlayMode").removeClass("palyModeLoop palyModeSingle"); 228 } 229 }); 230 function randomNum() { 231 var a = Math.floor(Math.random() * data.length); 232 return a; 233 } 234 function changeThisNum(click) { 235 if (playMode == 0) { 236 if (clickToLast) { 237 // console.log(thisNum) 238 if (thisNum > 0) { 239 thisNum--; 240 } else { 241 thisNum = data.length - 1; 242 } 243 } else { 244 if (thisNum < data.length - 1) { 245 thisNum++; 246 } else { 247 thisNum = 0; 248 } 249 } 250 } else if (playMode == 1) { 251 if (click === true) { 252 thisNum++; 253 } else if (click === false) { 254 thisNum--; 255 } else { 256 thisNum = thisNum; 257 } 258 } else if (playMode == 2) { 259 var getNum = randomNum(); 260 if (thisNum != getNum) { 261 thisNum = getNum; 262 } else { 263 changeThisNum(); 264 } 265 } 266 } 267 // audioDom = document.createElement("audio"); //创建MP3播放器 268 setTimeout(function() { 269 getData(0); 270 }, 500) 271 function getData(index) { 272 // thisNum = index; 273 audioDom = document.createElement("audio"); //创建MP3播放器 274 audioDom.controls = "controls"; 275 audioDom.mutsed = setMutsed; //设置音频是否静音。 276 audioDom.autoplay = true; //设置是否在加载完成后随即播放音频。 277 audioDom.id = "audioDom"; 278 audioDom.src = ''; //清除歌曲链接 279 $('.control').html(''); //清除控制器 280 $('.control').append(audioDom); 281 if (data.length > 0) { 282 $.ajax({ 283 type: "GET", 284 // url: "http://www.kugou.com/yy/index.php?r=play/getdata&hash=" + data[index].hash + "&album_id=" + data[index].album_id + "&_=" + new Date().valueOf(), 285 url: "http://www.kugou.com/yy/index.php?r=play/getdata&hash=" + data[index].FileHash + "&album_id=" + data[index].ID + "&_=" + new Date().valueOf(), 286 success: function(res) { 287 // audio_name歌曲名 album_name专辑名 song_name歌曲名 author_name作者姓名 img海报 lyrics歌词 play_url播放地址 timelength歌曲时长 288 // console.log(JSON.parse(res).data); 289 var data = JSON.parse(res).data; 290 var lrc = data.lyrics; 291 $(".poster").css('background-image', "url(" + data.img + ")"); 292 $("#bg").css('background-image', "url(" + data.img + ")"); 293 $(".controlPosterImg").css("background-image", "url(" + data.img + ")") 294 $(".albumContent").html(data.album_name); 295 $(".singerContent").html(data.author_name); 296 $(".lrcName").html(data.audio_name); 297 $(".songMsgLeft").html(data.audio_name); 298 $("#downHref").attr("href", data.play_url); 299 var getduration = new Date(data.timelength); 300 $(".getduration").html(getduration.getMinutes() + ":" + getduration.getSeconds()); 301 audioDom.src = data.play_url; 302 var lrcArray = lrc.split("["); 303 var html = ""; 304 for (var i = 0; i < lrcArray.length; i++) { 305 var arr = lrcArray[i].split("]"); 306 var lrcMsg = arr[1]; 307 var timers = arr[0].split("."); 308 var stime = timers[0].split(":"); 309 var ms = stime[0] * 60 + stime[1] * 1 - 1; 310 if (lrcMsg) { 311 html += "<div class='eachLrc' id='" + ms + "'>" + lrcMsg + "</div>"; 312 } 313 } 314 $("#m-con").html(html); 315 } 316 }); 317 clickToLast = false; 318 } 319 /** 320 *获取歌曲长度 321 */ 322 // setTimeout(function () { 323 // $(".getduration").html(formatSeconds(audioDom.duration.toFixed(0))) 324 // }, 500); 325 var history = 0; 326 num = 0; 327 audioDom.addEventListener("timeupdate", function() { 328 var time = this.currentTime; 329 $(".getCurrentTime").html(formatSeconds(this.currentTime.toFixed(0))); 330 $(".progressBar").css("width", this.currentTime / audioDom.duration * 370 + "px"); 331 $(".progressBall").css("margin-left", this.currentTime / audioDom.duration * 370 + "px"); 332 if (time >= audioDom.duration) { 333 timer(); 334 } 335 //通过时间来驱动歌词 336 var s = parseInt(time); 337 for (var i = 0; i < s; i++) { 338 $("#" + i).addClass("selfTurn").siblings().removeClass("selfTurn"); 339 } 340 // console.log($("#"+i)); 341 // console.log(history + " " + s); 342 if ($("#" + i).length == 1 && history != s) { 343 document.getElementById(i).scrollIntoView({ 344 block: "center", 345 behavior: "smooth" 346 }, false); 347 history = s; 348 } 349 }); 350 audioDom.addEventListener("pause", function() { 351 console.log("暂停"); 352 $(".playOrPause").removeClass("pause"); 353 $(".playOrPause").addClass("play"); 354 }); 355 audioDom.addEventListener("play", function() { 356 // console.log(audioDom) 357 console.log("播放"); 358 $(".playOrPause").removeClass("play"); 359 $(".playOrPause").addClass("pause"); 360 }); 361 audioDom.addEventListener("volumechange", function() { 362 // console.log(audioDom.volume); 363 $(".volume-bar, .volume-ball").css("margin-top", 90 * (1 - audioDom.volume) + "px"); 364 }); 365 // audioDom.addEventListener("ended", function () { 366 // console.log("yy"); 367 // timer(); 368 // return; 369 // }); 370 $(".playContent .eachSong").eq(thisNum).addClass("choosedSong").siblings().removeClass("choosedSong"); 371 $(".choosedSong").attr("id", "choosedSong").siblings().attr("id", ""); 372 if (document.getElementById("choosedSong")) { 373 document.getElementById("choosedSong").scrollIntoView(true); 374 } 375 $(".playContent .eachSong").hover(function() { 376 $(this).toggleClass("eachSongHhover"); 377 $(this).siblings.removeClass("eachSongHhover"); 378 }); 379 $(".eachSong").click(function() { 380 console.log($(this).index()); 381 thisNum = $(this).index() - 1; 382 getData(thisNum); 383 }); 384 } 385 var music_resize = function() { 386 $(".panelContent").css("height", $(window).height()); 387 }; 388 music_resize(); 389 $(window).resize(function() { 390 music_resize(); 391 }); 392 /** 393 * 切歌 394 */ 395 var timer = function(click) { 396 changeThisNum(click); 397 setTimeout(function() { 398 getData(thisNum); 399 $("#selectData").val(thisNum); 400 document.getElementById("m-con").scrollIntoView(false); 401 }, 500); 402 // setTimeout(function () { 403 // audioDom.play(); 404 // }, 1000); 405 }; 406 /** 407 * 下一首 408 */ 409 $(".playNext").click(function() { 410 // if (thisNum < data.length - 1) { 411 // clickToChange = false; 412 // } 413 timer(true); 414 }); 415 /** 416 * 上一首 417 */ 418 $(".playLast").click(function() { 419 if (thisNum >= 0) { 420 clickToLast = true; 421 } 422 timer(false); 423 }); 424 /** 425 * 获取分秒 426 */ 427 function formatSeconds(value) { 428 var theTime = parseInt(value); // 秒 429 var theTime1 = 0; // 分 430 if (theTime > 60) { 431 theTime1 = parseInt(theTime / 60); 432 theTime = parseInt(theTime % 60); 433 } 434 var result = "" + parseInt(theTime); 435 if (result < 10) { 436 result = "0" + result; 437 } 438 if (theTime1 < 10) { 439 result = "0" + parseInt(theTime1) + ":" + result; 440 } else { 441 result = "" + parseInt(theTime1) + ":" + result; 442 } 443 return result; 444 } 445 /** 446 * 播放/暂停 447 */ 448 $(".playOrPause").click(function() { 449 if (audioDom.paused) { 450 if (data.length > 0) { 451 audioDom.play().catch(err => { 452 alert(err); 453 });; 454 } 455 } else { 456 audioDom.pause(); 457 } 458 }); 459 /** 460 * 声音 461 */ 462 $(".changeVolume").click(function() { 463 // console.log(audioDom.muted); 464 if (audioDom.muted) { 465 audioDom.muted = false; 466 setMutsed = false; 467 audioDom.volume = mutsedValue; 468 $(".changeVolume").removeClass("noVolume"); 469 $(".changeVolume").addClass("volume"); 470 } else { 471 audioDom.muted = true; 472 setMutsed = true; 473 audioDom.volume = 0; 474 $(".changeVolume").removeClass("volume"); 475 $(".changeVolume").addClass("noVolume"); 476 } 477 }); 478 /** 479 * 循环播放等 480 */ 481 $(".changePlayMode").click(function() { 482 $(".playStyleList").toggleClass("changeDisplay"); 483 event.stopPropagation(); 484 }); 485 $(".panelContent").click(function() { 486 $(".playStyleList").removeClass("changeDisplay") 487 }); 488 /** 489 * 下载 490 */ 491 $(".changeShare").click(function() { 492 alert("不给 <( ̄︶ ̄)↗[GO!]"); 493 }); 494 /** 495 * 隐藏控制台 496 */ 497 $(".showOrHideControl").click(function() { 498 $(this).toggleClass("showControl"); 499 $(".playList").removeClass("showPlayList"); 500 $(".musicControl").toggleClass("showMusicControl"); 501 }); 502 /** 503 * 歌曲列表 504 */ 505 $(".controlList").hover(function() { 506 $(".listIcon").toggleClass("newListIcon"); 507 }); 508 $(".listIcon").click(function() { 509 $(".playList").toggleClass("showPlayList"); 510 }); 511 $(".icon-close").click(function() { 512 console.log(12); 513 $(".playList").toggleClass("showPlayList"); 514 }); 515 $(".each-control:first").hover(function() { 516 $(".volumeControl").show(); 517 }, function() { 518 $(".volumeControl").hide(); 519 }); 520 $(".icon-trash").click(function() { 521 audioDom.pause(); 522 data = []; 523 // console.log(data); 524 $(".posterImg").css("display", "block"); 525 $(".poster").css("background", "none"); 526 $(".controlPosterImg").css("background-image", ""); 527 $(".lrcName").html("啥都没有呀🙃"); 528 $(".lrcDetail").css("display", "none"); 529 $(".lrc").html("暂无播放歌曲,刷新页面啦🙄"); 530 $(".lrc").css("color", "#a2aab2"); 531 $(".lrc").css("font-size", "16px"); 532 $(".songMsgLeft").html("网页音乐就是牛"); 533 $(".getduration").html("00:00"); 534 $(".getCurrentTime").html("00:00"); 535 $(".playListLength").html(0); 536 $(".listNum").html(0); 537 $(".playContent .eachSong").remove(); 538 $(".playContentNull").css("display", "flex") 539 }); 540 window.document.onkeydown = function(event) { 541 var event = event || window.event; 542 if (event.preventDefault) { 543 event.preventDefault(); 544 } else { 545 window.event.returnValue = false; 546 } 547 // console.log(event.keyCode); 548 if (event.ctrlKey && event.keyCode == 120) { 549 $(".playNext").click(); 550 } else if (event.ctrlKey && event.keyCode == 119) { 551 $(".playLast").click(); 552 } else if (event.ctrlKey && event.keyCode == 117) { 553 if (audioDom.paused) { 554 if (data.length > 0) { 555 audioDom.play().catch(err => { 556 alert(err); 557 }); 558 } 559 } else { 560 audioDom.pause(); 561 } 562 } else if (event.ctrlKey && event.keyCode == 123) { 563 $(".changeVolume").click(); 564 } else if (event.ctrlKey && event.keyCode == 122) { 565 if (audioDom.volume < 1) { 566 audioDom.volume += 0.1; 567 } 568 if (audioDom.volume > 0.1) { 569 $(".changeVolume").removeClass("noVolume"); 570 $(".changeVolume").addClass("volume"); 571 } 572 } else if (event.ctrlKey && event.keyCode == 121) { 573 if (audioDom.volume >= 0.1) { 574 audioDom.volume -= 0.1; 575 } 576 if (audioDom.volume < 0.1) { 577 $(".changeVolume").removeClass("volume"); 578 $(".changeVolume").addClass("noVolume"); 579 } 580 } 581 }; 582 /** 583 * 歌曲进度条拖动 584 */ 585 var scroll = document.getElementsByClassName('progressBg')[0]; 586 var ball = document.getElementsByClassName('progressBall')[0]; 587 var bar = document.getElementsByClassName('progressBar')[0]; 588 var balleft = 0; 589 $(".Ball").mousedown(function(event) { 590 var event = event || window.event; 591 var leftVal = event.clientX - $(".progressBg").offset().left - 6; 592 audioDom.currentTime = audioDom.duration * (leftVal / scroll.offsetWidth); 593 }); 594 ball.onmousedown = function(event) { 595 var event = event || window.event; 596 var leftVal = event.clientX - this.offsetLeft; 597 var that = this; 598 document.onmousemove = function(event) { 599 var event = event || window.event; 600 balleft = event.clientX - leftVal; 601 if (balleft < 0) 602 balleft = 0; 603 else if (balleft > scroll.offsetWidth - ball.offsetWidth) 604 balleft = scroll.offsetWidth - ball.offsetWidth; 605 audioDom.currentTime = audioDom.duration * (balleft / scroll.offsetWidth); 606 //防止选择内容--当拖动鼠标过快时候,弹起鼠标,bar也会移动 607 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); 608 } 609 }; 610 document.onmouseup = function() { 611 document.onmousemove = null; //弹起鼠标不做任何操作 612 }; 613 /** 614 * 音量进度条拖动 615 */ 616 var volumeScroll = document.getElementsByClassName('volume-barHome')[0]; 617 var volumeBall = document.getElementsByClassName('volume-ball')[0]; 618 var volumeBarHome = document.getElementsByClassName('volume-barHome')[0]; 619 var balbottom = 0; 620 $(".volume-barHome").mousedown(function(event) { 621 var event = event || window.event; 622 // console.log($(window).height() - event.clientY - 12); //导航条底部 676导航底部据页面顶部的距离 586导航头部据页面顶部的距离 623 var balbottom = $(window).height() - event.clientY - 12 - 83; 624 // console.log($(window).height() - 95); 625 audioDom.volume = balbottom / 90; 626 mutsedValue = audioDom.volume; 627 $(".volume-bar, .volume-ball").css("margin-top", 90 - balbottom + "px"); 628 // $(".volume-ball").css("margin-top", 90 - balbottom + "px"); 629 // console.log(audioDom.volume); 630 }); 631 volumeBall.onmousedown = function(event) { 632 var event = event || window.event; 633 var windowHeight = $(window).height(); 634 var bottomVal = $(window).height() - 92; 635 var that = this; 636 // console.log("输出导航底部据页面顶部的距离"); 637 // console.log($(window).height() - 92); 638 document.onmousemove = function(event) { 639 var event = event || window.event; 640 var ballBottom = event.clientY - (bottomVal - 90); 641 if (ballBottom < 0) { 642 ballBottom = 0; 643 } else if (ballBottom > 90) { 644 ballBottom = 90; 645 } 646 $(".volume-bar, .volume-ball").css("margin-top", ballBottom + "px"); 647 // $(".volume-ball").css("margin-top", ballBottom + "px"); 648 audioDom.volume = (90 - ballBottom) / 90; 649 mutsedValue = audioDom.volume; 650 // audioDom.currentTime = audioDom.duration * (balleft / (scroll.offsetWidth - ball.offsetWidth)); 651 //防止选择内容--当拖动鼠标过快时候,弹起鼠标,bar也会移动 652 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); 653 } 654 }; 655 }); 656 </script> 657 </body> 658 659 <!-- <p>图片api等素材均取自酷狗音乐</p> --> 660 <!-- <p>大概做完之后未做太多修改,可能存在些不足之处,望见谅</p> --> 661 662 </html>