第八章 Electron 实现音乐播放器之爬虫播放音乐

一、介绍  ✈️

我在第五章已经有一篇Electron爬虫的文章,主要写的爬取图片资源的案例。这篇开始讲解如何到一个音乐网站爬取音乐资源,并且进行在线播放,下载等等。

那么什么是爬虫呢。百度百科上爬虫既是网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。我个人的理解就是,爬虫是一种自动化程序,它可以模拟人类浏览网页的行为,从互联网上爬取数据并进行处理。

二、爬虫准备  ✈️

1、编程语言准备   

除了node爬虫,常用的编程语言还有Python、Java、C++等,其中Python是最为流行的爬虫语言之一。不管是那种,思路和步骤基本上都是一样的。

2、数据储存   

爬虫爬取的数据需要进行存储,常用的数据存储方式有MySQL、MongoDB、Redis、SQLite3、Excel、txt、json等。具体采用什么方式储存需要看具体的数据类型、结构、大小等。

3、资源网站的观察   

在开始爬虫之前我们得去资源网站进行观察,python、java、node等语言爬虫都是需要对网站结构进行分析的。比如我们需要爬取一个网站内的分类,对于其他非分类的内容来说是没有任何意义的。可以观察网站中分类是否具有唯一的class或者id,又或者分类是在div容器中还是ul容器中。根据多方面的条件能够让我们很快,也能最简单的去通过一些工具取到想要的内容。这是结构的一个观察,还有请求的要求,有些接口请求的话会有一些繁琐的头部定义(Header)。如果不设置的话可能会出现401、404、50*等等各种情况。这些都是需要我们去观察以后,在脚本中去进行设置的。

三、爬虫能够做些啥  ✈️

1、数据采集     

爬虫可以自动化地从互联网上采集数据,包括文字、图片、音乐、视频等。

2、数据分析     

爬虫可以对采集到的数据进行分析和处理,例如数据清洗、数据挖掘等。

3、搜索引擎优化     

爬虫可以帮助网站提升搜索引擎排名,从而增加网站的流量和曝光度。

4、网络安全     

爬虫可以帮助企业进行网络安全测试,发现漏洞和安全隐患。

四、爬虫技巧  ✈️

1、合理设置爬虫请求频率,避免对服务器造成过大的负担。  

2、使用多个IP地址进行爬取,避免被封禁。  

3、使用随机的User-Agent头信息,避免被网站识别为爬虫。  

4、避免爬取敏感信息,遵守网站的robots.txt协议。  

五、开始爬取音乐  ✈️

安装依赖

yarn add cheerio

yarn add @types/cheerio -D

这里的话具体的网站地址我就不放出来了,避免一些不必要的麻烦,如果有需要的小伙伴可以私信我。

首先我搜索周杰伦以后,就会出来一个搜索结果的页面,页面内还包含了分页数据。所以页面内我需要的数据就是内容和分页。通过对页面的分析,$('.list-unstyled .media')就能帮我定位到内容。

$('.pagination li')就能帮我定位的分页。

第八章 Electron 实现音乐播放器之爬虫播放音乐_第1张图片

第八章 Electron 实现音乐播放器之爬虫播放音乐_第2张图片

点击相对应的歌曲进入以后,我们还可以获取到歌曲的相信信息,歌曲名称、歌手、歌词等等

第八章 Electron 实现音乐播放器之爬虫播放音乐_第3张图片

当我们点击播放的时候,可以在Network中观察到,它请求的地址,这个地址复制在浏览器中打开是可以直接播放音乐的。也能直接下载,所有我们需要这个地址。

第八章 Electron 实现音乐播放器之爬虫播放音乐_第4张图片

第八章 Electron 实现音乐播放器之爬虫播放音乐_第5张图片

综合以上的全部分析,具体的实现代码如下:

/** 根据歌曲名称查询对应的列表
 * @Description:
 * @CreationDate 2023-05-08 10:11:51
 */
