日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

通过网易云api实现一个简单的音乐播放器

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通过网易云api实现一个简单的音乐播放器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這次文章我來實現一個簡易的播放器,這里調用了網易云的api來獲取他的音樂,可以自行下載其文件,本次案例需要?nodejs?來獲取接口,需要通過ajax來請求數據,實現功能有搜索音樂并顯示列表,展示歌詞等,本次實現get請求的封裝,以及有富含js封裝函數的思想,模塊化開發?狀態化處理,說這3個我有點不配啊🤢 只是普通的案例涉及一點這些思想

還是那句話先來效果看下,有點丑,希望大家不要介意?🌹🌹🌹 這里吹以下漠河舞廳真的好聽

首先運行網易云api,由于是我之前的一個案例,這里忘了在哪里找的api了可以自行查找去下載。安裝后打開cmd輸入 node app.js運行3000端口

?首先準備容器直接放代碼 css就不放了有點丑,這里的搜索列表是先通過position隱藏起來的之后在js里再改變其position將其展示(調整top值,讓他在頁面上面)

<div><input type="text" id="keyword"><button id="search-button">搜索</button></div><!-- 搜索列表 --><div class="search-list"><ul id="result-list"></ul></div><!-- 歌詞容器 --><div class="lrc-all-warp"><ul id="lrc-warp"></ul></div><!-- 音頻 --><audio src="" id="audio" controls></audio><script src="./music.js"></script>

然后就是最主要的js了

先來封裝以下ajax的get請求,因為搜索音樂要頻繁的調用ajax請求,每次都調用太過浪費,只在搜素/獲取音樂鏈接的時候發一次,

先放一波常規的ajax請求 發起請求得到數據,將數據修改字符串性質,這里的http://localhost:3000/search?keywords=啦啦啦,簡易參考下3000端口的內容,會告訴該怎么獲取內容

var xhr =new XMLHttpRequest() // xhr.open('get','http://localhost:3000/search?keywords=啦啦啦',true) // xhr.send() // xhr.onreadystatechange=function(){ // if(xhr.status==200&&xhr.readyState==4){ // // 獲取成功的結果 // console.log(JSON.parse(xhr.response)) // // 返回的結果是一個JSON的字符串 // // 怎么處理JSON格式的字符串 // // 變成JS對象數據類型方便我們使用 // // 獲取音樂名字 // var result=JSON.parse(xhr.response) // var songs= result.result.songs // console.log(songs) // // 放歌 // var firstSongId=songs[0].Id // xhr.open('get','http://localhost:3000/song/url?id='+firstSongId,true) // xhr.send() // }

接下來就擼起袖子加油干!實現get的ajax請求封裝 ,拼接字符串實現 ,url是路徑,data是要請求的參數,也就是query參數,callback比較重要,是回調函數,如果調用get方法有回調函數,就會把JSON.parse(xhr.response)當成參數來給該函數。之后的請求會基于這個回調再獲取數據,再通過他們的回調獲取數據,其實這里有點回調地獄的意思了,我promise沒學好,沒給他改好,先對付看吧

// get請求包裝 把ajax包裝成get方法 var get = function (url, data, callback) {var xhr = new XMLHttpRequest()var param = '?'for (var key in data) {if (data.hasOwnProperty(key)) {param += key + '=' + data[key] + '&'}}param = param.slice(0, param.length - 1)// http://localhost:3000/song/url?id=123456 要這樣的形式 ?id=123456xhr.open('GET', url + param, true)xhr.send()xhr.onreadystatechange = function () {if (xhr.status == 200 && xhr.readyState == 4) {if (callback) {callback(JSON.parse(xhr.response))}}} }

第二層封裝,封裝一些常用的方法

首先是一個搜索音樂的函數 ,這里就通過給get傳遞回調函數獲取通過請求得到的數據也就是JSON.parse(xhr.response),還有一個回調🐱?👤,與上面同理,如果存在就把數據通過回調函數傳過去

