基于Electron的在线音乐播放器开发


前言

码云地址: 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)

总结

记录开源生活,用代码去实现想实现的,在不断的实践中领悟代码的真正意义。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值