getListByMusicName(musicName: string, page?: number) {
	if (!page) {
		this.resetGetParam(musicName)
	}
	const path = `search-${encodeURIComponent(musicName)}-1-${ page ? page : this.queryMusicResult.music_current_page }.htm`
	try {
		axios.get('https://www.******.com/' + path).then((res: any) => {
			const $: any = cheerio.load(res.data)
			const musicContent = $('.list-unstyled .media')
			const pagination = $('.pagination li')
			// 获取总页数
			if (pagination.eq(pagination.length - 2).children('a').html()) {
				const pageTotal = (pagination.eq(pagination.length - 2).children('a').html()).match(/\d+/g)[0]
				if (pageTotal && pageTotal > 0) {
					this.queryMusicResult.music_page_count = Number(pageTotal)
				}
			}

			if (this.queryMusicResult.music_current_page === this.queryMusicResult.music_page_count) {
				this.queryMusicResult.music_noMore = true
			}

			// 如何搜索出的结果为0就直接结束
			if (musicContent.length === 0) {
				this.queryMusicResult.music_loading = false
				this.queryMusicResult.music_noMore = false
			} else {
				this.circulateGetMusicList(musicContent)
			}
		}).catch((e: any) => {
			this.queryMusicResult.music_loading = false
			console.log('-----------------', e);
		})
	} catch (e) {
		this.queryMusicResult.music_loading = false
		console.log('-----------------', e);
	}
},
/**
 * @Description: 循环查询当前页面的歌曲相关信息
 * @CreationDate 2023-05-08 11:48:43
 */
circulateGetMusicList(musicContent: any) {
	try {
		for (let i = 0; i < musicContent.length; i++) {
			const musicHref = musicContent['eq'](i).children('div .media-body').children('div .subject').children('a')
			axios.get('https://www.*****.com/' + musicHref.attr('href')).then(info => {
				const $info: any = cheerio.load(info.data)
				const musicInfo = $info('.card-thread')['children']('div .card-body').children('div .break-all')
				if (musicContent.length === (i + 1)) {
					this.queryMusicResult.music_loading = false
				}
				if (musicInfo.children('script') && musicInfo.children('script').get(1) && musicInfo.children('script').get(1).children) {
					const musicInfos = musicInfo.children('script').get(1).children[0]['data']
					const S = musicInfos.indexOf('[')
					const E = musicInfos.indexOf(']')
					let data = musicInfos.substring(S + 1, E - 3).replace(/\s*/g, '')
					if (data) {
						data = data.substring(0, data.length - 1)
						data = eval('(' + data + ')')
						this.queryMusicResult.music_current_list.push({
							name: data.title,
							url: data.url.includes('https') ? data.url.replace('-', '%20-%20') : 'https://www.*****.com/' + data.url,
							author: data.author,
							pic: data.pic
						} as MusicType)
					}
				}
			})
		}
	} catch (e) {
		this.queryMusicResult.music_loading = false
		console.log('-----------------', e)
	}
},

这里的话我们就实现了爬虫的部分代码,是不是超级简单,现在就要对爬取的资源进行一个展示,以及音乐的播放,下载等等。

我将上一章中的目录结构进行了更改。创建src/views/music目录,原本home下面的index.vue更改为localAndDownload.vue,并移动到music目录下。同时创建index.vue页面。接下来,我们将爬取的资源在music/index.vue中进行一个实现。

第八章 Electron 实现音乐播放器之爬虫播放音乐_第6张图片

六、完整案例  ✈️

首先创建路由。这里的话我就不做菜单了,自行去完成,我直接将根路径访问指向music/index

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'

export const asyncRoutes: RouteRecordRaw[] = [
    {
        path: '/',
        component: () => import('@/views/music/index.vue')
    },
    {
        path: '/home',
        component: () => import('@/views/home/index.vue')
    },
    {
        path: '/401',
        component: () => import('@/views/401.vue'),
    },
    {
        path: '/localAndDownload',
        component: () => import('@/views/music/localAndDownload.vue')
    },
]

const router = createRouter({
    history: createWebHashHistory(),
    routes: asyncRoutes,
    scrollBehavior: () => ({ left: 0, top: 0 })
})

export default router

修改src/views/music/index.vue






