从一个简单的音乐播放器,竟然要用到这么些东西?

1,909 阅读4分钟

前几天写了一个简易的音乐播放器,也收到了大家的一些反馈。最大的问题就是总是资源失效,针对这一点昨天我进行了一次重写,也把重构过程中的一些知识点和心得记录下来与大家一起分享。 没怎么写过文章,语句不通或者错误地方也请大家指出,我多多改正。项目地址

下面开始进入正题

现在已经有很多基于binaryify大佬的网易云API的web音乐播放器。界面都很美观体验也不错,但是在大家在使用时还是官方的。

写这个项目的初衷是因为突然想听周杰伦的歌了,然后去网上一搜,试听都要收费了,然后再油猴的市场里翻到了一个能免费听歌曲的在线工具,这段时间也比较喜欢用node,所以就在摸鱼时,用 puppeteer把周杰伦所有的歌曲地址都整理下来了,然后写成了一个简单的网页播放器。并且发了一个沸点,收到了大家很多的评论和点赞,github上面也出现了我人生中的第一次星星,同时也收到了很多反馈,其中最严重的是歌曲失效问题。

第一次解决失效问题

在查找失效原因时,发现了整理的歌曲地址中存在一个有时效性的key,应该就是为了防止我这种人做的处理。解决办法是,我写了一个定时任务,每隔三个小时重新去拉取一次列表。同时将GitHub的体验地址重定向到了我的博客中,使用的是我自己的服务器资源。我的服务器配置很低,3个小时也是为了节省一些资源。
但是,依然会出现间隔性失效的问题。

第二次解决失效问题

这次换了个思路,既然访问源地址有时效性,那么我就直接了当的把所有的歌曲都下载下来,一劳永逸。怎么下载呢,肯定不是手动,手动是没有灵魂的。然后还是node,使用了node 的 request模块。于是引出了小知识点,同时下载394个文件?肯定不行啊,于是手动实现了一个下载队列的函数,可以自定义同时下载多少个任务数。函数已经写好了,源码或者文章都有。 ... 下载完之后又来了一个问题,我存哪里呢?放自己服务器,不可能的。于是选择了七牛云来做储存。get一个小知识点,文件上传七牛云。 至此,再也不用担心歌曲连接失效的问题了,除非唱片公司告我侵权,我给全部删了。。。

关于UI和功能新增的问题

这个项目非常简单,主要是node的知识运用。前端方面只有一个简单的html页面。UI也很难看。如果大家有兴趣可以自己来修改扩展。

一个小槽点

我的node代码里很多地方没有加 ; 大家不要学我,在写node的时候最好把;加上哈。尤其在require()

第一次写这么多话,我的表达能力很差,如果看不懂我说的,可以移步GitHub直接查看源码。就说这么这么多了,溜了溜了。另外我这里招前端开发,1年经验起步。不要实习,坐标河北廊坊。我的微信在文章最后。

一个下载队列函数

前两天写的那个在线播放周杰伦所有歌曲的小项目,因为总是歌曲地址失效,所以准备把歌曲全部下载下来。放到七牛或者其他的云进行储存。
一共是394条数据,同时下载肯定不行的,所以自己手动写了一个下载的方法,只允许最多同时下载5首歌曲。最后封装成了一个通用的方法并且与大家一起交流分享。

/**
 * 下载队列
 * @param {Number} max @default 5 -最大并行下载数
 * @param {Array} list -下载列表
 *
 * state not : 未下载; loading : 下载中; done : 下载完成
 * */
function downloadQueue(list, max) {
    for (let i of list) {
        i.state = 'not'
    }
    // 是否下载完成
    let allDone = false

    const down = () => {
        let noIndex = null
        let notDownload = null

        for (let i = 0; i < list.length; i++) {
            const item = list[i]
            if (item.state === 'not') {
                notDownload = item
                noIndex = i
                break
            }
        }

        if (!notDownload) {
            console.log('全部下载完毕')
            allDone = true
            return
        }

        const downLoadings = list.filter(item => item.state === 'loading')
        if (downLoadings.length >= max) {
            return
        }
        notDownload.state = 'loading'
        console.log(`下载第 ${noIndex} 个`)
        down()
        setTimeout(() => {
            console.log(`下载第 ${noIndex} 个完成`)
            console.log(`剩余 ${list.length} 个`)

            list[noIndex].state = 'done'
            if (allDone) {
                return
            }
            down()
        }, 300)
    }
    down()
}