From c087e0db38b003d9ba6ad7d49fe856cb09b41b56 Mon Sep 17 00:00:00 2001 From: Norman Wang Date: Sat, 9 Oct 2021 22:51:02 +0800 Subject: [PATCH] fix: some bugs --- README.md | 10 ++- package.json | 2 +- src/background.js | 29 ++++++-- src/components/CheckUpdate/CheckUpdate.vue | 2 - src/components/SettingDrawer.vue | 5 -- src/components/VideoModal.vue | 4 -- src/core/bilibili.js | 26 +++++-- src/core/download.js | 11 ++- src/utlis/formatPath.js | 8 +++ src/views/Download.vue | 82 +++++++++++----------- src/views/Home.vue | 14 ++-- 11 files changed, 111 insertions(+), 82 deletions(-) create mode 100644 src/utlis/formatPath.js diff --git a/README.md b/README.md index f6d241a..2ca30d3 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ * [x] 删除下载记录 * [ ] 暂停/恢复下载 -## 运行 +## 开发 + +**提前自备梯子,因为electron electron-builder等依赖项需要从GitHub下载** ```bash git clone https://github.com/blogwy/BilibiliVideoDownload.git @@ -52,6 +54,11 @@ yarn electron:build ``` ## 版本 +v3.1.5 `2021-10-08` + +1. 修复无法删除的bug [issues/41](https://github.com/blogwy/BilibiliVideoDownload/issues/41) +2. 新增回车键确认在主页 + v3.1.4 `2021-09-24` 1. 修复在升级版本后,可能会导致设置页面无法关闭问题 [issues/39](https://github.com/blogwy/BilibiliVideoDownload/issues/39) @@ -119,4 +126,5 @@ Node.js重构,以前的在vuejs分支 * [Vue.js](https://vuejs.org/) * [Ant Design Vue](https://antdv.com/docs/vue/introduce-cn/) * [got](https://github.com/sindresorhus/got) +* [bilibili-API-collect](https://github.com/SocialSisterYi/bilibili-API-collect) diff --git a/package.json b/package.json index 91ef327..3684b38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "BilibiliVideoDownload", - "version": "3.1.4", + "version": "3.1.5", "private": true, "author": "wangyu ", "description": "欢迎使用BilibiliVideoDownload", diff --git a/src/background.js b/src/background.js index 6394796..adca3a1 100644 --- a/src/background.js +++ b/src/background.js @@ -86,7 +86,6 @@ function registerLocalResourceProtocol () { } function initSetting () { - console.log('setting info') const curSetting = store.get('setting') if (!curSetting) { store.set('setting', { @@ -103,7 +102,6 @@ function initSetting () { function creatImageServer () { server.get('/', async (req, res) => { - console.log(req.query.img) if (req.query.img) { const { rawBody } = await got(req.query.img) res.set('Content-Type', 'image/webp') @@ -162,7 +160,6 @@ app.on('ready', async () => { properties: ['openDirectory'] }) .then(res => { - console.log(res) event.reply('dir-dialog-reply', res) }) .catch(error => { @@ -179,11 +176,8 @@ app.on('ready', async () => { buttons: ['取消', '关闭'] }) .then(res => { - console.log(res) if (res.response === 1) { app.exit() - } else { - console.log('点击取消') } }) .catch(error => { @@ -191,9 +185,30 @@ app.on('ready', async () => { }) }) + // 删除视频 + ipcMain.on('open-delete-video-dialog', (event, arg) => { + console.log(arg.title) + dialog.showMessageBox(win, { + type: 'info', + title: '提示', + message: `是否要移除${arg.title}任务吗?`, + checkboxLabel: '同时删除文件', + buttons: ['取消', '删除'] + }) + .then(res => { + console.log(res) + event.reply('delete-video-dialog-reply', { + result: res, + videoInfo: arg + }) + }) + .catch(error => { + console.log(error) + }) + }) + // 打开浏览器 ipcMain.on('open-external', (event, arg) => { - console.log(arg) shell.openExternal(arg) }) diff --git a/src/components/CheckUpdate/CheckUpdate.vue b/src/components/CheckUpdate/CheckUpdate.vue index a927a1d..f946367 100644 --- a/src/components/CheckUpdate/CheckUpdate.vue +++ b/src/components/CheckUpdate/CheckUpdate.vue @@ -34,7 +34,6 @@ export default { created () {}, methods: { handleOk () { - console.log('handleOk') window.ipcRenderer.send('open-external', this.htmlUrl) }, handleCancel () { @@ -46,7 +45,6 @@ export default { } this.got('https://api.github.com/repos/blogwy/BilibiliVideoDownload/releases/latest', { responseType: 'json' }) .then(res => { - console.log(res.body) this.newVersion = res.body.tag_name.substr(1) this.htmlUrl = res.body.html_url this.updateContent = res.body.body diff --git a/src/components/SettingDrawer.vue b/src/components/SettingDrawer.vue index 704057f..b9181a6 100644 --- a/src/components/SettingDrawer.vue +++ b/src/components/SettingDrawer.vue @@ -87,7 +87,6 @@ export default { }, mounted () { window.ipcRenderer.on('dir-dialog-reply', (event, arg) => { - console.log(arg) if (!arg.canceled) { this.form.setFieldsValue({ downloadPath: arg.filePaths[0] @@ -105,7 +104,6 @@ export default { hide () { this.form.validateFields((error, values) => { if (!error) { - console.log(values) this.store.set('setting', values) this.visible = false this.form.resetFields() @@ -113,7 +111,6 @@ export default { }) }, async show (info) { - console.log(info) if (info) { setTimeout(() => { this.form.setFieldsValue(info) @@ -129,13 +126,11 @@ export default { }) }, openFolder () { - console.log('openFolder') window.ipcRenderer.send('open-dir-dialog', 'open') }, logout () { this.form.validateFields(async (error, values) => { if (!error) { - console.log(values) values.SESSDATA = null this.store.set('setting', values) const status = await checkLogin() diff --git a/src/components/VideoModal.vue b/src/components/VideoModal.vue index 90da71a..9809dc5 100644 --- a/src/components/VideoModal.vue +++ b/src/components/VideoModal.vue @@ -86,7 +86,6 @@ export default { methods: { onAllSelectedChange (e) { this.allSelected = e.target.checked - console.log(e.target.checked) this.selected = [] if (e.target.checked) { this.videoInfo.page.forEach(element => { @@ -108,7 +107,6 @@ export default { } }, async handleOk () { - console.log(this.videoInfo) if (!this.quality) { this.$message.info('请选择清晰度') return @@ -143,8 +141,6 @@ export default { this.$store.commit('addDownloadingTask', allowDownTaskData.length) } this.confirmLoading = false - console.log('下载列表') - console.log(taskList) // 跳转到下载页面 this.$router.push('/download') }, diff --git a/src/core/bilibili.js b/src/core/bilibili.js index f648095..eb5348a 100644 --- a/src/core/bilibili.js +++ b/src/core/bilibili.js @@ -13,6 +13,8 @@ const got = require('got') */ const getDownloadList = async (videoInfo, selected, quality) => { const SESSDATA = window.remote.getGlobal('store').get('setting.SESSDATA') + const isFolder = window.remote.getGlobal('store').get('setting.isFolder') + const downloadPath = window.remote.getGlobal('store').get('setting.downloadPath') const bfeId = window.remote.getGlobal('store').get('setting.bfe_id') ? window.remote.getGlobal('store').get('setting.bfe_id') : '' const config = { headers: { @@ -44,9 +46,16 @@ const getDownloadList = async (videoInfo, selected, quality) => { videoDuration = videoInfo.duration videoUrl = videoInfo.url } + const taskId = `${new Date().getTime()}${randomNum(1000, 9999)}` + let delDir = [] + if (isFolder) { + delDir = `${downloadPath}/${videoTitle}-${taskId}/` + } else { + delDir.push(`${downloadPath}/${videoTitle}-${taskId}.mp4`, `${downloadPath}/${videoTitle}-${taskId}.png`, `${downloadPath}/${videoTitle}-${taskId}-video.m4s`, `${downloadPath}/${videoTitle}-${taskId}-audio.m4s`) + } const videoData = { ...videoInfo, - id: `${new Date().getTime()}${randomNum(1000, 9999)}`, + id: taskId, title: videoTitle, quality: quality, duration: videoDuration, @@ -54,9 +63,14 @@ const getDownloadList = async (videoInfo, selected, quality) => { progress: 0, size: null, url: videoUrl, - downloadPath: { + downloadLink: { video: video.find(item => item.id === quality) ? video.find(item => item.id === quality).baseUrl : video[0].baseUrl, audio: audio[0].baseUrl + }, + fileDir: { + dir: isFolder ? `${downloadPath}/${videoTitle}-${taskId}/` : `${downloadPath}/`, + file: isFolder ? `${videoTitle}` : `${videoTitle}-${taskId}`, + delDir: delDir } } console.log(videoData) @@ -96,8 +110,6 @@ const checkLogin = async () => { }, responseType: 'json' }) - console.log(SESSDATA) - console.log(body) if (!body.data.isLogin) return 0 if (body.data.isLogin && !body.data.vipStatus) return 1 if (body.data.isLogin && body.data.vipStatus) return 2 @@ -159,7 +171,8 @@ const parseBV = (html, url) => { qualityOptions: data.accept_quality.map(item => ({ label: quality[item], value: item })), page: videoData.pages.map(item => ({ title: item.part, page: item.page, duration: item.duration, cid: item.cid })), subtitle: videoData.subtitle.list, - downloadPath: {} + downloadLink: {}, + fileDir: {} } resolve(obj) } catch (error) { @@ -192,7 +205,8 @@ const parseEP = (html, url) => { qualityOptions: data.accept_quality.map(item => ({ label: quality[item], value: item })), page: [{ page: 1, cid: epInfo.cid }], subtitle: [], - downloadPath: {} + downloadLink: {}, + fileDir: {} } resolve(obj) } catch (error) { diff --git a/src/core/download.js b/src/core/download.js index 5d981af..98e9b70 100644 --- a/src/core/download.js +++ b/src/core/download.js @@ -54,17 +54,14 @@ export default async (videoInfo, event) => { referer: videoInfo.url } } - let fileName = '' + let fileName = `${videoInfo.fileDir.dir}${videoInfo.fileDir.file}` if (setting.isFolder) { // 创建文件夹 try { - fs.mkdirSync(`${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}/`) - fileName = `${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}/${videoInfo.title}` + fs.mkdirSync(`${videoInfo.fileDir.dir}`) } catch (error) { console.log(`创建文件夹失败:${error}`) } - } else { - fileName = `${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}` } // 下载封面 await pipeline( @@ -80,7 +77,7 @@ export default async (videoInfo, event) => { } // 下载视频 await pipeline( - got.stream(videoInfo.downloadPath.video, downloadConfig) + got.stream(videoInfo.downloadLink.video, downloadConfig) .on('downloadProgress', progress => { let nowTime = +new Date() clearTimeout(videoTimer) @@ -114,7 +111,7 @@ export default async (videoInfo, event) => { await sleep(500) // 下载音频 await pipeline( - got.stream(videoInfo.downloadPath.audio, downloadConfig) + got.stream(videoInfo.downloadLink.audio, downloadConfig) .on('downloadProgress', progress => { let nowTime = +new Date() clearTimeout(audioTimer) diff --git a/src/utlis/formatPath.js b/src/utlis/formatPath.js new file mode 100644 index 0000000..6911c48 --- /dev/null +++ b/src/utlis/formatPath.js @@ -0,0 +1,8 @@ +export default path => { + const pattern = /[\/]/g + if (process.platform === 'win32') { + return path.replace(pattern, '\\') + } else { + return path + } +} diff --git a/src/views/Download.vue b/src/views/Download.vue index 9920704..0cd0678 100644 --- a/src/views/Download.vue +++ b/src/views/Download.vue @@ -35,7 +35,7 @@
播放:{{ current.watch }}
弹幕:{{ current.danmu }}
评论:{{ current.comment }}
-
+
删除 打开
@@ -49,6 +49,7 @@ import base from '../mixin/base' import { quality } from '../assets/data/quality' import taskStatus from '../assets/data/status' import sleep from '../utlis/sleep' +import formatPath from '../utlis/formatPath' const fs = require('fs') export default { mixins: [base], @@ -79,60 +80,57 @@ export default { mounted () { this.getTaskList() window.ipcRenderer.on('reply-download-video', this.handleProgress) + window.ipcRenderer.on('delete-video-dialog-reply', this.handleDelVideo) }, created () {}, destroyed () { window.ipcRenderer.removeListener('reply-download-video', this.handleProgress) + window.ipcRenderer.removeListener('delete-video-dialog-reply', this.handleDelVideo) }, methods: { openFolder (videoInfo) { - const setting = this.store.get('setting') - let dir = '' - if (process.platform === 'win32') { - dir = `${setting.downloadPath}\\${videoInfo.title}-${videoInfo.id}` - } else { - dir = `${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}` - } - window.remote.shell.showItemInFolder(dir) + const dir = formatPath(videoInfo.fileDir.dir) + window.remote.shell.openPath(dir) }, delDir (videoInfo) { - this.$confirm({ - title: '你确定要删除当前任务吗?', - content: '视频文件也会被删除', - cancelText: '取消', - okText: '删除', - onOk: () => { - // 删除文件 - const setting = this.store.get('setting') - fs.rmdir(`${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}`, { recursive: true }, err => { - if (err) { - console.log(err) - } else { - console.log('video-删除成功') + window.ipcRenderer.send('open-delete-video-dialog', videoInfo) + }, + handleDelVideo (event, { result, videoInfo }) { + console.log('handleDelVideo') + console.log(videoInfo) + if (!result.response) return + // 删除记录 + const taskList = this.store.get('taskList') + const index = taskList.findIndex(item => item.id === videoInfo.id) + taskList.splice(index, 1) + this.store.set('taskList', taskList) + if (result.checkboxChecked) { + // 删除文件 + const flag = Array.isArray(videoInfo.fileDir.delDir) + if (!flag) { + try { + fs.rmdirSync(`${videoInfo.fileDir.dir}`, { recursive: true }) + } catch (error) { + console.log(error) + this.$message.error('视频文件删除失败') + } + } else { + try { + const fileList = videoInfo.fileDir.delDir + for (let index = 0; index < 3; index++) { + fs.unlinkSync(fileList[index]) } - }) - // 删除记录 - const taskList = this.store.get('taskList') - const index = taskList.findIndex(item => item.id === videoInfo.id) - taskList.splice(index, 1) - this.store.set('taskList', taskList) - this.$message.success('删除成功') - this.getTaskList() - }, - onCancel () { - console.log('取消') + } catch (error) { + console.log(error) + // this.$message.error('视频文件删除失败') + } } - }) + } + this.$message.success('删除成功') + this.getTaskList() }, getVideoSize (videoInfo) { - const setting = this.store.get('setting') - let fileName = '' - if (setting.isFolder) { - fileName = `${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}/${videoInfo.title}` - } else { - fileName = `${setting.downloadPath}/${videoInfo.title}-${videoInfo.id}` - } - fs.stat(`${fileName}.mp4`, (err, info) => { + fs.stat(`${videoInfo.fileDir.dir}${videoInfo.fileDir.file}.mp4`, (err, info) => { if (err) { console.log(err) } else { diff --git a/src/views/Home.vue b/src/views/Home.vue index 4bd9330..966559a 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -4,7 +4,7 @@
- +
@@ -49,6 +49,11 @@ export default { this.$message.info('请输入视频地址') return } + const videoType = checkUrl(this.url) + if (videoType === -1) { + this.$message.error('请输入正确的视频地址') + return + } // 检测登录状态 if (this.$store.state.showLoginModal) { const status = await checkLogin() @@ -71,12 +76,7 @@ export default { const res = await this.got(params.url, params.config) // 检测是否有重定向 const url = res.redirectUrls[0] ? res.redirectUrls[0] : this.url - const type = checkUrl(url) - if (type === -1) { - this.$message.error('请输入正确的视频地址') - return - } - const videoInfo = await parseHtml(res.body, type, url) + const videoInfo = await parseHtml(res.body, videoType, url) this.$refs.videoModal.show(videoInfo) } catch (error) { console.log(error)