修改src/pinia/modules/music.modules.ts

import { defineStore } from 'pinia';
import {durationConversionTime} from "@/utils/DateTime";
// @ts-ignore
import {ElMessage} from "element-plus";
import axios from "axios";
// @ts-ignore
const cheerio = require('cheerio')

/**
 * @Description: 歌曲信息类型
 * @CreationDate 2023-05-08 11:50:36
 */
export interface MusicType {
    name?: string
    album?: string
    url?: string
    author?: string
    pic?: string
    percentage?: number
}

/**
 * @Description: 搜索歌曲结果
 * @CreationDate 2023-05-08 17:02:57
 */
export interface QueryMusicResultType {
    music_page_count: number // 搜索出来的歌曲总页数
    music_current_page: number // 当前搜索匹配的页数
    music_loading: boolean // 搜索歌曲时的状态
    music_noMore: boolean // 没有更多了
    music_name: string // 当前搜索歌曲的名称
    music_current_list: MusicType[] // 搜索出来的歌曲列表,叠加
}

/**
 * @Description: 当前播放音乐信息类型
 * @CreationDate 2023-05-08 11:51:00
 */
export interface CurrentPlayMusicType extends MusicType{
    current_play_audio_ready?: boolean //
}

/**
 * @Description: 歌单类型
 * @CreationDate 2023-05-11 11:00:37
 */
export interface PlaylistsListType {
    id?: number
    name: string // 歌单名称
    describe: string // 描述
}

/**
 * @Description: 我喜欢的音乐
 * @CreationDate 2023-05-13 20:06:33
 */
export interface LikeMusicType extends MusicType {
    id: number // 主键
}

/**
 * @Description: 播放器设置
 * @Author: Etc.End([email protected])
 * @Copyright: TigerSong
 * @CreationDate 2023-05-13 00:04:43
 */
interface PlayerSettingType {
    playing: string //
    volume: number // 音量
    total_duration?: number // 当前播放歌曲时长
    total_duration_char?: string // 当前播放歌曲时长字符
    current_duration?: number // 当前播放歌曲时段
    current_duration_char?: string // 当前播放歌曲时段
    current_list_name: 'likeMusicList' | 'queryMusicResult' | 'playlistsList' | 'collectList' | 'downloadMusicList' // 当前播放列表 喜欢、查询、歌单、收藏
    play_mode: 'singleCirculation' | 'tableCirculation' | 'sequentialPlay' | 'randomPlay' // 播放模式 单曲循环 列表循环 顺序播放 随机播放
    previous_is_click: boolean // 可以点击上一首
    next_is_click: boolean // 可以点下一首
    play_is_click: boolean // 可以点播放
    play_index: number // 当前播放歌曲在列表中的索引
    play_name: string // 当前播放歌曲的名称
    play_state: boolean // 当前播放状态
}

/**
 * @Description: musicModule类型
 * @CreationDate 2023-05-08 11:51:15
 */
interface IAppState {
    player?: HTMLAudioElement // 播放器
    queryMusicResult: QueryMusicResultType // 搜索歌曲的结果
    currentPlayMusic: CurrentPlayMusicType // 当前播放音乐的相关信息
    playlistsList: PlaylistsListType[] // 歌单列表
    collectList: MusicType[] // 收藏列表
    likeMusicList: LikeMusicType[] // 喜欢的音乐
    playerSetting: PlayerSettingType // 播放器设置
    downloadMusicList: MusicType[]
}

/**
 * @Description: 音乐播放器状态管理器
 * @Author: Etc.End([email protected])
 * @Copyright: TigerSong
 * @CreationDate 2023-05-08 11:51:33
 */
