前言
码云地址: https://gitee.com/kiven-lst/music.
本文用Electron技术搭配vue,scss,爬虫,cheerio,html,nodejs,audio等不同部件协作开发了一款在线搜索网易云和酷我音乐两大库源的在线音乐播放器,UI精致,动态效果十足。
一、Electron是什么?
Electron提供了丰富的本地(操作系统)的API,使你能够使用纯JavaScript来创建桌面应用程序。与其它各种的Node.js运行时不同的是Electron专注于桌面应用程序而不是Web服务器。Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作是专注于桌面应用的,io.js 的一个变体。这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相反,Electron 使用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 控制的,精简版的 Chromium 浏览器。
二、使用步骤
1.引入库
渲染进程引入的库
const { ipcRenderer } = require('electron')
const request = require('request')
const cheerio = require('cheerio')
主进程引入的库
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const fs = require('fs');
const { decode } = require('querystring');
const csv = require('csvtojson')
2.技术点分析
整个软件采用vue作为基本架构,这都取决于vue对于动态渲染数据的方便性
这里需要将外部调用的库加入到vue的原型链中方便在vue中使用。
Vue.prototype.$request = request
Vue.prototype.$cheerio = cheerio
Vue.prototype.$ipcRenderer = ipcRenderer
这里加入了15s无操作息屏事件
主要思想就是开局注册一个定时事件,15s息屏,如果有操作则注销该事件重新注册,核心思想和防抖一样
// 设置15s无操作息屏事件
origin() {
this.timer = setTimeout(() => {
this.flag = 1
this.isFadeOut = true
}, 15000);
},
// 鼠标移动禁止息屏事件
move() {
document.body.addEventListener('mousemove', () => {
if (this.flag == 1) {
this.flag = 0
this.isFadeOut = false
}
clearTimeout(this.timer)
this.origin()
})
},
最为复杂的就是切歌和播放歌曲部分了,需要区分是播放暂停还是切换下一首新歌,同时还需要在我的喜欢和搜索结果中判断是否在两个板块中切换,并且需要避免添加同一首歌等等逻辑操作。
// 点击页面的歌曲进行判断是否播放,切歌,暂停,添加喜欢,剔除相同喜欢歌曲,图标旋转等一系列复杂逻辑
submit(e1, e2, e3, e4, e5, e6) {
if (e3 != this.event || this.clientWidth != e5.srcElement.clientWidth) {
this.songName = "缓冲中..."
this.title.innerHTML = "极简音乐"
this.songAuthor = ""
this.timeLength = "00:00"
clearInterval(this.InterVal)
e6 = parseInt(e6)
switch (e6) {
case 1:
this.audio.src = 'https://music.hwkxk.cf/api/?id=' + e4 + '&source=kuwoST'
break;
case 2:
this.audio.src = 'https://music.hwkxk.cf/api/?source=WYHD&id=' + e4
break
}
this.audio.oncanplaythrough = () => {
this.audio.play()
clearInterval(this.InterVal)
this.rotateImg()
this.songName = e1
this.title.innerHTML = e1 + '-' + e2
this.songAuthor = e2
this.process.max = this.audio.duration
var minute = Math.floor(this.audio.duration / 60)
var showMinute = minute >= 10 ? minute.toString() : '0' + minute
var second = (Math.floor(this.audio.duration) % 60).toFixed()
var showSecond = second >= 10 ? second.toString() : '0' + second
this.timeLength = showMinute + ':' + showSecond
}
this.audio.addEventListener('timeupdate', () => {
this.process.value = this.audio.currentTime
var minute = Math.floor(this.audio.currentTime / 60)
var showMinute = minute >= 10 ? minute.toString() : '0' + minute
var second = (Math.floor(this.audio.currentTime) % 60).toFixed()
var showSecond = second >= 10 ? second.toString() : '0' + second
this.currentTime = showMinute + ':' + showSecond
})
this.event = e3
this.clientWidth = e5.srcElement.clientWidth
if (e5.srcElement.className === "playList") {
for (var i = 0; i < this.loves.length; i++) {
if (this.loves[i].url == e4) {
return
}
}
this.id++
this.loves.push({ name: e1, author: e2, url: e4, flag: e6 })
}
if (this.loves.length > 50) {
this.loves.shift()
}
}
else {
if (this.audio.paused) {
this.audio.play()
this.rotateImg()
}
else {
this.audio.pause()
clearInterval(this.InterVal)
}
}
},
其次就是搜索中爬虫应用了,需要对爬取结果解析得到歌手名和歌曲id。
// 搜索爬取歌曲网页,并解析歌曲id和歌曲名字及歌手名字
explore() {
this.isLoading = false
var temp = this.isEmerge
this.isEmerge = true
this.songs = []
var exploreValue = encodeURI(this.$refs.input1.value)
var options = [{
url: 'https://music.hwkxk.cf/?kw=' + exploreValue + '&source=kuwo',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
}
},
{
url: 'https://music.hwkxk.cf/?kw=' + exploreValue + '&source=wy',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
}
},
];
for (let i = 0; i < 2; i++) {
this.$request(options[i], (err, response, data) => {
let result = []
let id = []
if (response.statusCode == 404) {
let option = {
title: "数据请求失败",
body: "请检查网络连接,也有可能服务器跑丢了"
}
new Notification(option.title, option)
return
}
let $ = this.$cheerio.load(data)
$('td[class=song-name]').each((index, element) => {
if (index == 0) { }
else {
let temp = $(element).text().split('-')
result.push({
name: temp[1],
author: temp[0],
flag: i + 1,
url: ""
})
}
})
$('td[class=song-bitrate] a').each((index, element) => {
if ($(element).hasClass('btn-info')) {
id.push($(element).attr('href').match(/\d+/g))
}
})
for (var j = 0; j < result.length; j++) {
result[j].url = id[j][0]
this.songs.push(result[j])
}
this.isLoading = true
this.isEmerge = temp
})
}
},
最后就是设置的播放图标播放旋转,暂停停止。需要在不同的时刻注册旋转和注销旋转事件,来满足这种效果。
// 使播放图标进行旋转
rotateImg() {
this.InterVal = setInterval(() => {
var img = document.getElementById('img')
this.rotateVal += 1
img.style.transform = 'rotate(' + this.rotateVal + 'deg)'
img.style.transition = 'all 0.1s linear'
}, 100)
},
clearInterval(this.InterVal)
总结
记录开源生活,用代码去实现想实现的,在不断的实践中领悟代码的真正意义。