博客地址:https://ainyi.com/59
閑言碎語:
有好幾天沒有發表博客了,這也是因為一直開發音樂和完善我的博客項目,好不容易抽出時間總結一下這幾天所做的東西,還這么多課,實則匆忙
今天難得逃了一次課,就趁這時間,該寫寫就寫寫吧~~
進入正題:Lily_music
本次開發,參照本人之前所做的 樂詩博客(文末會說到)的相關播放控制等功能,繼續優化的結果。
前端模仿qq音樂界面,然后在此之上進行修改的界面,並使用了一點 es6 的語法
話說個人挺喜歡qq音樂界面的,簡潔,當然也少不了背景模糊插件以及滾動條美化相關插件,
也用到了彈窗、點擊復制歌曲鏈接和歌詞鏈接相關功能,但是目前歌曲分享功能暫未實現、后續....
致謝:歌曲搜索參照某位大佬封裝的 qq 音樂的 api,UI 界面參照另一位大神的一些解決方案,在此表示感謝
相關鏈接:
那么相關使用的開源插件有:
jQuery官方類庫:https://jquery.com/
layer彈窗插件:http://layer.layui.com/
復制粘貼庫插件:https://www.npmjs.com/package/clipboard-js
mCustomScrollbar滾動條美化插件:http://manos.malihu.gr/jquery-custom-content-scroller/
background-blur背景圖片模糊特效插件:https://msurguy.github.io/background-blur/
還有播放、控制、歌詞解析、搜索、加載動畫sg類庫等功能全部手寫,爽的不行。
溫馨提醒:
本播放器並不需要什么特別的運行環境,直接下載打開就能用了 ^_^
響應式優化,可在各種大小的設備運行打開
音樂搜索的結果均來自 qq音樂 (后續會繼續擴大到多個平台)
本播放器還有一些 bug,需求就是不斷滿足的,虛心請教...
談談開發:
果斷使用的是 H5 播放器,十分好用
一般在做這種播放器的開發,要多多使用面向對象的開發思想。
定義一個播放器對象,相關參數、方法如下:
播放器對象:krAudio
參數:
播放器:audioDom
進度條鎖定:locked:true
進度條按下的鎖:kdown
靜音的鎖:flag_volume
當前音量:curentVoice
當前播放的列表序號:Currentplay
當前播放列表歌曲總數:allItem
播放模式,1為列表循環:orderModes
方法:
播放器初始化:init
設置播放的音樂地址:seturl
播放:play
暫停:stop
播放時間監聽及處理:time
時間格式化:format
下一首:next
上一首:prev
播放模式:ordermode
拖動進度條:controlTime
拖動音量條:controlVoice
上面部分的參數及方法基本涵蓋播放器該有的功能
歌詞解析,我之前做的樂詩博客采用自己寫的一種歌詞解析滾動播放的方法:
首先明白一般歌詞的形式是:[00:13.80]期望飛上恬靜月球遙望每家的窗 [00:18.24]誰伴深愛細味露台玫瑰香
這樣子的形式,利用 ajax 異步請求到歌詞文件,然后就可以進行字符串裁剪,單單取出時間和歌詞,一一對應
1 loadLrc:function(){//加載歌詞 2 var vallrc = $(".hidetextlrc").text(); 3 //如果沒有上傳歌詞或者刪除了歌詞 4 if(!vallrc || $(".is_deleteLrc").text() == 1){ 5 $(".lrc_content_notext").text("暫無歌詞"); 6 $(".lrc_content_notext").show(); 7 return; 8 } 9 var isHrefLrc = $(".is_href_lrc").text(); 10 //如果是上傳的歌詞,那就要拼接上服務器地址 11 if(isHrefLrc == 0) vallrc = basePath + "/" + vallrc; 12 $.ajax({ //異步請求獲取本地歌詞 13 url:vallrc, 14 type:"post", 15 success:function(data){ 16 //第一次分離歌詞 17 var lrcArr = data.split("["); 18 //存放分離后的歌詞 19 var html = ""; 20 var lrclast = null; //記錄上一行的歌詞 21 var lrcmes = null; //記錄當前行的歌詞 22 var bofo = -1; //記錄上一行歌詞的秒數 23 var ms = -1; //當前這一行的秒數 24 for(var i = 0;i < lrcArr.length;i++){ 25 //第二次分割歌詞,變成["03:01.08","這個世界變得更加美麗"],數組以逗號分隔 26 var arr = lrcArr[i].split("]"); 27 //取到數組arr下標為1的歌詞部分 28 //將上一行的歌詞賦值給lrclast 29 lrclast = lrcmes; 30 //得到當前歌詞 31 lrcmes = arr[1]; 32 //取到時間 33 var time = arr[0].split("."); //變成["03:01","08"] 34 //取到time下標為0的分鍾和秒 35 var ctime = time[0].split(":"); //變成["03","01"]; 36 //將上一行的秒數賦值給bofo 37 bofo = ms; 38 //轉化成秒數 39 ms = ctime[0]*60 + ctime[1]*1; 40 //如果上一行和當前行秒數相同,則當前行秒數++ ,解決秒數相同的辦法 41 if(bofo == ms){ 42 ms++; 43 }else if(ms >= 0){ 44 if(!isNaN(bofo)){ //如果是數字 45 var classeName = "l_"+bofo; 46 var concon = bofo;//bofo會自增,所以下面for循環條件用這個變量來代替 47 for(var j = 0;j < ms-concon-1;j++){ 48 classeName += " l_"+ ++bofo; 49 } 50 if(ms>=0 && lrclast != null){ 51 html += "<li class='"+classeName+"'>"+lrclast+"</li>"; 52 } 53 } 54 } 55 } 56 //裝載最后一行歌詞的機制,先獲取歌曲總時間 57 setTimeout(function(){ 58 var allall = krAudio.audioDom.duration; 59 var classlaName = "l_"+ms; 60 var conben = ms; //ms會自增,所以下面for循環條件必須用這個變量來代替 61 for(var j = 0;j < allall-conben-1;j++){ 62 classlaName += " l_"+ ++ms; 63 } 64 html += "<li class='"+classlaName+"'>"+lrcmes+"</li>"; 65 //把解析好的歌詞放入歌詞展示區中 66 $("#lrcly").html(html); 67 $("#lyrics").html(html); 68 },200); 69 } 70 }); 71 // 聯動音樂播放歌詞 72 krAudio.audioDom.addEventListener("timeupdate",function(){ 73 //獲取當前播放時間,獲得的是秒數 74 var time = this.currentTime; 75 //解析音樂對應的時間 76 var m = parseInt(time / 60);//獲取此時的分鍾 77 var s = parseInt(time); //轉換int類型,獲取此時的秒數 78 $(".l_"+s).addClass("lrcsel").siblings().removeClass("lrcsel"); 79 //歌詞滾動條,使歌詞在中間的計算公式: 80 //第n行歌詞*li的高度-歌詞區域中間的li(就是包括這個li,取這個li的一半)以上的li的總高度 81 //局部歌詞的控制 82 $(".lrc_content_box").stop().animate({ 83 scrollTop:(($(".lrcsel").index()+1)*29 - 145)//減去偏差,使當前歌詞在中間 84 },240); 85 //全屏歌詞的控制 86 $("#lyrics").stop().animate({ 87 scrollTop:(($(".lrcsel").index()+1)*24 - 168)//減去偏差,使當前歌詞在中間 88 },240); 89 }); 90 },
這種歌詞解析、聯動播放的進度進行滾動是我之前樂詩博客采用的一種方案,感覺也不錯
此次采用另一種解析方式,利用 js 正則表達式全部替換的方式
替換方式:
1 var reg = /-/g; // g表示全部替換 ,要替換的字符串是- 2 createTime = createTime.replace(reg,"/"); // 第二個參數表示替換成 / 3 //替換成2018/04/03
歌詞解析:
1 //解析歌詞 2 function parseLyric(lrc) { 3 var lyrics = lrc.split("\n"); 4 var lrcText = {}; 5 for(var i=0;i<lyrics.length;i++){ 6 var lyric = decodeURIComponent(lyrics[i]); 7 var timeReg = /\[\d*:\d*((\.|\:)\d*)*\]/g; 8 var timeRegExpArr = lyric.match(timeReg); 9 if(!timeRegExpArr)continue; 10 var clause = lyric.replace(timeReg,''); 11 for(var k = 0,h = timeRegExpArr.length;k < h;k++) { 12 var t = timeRegExpArr[k]; 13 var min = Number(String(t.match(/\[\d*/i)).slice(1)), 14 sec = Number(String(t.match(/\:\d*/i)).slice(1)); 15 var time = min * 60 + sec; 16 lrcText[time] = clause; 17 } 18 } 19 return lrcText; 20 }
這樣子解析出來的是一個對象,存放着鍵值對,鍵:時間(秒),值(歌詞)
就可以直接做一個 for in 循環將每句歌詞添加到歌詞區域,將時間添加到每句歌詞的樣式控制class
根據每句歌詞的時間,就可以在播放器的 timeupdate 監聽事件里實現滾動播放歌詞了
鼠標拖動進度條的時候,有三個監聽事件,
按下:onmousedown
移動:onmousemove
彈起:onmouseup
這里鼠標移動事件需要放在鼠標按下事件里面,當鼠標彈起時,在里面清除移動、彈起兩個事件,以免彈起時還執行鼠標按下拖動事件(也可以定義一把鎖來控制)
還有很多細節點的問題,上一曲下一曲臨界值、搜索后的播放控制、列表小菜單與主按鈕之間的聯動、三種播放模式等等等等... 有坑也有歡笑
另外給大家提供一個判斷非空的方法:
1 //判斷非空 2 function isEmpty(val) { 3 val = $.trim(val); 4 if (val == null) 5 return true; 6 if (val == undefined || val == 'undefined') 7 return true; 8 if (val == "") 9 return true; 10 if (val.length == 0) 11 return true; 12 if (!/[^(^\s*)|(\s*$)]/.test(val)) 13 return true; 14 return false; 15 }
ES6 都出來了,那當然要好好使用,在字符串拼接的代碼,均使用 es6 語法,十分好用
截圖展示:
項目鏈接:
在線演示:https://www.ainyi.com/Lily_music/
git:https://github.com/Krryxa/Lily_music
樂詩博客是一個音樂、日記分享平台,我們致力於讓用戶發表自己的心情,分享自己喜愛的音樂,聆聽你我的聲音。歡迎訪問 ^_^
博客地址:https://ainyi.com/59
版權所有,轉載請注明出處