export const musicModule = defineStore({
    id: 'music',
    state(): IAppState {
        return {
            currentPlayMusic: {
                current_play_audio_ready: true,
                name: '',
                url: '',
                author: '',
                pic: '',
            },
            queryMusicResult: {
                music_name: '',
                music_page_count: 0,
                music_current_page: 1,
                music_loading: false,
                music_noMore: false,
                music_current_list: []
            },
            playlistsList: [],
            collectList: [],
            likeMusicList: [],
            playerSetting: {
                playing: '',
                volume: 100,
                current_list_name: 'downloadMusicList',
                play_mode: 'tableCirculation',
                previous_is_click: true,
                next_is_click: true,
                play_is_click: true,
                play_index: -1,
                play_name: '',
                play_state: false
            },
            downloadMusicList: []
        };
    },

    actions: {
        /**
         * @Description: 初始化音乐播放器
         * @CreationDate 2023-05-08 11:50:15
         */
        initMusic(container: HTMLAudioElement) {
            this.player = container
            this.setPreviousAndNextClick()
            this.playerSetting.play_index = -1
        },
        /**
         * @Description: 播放
         * @CreationDate 2023-05-08 11:50:03
         */
        play(index?: number):void {
            if (index || index === 0) {
                this.playerSetting.play_index = index;
                (this.player && this.currentPlayMusic.current_play_audio_ready) && this.player.play();
                this.currentPlayMusic.current_play_audio_ready = false
                this.playerSetting.play_state = true
            } else {
                (this.player) && this.player.play();
                this.playerSetting.play_state = true
            }
            this.setPreviousAndNextClick()
        },
        /**
         * @Description: 更新当前歌曲信息
         * @CreationDate 2023-05-08 11:49:06
         */
        setCurrentMusicInfo(info: MusicType):void {
            this.currentPlayMusic = Object.assign(this.currentPlayMusic, info)
            if (this.player && this.currentPlayMusic.url) {
                this.player.src = this.currentPlayMusic.url
                this.playerSetting.play_name = this.currentPlayMusic.name!
            }
        },
        /**
         * @Description: 获取已经下载的所有文件名
         * @CreationDate 2023-05-16 17:24:08
         */
        getDownloadMusicList() {
            const that = this
            const musicList :MusicType[] = [];
            const fs = require('fs')
            const pathList = fs.readdirSync(`${process.cwd()}/download/music`);

            !(async () => {
                for (let i = 0; i < pathList.length; i++) {
                    const data: any = await that.getDownloadMusicInfo(`${process.cwd()}/download/music/${pathList[i]}`)
                    if (data.tags) {
                        musicList.push({
                            name: data.tags.title || pathList[i],
                            album: data.tags.album,
                            author: data.tags.artist,
                            pic: '',
                            url: `file:${process.cwd()}/download/music/${pathList[i]}`
                        });
                    }
                }
                this.downloadMusicList = musicList
            })();
        },
        /**
         * @Description: 根据jsmediatags插件读取下载的歌曲的信息
         * @CreationDate 2023-05-22 09:33:44
         */
        getDownloadMusicInfo(path: string) {
            return new Promise((resolve, reject) => {
                const jsmediatags = require('jsmediatags')
                new jsmediatags.Reader(path).setTagsToRead(["title", "track", "artist", "album", "year"])
                    .read({
                        onSuccess: (tag: any) => {
                            resolve(tag);
                        },
                        onError: (error: any) => {
                            reject(error);
                        }
                    });
            })
        },
        // -----------------------------------------------------------------播放器相关设置-----------------------------------------------------------------
        ready ():void{
            this.currentPlayMusic.current_play_audio_ready = true
            this.playerSetting.total_duration = ~~this.player!.duration;
            this.playerSetting.total_duration && (this.playerSetting.total_duration_char = durationConversionTime(this.playerSetting.total_duration))
        },
        /**
         * @Description: 报错回调
         * @CreationDate 2023-05-13 17:39:59
         */
        error(code: any): void {
            console.log(code)
        },
        /**
         * @Description: 获取音乐当前播放的时段
         * @CreationDate 2023-05-13 20:46:53
         */
        updateTime(): void {
            if (this.player) {
                this.playerSetting.current_duration = ~~this.player.currentTime
                this.playerSetting.current_duration && (this.playerSetting.current_duration_char = durationConversionTime(this.playerSetting.current_duration))
            }
        },
        /**
         * @Description: 设置音乐当前播放的时段
         * @CreationDate 2023-05-13 20:47:17
         */
        settingDuration(val: number): void {
            if (this.player) {
                this.player.currentTime = val
            }
        },
        /**
         * @Description: 设置音量
         * @CreationDate 2023-05-12 23:44:52
         */
        settingVolume(volume: number):void {
            this.player && (this.player.volume = volume)
        },
        /**
         * @Description: 监听音乐播放结束
         * @CreationDate 2023-05-12 22:24:36
         */
        endPlayback ():void {
            this.playerSetting.current_duration = 0
            // 单曲循环
            if (this.playerSetting.play_mode === 'singleCirculation') {
                this.play(this.playerSetting.play_index)
            } else if (this.playerSetting.play_mode === 'sequentialPlay') { // 顺序播放
                let listLength:number = 0
                if (this.playerSetting.current_list_name === 'queryMusicResult') {
                    listLength = this.queryMusicResult.music_current_list.length
                } else {
                    listLength = this[this.playerSetting.current_list_name].length
                }
                if ((this.playerSetting.play_index + 1) === listLength) {
                    this.playerSetting.current_duration_char = '0:00'
                    this.suspend()
                } else {
                    this.play(this.playerSetting.play_index + 1)
                }
            }
            else { // 播放器默认就是列表循环 列表循环
                this.next()
            }
        },
        /**
         * @Description: 切换播放模式
         * @CreationDate 2023-05-15 09:43:34
         */
        changePlayMode (mode: 'singleCirculation' | 'tableCirculation' | 'sequentialPlay' | 'randomPlay'):void {
            this.playerSetting.play_mode = mode
        },
        /**
         * @Description: 上一首
         * @CreationDate 2023-05-08 11:49:31
         */
        previous():void {
            if (this.playerSetting.play_index > 1) {
                this.playerSetting.play_index -= 1
                this.setCurrentMusicInfo(this.queryMusicResult.music_current_list[this.playerSetting.play_index])
                this.play()
            }
        },
        /**
         * @Description: 下一首
         * @CreationDate 2023-05-08 11:49:24
         */
        next():void {
            if (this.playerSetting.current_list_name === 'queryMusicResult') {
                if (this.playerSetting.play_index < this.queryMusicResult.music_current_list.length) {
                    this.playerSetting.play_index += 1
                } else {
                    this.playerSetting.play_index = 0
                }
                this.setCurrentMusicInfo(this.queryMusicResult.music_current_list[this.playerSetting.play_index])
            } else {
                if (this.playerSetting.play_index < this[this.playerSetting.current_list_name].length) {
                    this.playerSetting.play_index += 1
                } else {
                    this.playerSetting.play_index = 0
                }
                this.setCurrentMusicInfo(this[this.playerSetting.current_list_name][this.playerSetting.play_index])
            }
            this.play()
        },
        /**
         * @Description: 单曲循环
         * @CreationDate 2023-05-15 10:47:50
         */
        singleCirculation() :void {
            if (this.player) {
                this.player.currentTime = 0
                this.play()
            }
        },
        /**
         * @Description: 暂停
         * @CreationDate 2023-05-08 11:49:42
         */
        suspend():void {
            this.player && this.player.pause();
            this.playerSetting.play_state = false
        },
        /**
         * @Description: 设置上一首下一首按钮可以点击
         * @CreationDate 2023-05-09 10:15:10
         */
        setPreviousAndNextClick():void {
            this.playerSetting.next_is_click = this.playerSetting.play_index !== -1;
            this.playerSetting.previous_is_click = this.playerSetting.play_index !== -1;
        },
        // -----------------------------------------------------------------爬虫相关-----------------------------------------------------------------
        /** 根据歌曲名称查询对应的列表
         * @Description:
         * @CreationDate 2023-05-08 10:11:51
         */
        getListByMusicName(musicName: string, page?: number) {
            if (!page) {
                this.resetGetParam(musicName)
            }
            const path = `search-${encodeURIComponent(musicName)}-1-${ page ? page : this.queryMusicResult.music_current_page }.htm`
            try {
                axios.get('https://www.****.com/' + path).then((res: any) => {
                    const $: any = cheerio.load(res.data)
                    const musicContent = $('.list-unstyled .media')
                    const pagination = $('.pagination li')
                    // 获取总页数
                    if (pagination.eq(pagination.length - 2).children('a').html()) {
                        const pageTotal = (pagination.eq(pagination.length - 2).children('a').html()).match(/\d+/g)[0]
                        if (pageTotal && pageTotal > 0) {
                            this.queryMusicResult.music_page_count = Number(pageTotal)
                        }
                    }

                    if (this.queryMusicResult.music_current_page === this.queryMusicResult.music_page_count) {
                        this.queryMusicResult.music_noMore = true
                    }

                    // 如何搜索出的结果为0就直接结束
                    if (musicContent.length === 0) {
                        this.queryMusicResult.music_loading = false
                        this.queryMusicResult.music_noMore = false
                    } else {
                        this.circulateGetMusicList(musicContent)
                    }
                }).catch((e: any) => {
                    this.queryMusicResult.music_loading = false
                    console.log('-----------------', e);
                })
            } catch (e) {
                this.queryMusicResult.music_loading = false
                console.log('-----------------', e);
            }
        },
        /**
         * @Description: 循环查询当前页面的歌曲相关信息
         * @CreationDate 2023-05-08 11:48:43
         */
        circulateGetMusicList(musicContent: any) {
            try {
                for (let i = 0; i < musicContent.length; i++) {
                    const musicHref = musicContent['eq'](i).children('div .media-body').children('div .subject').children('a')
                    axios.get('https://www.****.com/' + musicHref.attr('href')).then(info => {
                        const $info: any = cheerio.load(info.data)
                        const musicInfo = $info('.card-thread')['children']('div .card-body').children('div .break-all')
                        if (musicContent.length === (i + 1)) {
                            this.queryMusicResult.music_loading = false
                        }
                        if (musicInfo.children('script') && musicInfo.children('script').get(1) && musicInfo.children('script').get(1).children) {
                            const musicInfos = musicInfo.children('script').get(1).children[0]['data']
                            const S = musicInfos.indexOf('[')
                            const E = musicInfos.indexOf(']')
                            let data = musicInfos.substring(S + 1, E - 3).replace(/\s*/g, '')
                            if (data) {
                                data = data.substring(0, data.length - 1)
                                data = eval('(' + data + ')')
                                this.queryMusicResult.music_current_list.push({
                                    name: data.title,
                                    url: data.url.includes('https') ? data.url.replace('-', '%20-%20') : 'https://www.****.com/' + data.url,
                                    author: data.author,
                                    pic: data.pic
                                } as MusicType)
                            }
                        }
                    })
                }
            } catch (e) {
                this.queryMusicResult.music_loading = false
                console.log('-----------------', e)
            }
        },
        /**
         * @Description: 加载更多
         * @CreationDate 2023-05-08 11:48:21
         */
        loadMore() {
            this.queryMusicResult.music_current_page += 1
            this.getListByMusicName(this.queryMusicResult.music_name, this.queryMusicResult.music_current_page)
        },
        /**
         * @Description: 重置查询条件
         * @CreationDate 2023-05-08 11:48:32
         */
        resetGetParam(musicName: string){
            this.queryMusicResult.music_page_count = 0
            this.queryMusicResult.music_current_page = 1
            this.queryMusicResult.music_noMore = false
            this.queryMusicResult.music_loading = true
            this.queryMusicResult.music_name = musicName
            this.queryMusicResult.music_current_list = []
        },
    },
    getters: {
    },
});