// 建立一個搜索函數 var search = function (keywords, callback) {get('http://localhost:3000/search', {keywords: keywords}, function (res) {if (callback) {// 歌在res的result的songs里 此時的res為get()里的callback()里的JSON.parse(xhr.response)callback(res.result.songs)}}) }

播放封裝

// 播放封裝 獲取url封裝 var getSongUrl = function (id, callback) {get('http://localhost:3000/song/url', {id: id}, function (res) {if (callback) {// 音樂播放鏈接callback(res.data[0].url)}}) }

獲取歌詞封裝

var getLrc = function (id, callback) {get('http://localhost:3000/lyric', {id: id}, function (res) {// console.log(res)var lrcString = res.lrc.lyricif (callback) {callback(lrcString)}}) }

這些url以及數據都在3000端口有說的

先來倆個簡單的函數,打開列表和關閉列表

// 構造打開列表關閉列表方法 用的時候調用就好了 var closeSearchList = function () {searchList.className = 'search-list' } var openSearchList = function () {searchList.className = 'search-list active' }

渲染搜索列表方法 這里resultList獲取的是渲染列表的ul元素 參數為key也就是到時候輸入框獲取的value值,并且傳遞回調函數為參數

使用一個模板來更換ul列表的innerHTML?

var resultList = document.getElementById('result-list') var renderSearchList = function (key) {search(key, function (res) {console.log(res)// 模板 class方便點擊事件 data-id為了存儲歌曲idvar tpl = '<li class="songs" data-id="{--id--}">' +'<h3>{--name--}</h3>' +'<h5><span>{--geshou--}</span> - 專輯:<span>{--zhuanji--}</span></h5>' +'<hr>' +'</li>'var html = ''for (var i = 0; i < res.length; i++) {html += tpl.replace('{--name--}', res[i].name).replace('{--geshou--}', res[i].artists[0].name).replace('{--zhuanji--}', res[i].album.name).replace("{--id--}", res[i].id)}resultList.innerHTML = htmlopenSearchList()// 不要在一個方法構造實現另一個方法// searchList.className='search-list active'addEventListener()}) }

這里不直接改變列表的類名來更改樣式,而是用了個函數來進行封裝,也體現了函數封裝的思想,一個代碼應該這樣他的功能邏輯和函數多少成反比的是。而且這樣多的模塊可以更好的實現復用以及維護。這才是我這篇文章想向你們表達的東西,更多的實現功能函數,每個方法都是一個函數,達到模塊化代碼

?接下來獲取輸入框想聽的音樂,并且調用獲取列表方法展示列表

// 點擊按鈕 獲取Input里的輸入值 var searchButton = document.getElementById('search-button') var keywordInput = document.getElementById('keyword')searchButton.addEventListener('click', function () {var value = keywordInput.value// 將input的輸入值代入renderSearchList函數里renderSearchList(value)})

接下來就是點擊列表里的音樂來進行播放了,這里我已經詳細把注釋寫在上面了,這里的songs是之前渲染模板增加的類名,并且把音樂id存儲在data-id屬性中了,下面的展示歌詞和清空歌詞下main會說

var audio = document.getElementById('audio') // 做一個li點擊事件方法 var addEventListener = function () {var songs = document.getElementsByClassName('songs')for (var i = 0; i < songs.length; i++) {songs[i].addEventListener('click', function () {// getAttributevar id = this.getAttribute('data-id')// 通過getSongUrl方法來播放音樂getSongUrl(id, function (url) {// 通過獲取audio來播放音樂 通過src來播放audio.src = url// 與視頻一樣play()開始播放audio.play()closeSearchList()// searchList.className='search-list'})// 展示歌詞getLrc(id, function (res) {var lrc = parseLrc(res)console.log(lrc)fillLrc(lrc)})// 清空歌詞var lrcWarp = document.getElementById('lrc-warp')if(lrcWarp){lrcWarp.innerHTML=''}})} }

接下來就是解析歌詞以及展示歌詞了,通過api獲取的歌詞格式和要使用的歌詞有點不太一樣,我們得把他解析我們要用的格式,概念寫在下面,時間戳是用來到時候來展現歌詞高亮用的

[03:06.466]晚星就像你的眼睛殺人又放火\n把字符串轉化為數組需要的格式 把字符串準換為對象格式{time:186.466,content:'晚星就像你的眼睛殺人又放火'}

解析歌詞方法,方法詳細寫在了注釋上,先把歌詞與時間分離開,在格式化時間

// 歌詞 // [03:06.466]晚星就像你的眼睛殺人又放火\n var parseLrc = function (lrcString) {// 將時間字符串類型轉化為number類型 做函數var parseTime = function (timeString) {// 切割分鐘和秒 會分為倆項var timeStringArr = timeString.split(':') //["01","51.73"]var min = parseInt(timeStringArr[0]) //01var s = parseFloat(timeStringArr[1]) //51.73var totalTime = (min * 60 + s) * 1000return parseInt(totalTime)}var lrcArr = []// 通過split()方法來用'\n'分割歌詞lrcArr = lrcString.split('\n')//把每一行存儲時間和內容var lrcObjArr = []// 遍歷 通過split()方法來用']'分割歌詞內容與事件for (var i = 0; i < lrcArr.length; i++) {var lines = lrcArr[i].split(']')//提取時間,通過把 [03:06.466 的 [ 用slice()給切割 得到03:06.466 slice(1,lines[0].length從1開始切(保留)到length最后 仍掉數組[0]var time = parseTime(lines[0].slice(1, lines[0].length))// 內容var content = lines[1]// console.log(time, content)// console.log(lines,time)//錯誤處理 如果某一行解析不對直接跳過這一行 //continue在foreach()里用不了if (content == undefined || isNaN(time)) {continue}lrcObjArr.push({// 因為要把字符串時間轉化為數組類型,所以在這里就處理了time: time,content: content})};// console.log(lrcObjArr)return lrcObjArr }

接下來就是封裝歌詞填充的方法,同樣定義模板字符串來拼接通過replace方法來替換

// 模板 var tpl = '<li class="lrc-item">{--content--}</li>' // 歌詞填充 var lrcWarp = document.getElementById('lrc-warp') var fillLrc = function (lrcObjArr) {var html = ''for (var i = 0; i < lrcObjArr.length; i++) {html += tpl.replace('{--content--}', lrcObjArr[i].content)}lrcWarp.innerHTML = htmlnowLrcObject = lrcObjArr }

接下來就是令歌詞滾動并且展示高亮了? 🐱?👤都碼累了

// 歌詞滾動 var index = 0 // 初始距離 var marginTop=240 var nowLrcObject = [] // 對比歌詞 var compareLrc = function () {// 在html中獲取全部的歌詞var lrcItem = document.getElementsByClassName('lrc-item')// 對比時間,確定那一句歌詞播放if (nowLrcObject[index].time - audio.currentTime * 1000 < 300) {lrcItem[index].style.color = 'red'// 歌詞向上移動20pxmarginTop-=20lrcWarp.style.marginTop=marginTop+'px'lrcItem[index].style.fontSize = '1.2em'// 將上一句的高亮去掉if(index-1>-1){lrcItem[index-1].style.color = ''lrcItem[index-1].style.fontSize = ''}index++}}

最后通過timeupdata事件函數來調用對比歌詞方法

// 在這里timeupdate對比 audio.addEventListener('timeupdate', function () {compareLrc() })

現在就可以聽音樂了!

模塊化開發 ,屁大點事也要寫個函數? 一個函數應該只關心另外一個函數給我們提供的功能,而不參與他的實現。這就是我本篇文章的內容,希望可以得到大家的見解和指摘,感謝大家觀看

總結

以上是生活随笔為你收集整理的通过网易云api实现一个简单的音乐播放器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。