修改electron/main.ts主进程,增加下载监听

const fs = require('fs')
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const remote = require("@electron/remote/main");
remote.initialize();

const NODE_ENV = process.env.NODE_ENV
let win

/**
 * @Description: electron程序入口
 * @Author: Etc.End
 * @Copyright: TigerSong
 * @CreationDate 2023-05-20 14:39:26
 */
const createWindow = () => {
    win = new BrowserWindow({
        icon: './public/logo.png',
        frame: false, // 去掉导航最大化最小化以及关闭按钮
        width: 1200,
        height: 800,
        minWidth: 1200,
        minHeight: 800,
        center: true,
        skipTaskbar: false,
        transparent: false,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
            webSecurity: false,
        }
    })

    try {
        const activation = fs.readFileSync('./config/core.tiger', 'utf8')
        if (activation) {
            // 这里就可以把pinia中的逻辑放在这里,如果激活码不正确的话,就不加载某些脚本。
            // 也可以根据判断激活码来生成路由或删除路由数据,方案很多,自由发挥。
        }
    } catch (e) {
        console.log('-----------------注册码读取失败', e.message)
    }

    win.loadURL(
        NODE_ENV === 'development' ? 'http://localhost:5173/' : `file://${path.join(__dirname, '../dist/index.html')}`
    )

    if (NODE_ENV === 'development') {
        win.webContents.openDevTools()
    }

    remote.enable(win.webContents);
}

// 监听渲染进程发出的download事件
ipcMain.on('download', (evt, args) => {
    downloadFileToMusic(args.downloadPath, args.fileName, args.author, args.pic)
})

function downloadFileToMusic(url, fileName, author, pic) {
    win.webContents.downloadURL(url)
    win.webContents.session.once('will-download', (event, item) => {
        let filePath = path.join(app.getAppPath(), '/download/music', `${fileName}.mp3`);
        if (NODE_ENV !== 'development') {
            filePath = path.join(path.dirname(app.getPath('exe')), '/download/music', `${fileName}.mp3`);
        }
        item.setSavePath(filePath)
        item.on('updated', (event, state) => {
            // 中断
            if (state === 'interrupted') {
                console.log('-----------------下载已中断,但可以继续')
            } else if (state === 'progressing') {
                if (item.isPaused()) {
                    console.log('-----------------这里是暂停的逻辑')
                } else {
                    // const receivedBytes = item.getReceivedBytes()
                    // // 计算每秒下载的速度
                    // item.speed = receivedBytes - prevReceivedBytes
                    // prevReceivedBytes = receivedBytes
                    const progress = item.getReceivedBytes() / item.getTotalBytes()
                    // win.setProgressBar(progress)
                    win.webContents.send('updateProgressing', progress)
                }
            }
        })
        item.once('done', (event, state) => {
            if (state === 'completed') {
                console.log('-----------------下载成功')
            } else {
                console.log('-----------------下载失败:', state)
            }
        })
    })
}

let CONFIG_PATH = path.join(app.getAppPath(), '/config');
if (NODE_ENV !== 'development') {
    CONFIG_PATH = path.join(path.dirname(app.getPath('exe')), '/config');
}

app.whenReady().then(() => {
    createWindow()
    const isExistDir = fs.existsSync(CONFIG_PATH)
    if (!isExistDir) {
        fs.mkdirSync(CONFIG_PATH)
    }
})

ipcMain.on('TSActivateApplication', (evt, args) => {
    fs.writeFile(`${CONFIG_PATH}/core.tiger`, args, function(err) {
        if(err) {
            return console.log('-----------------创建激活码文件失败!')
        }
        setTimeout(() => {
            // 重启
            if (NODE_ENV !== 'development') {
                app.relaunch()
                app.exit()
            }
        }, 2 * 1000);
    })
})

/**
 * @Description: 限制只能打开一个页面
 * @CreationDate 2023-05-20 14:35:52
 */
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
    app.quit()
} else {
    app.on('second-instance', (event, commandLine, workingDirectory) => {
        if (win) {
            if (win.isMinimized()) win.restore()
            win.focus()
        }
    })
}

app.on('window-all-closed', function () {
    if(process.platform !== 'darwin') app.quit()
})

七、最终效果预览  ✈️

搜索

第八章 Electron 实现音乐播放器之爬虫播放音乐_第7张图片

下载

第八章 Electron 实现音乐播放器之爬虫播放音乐_第8张图片

我是Etc.End。如果文章对你有所帮助,能否帮我点个免费的赞和收藏。

   

你可能感兴趣的:(Electron,electron,javascript,前端)