diff --git a/README.md b/README.md
index 4ca1bd7..137b991 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ yarn run build --universal --mac
# 打包win
yarn run build --win
-# 打包win
+# 打包linux
yarn run build --linux
```
diff --git a/components.d.ts b/components.d.ts
index 620980f..f1b4c41 100755
--- a/components.d.ts
+++ b/components.d.ts
@@ -8,6 +8,9 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
ElButton: typeof import('element-plus/es')['ElButton']
+ ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
+ ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
+ ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElForm: typeof import('element-plus/es')['ElForm']
@@ -15,11 +18,11 @@ declare module 'vue' {
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
- ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
+ ElPopover: typeof import('element-plus/es')['ElPopover']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
Footer: typeof import('./src/components/layout/Footer.vue')['default']
diff --git a/electron/main/cert.ts b/electron/main/cert.ts
index 7ba48df..020569d 100755
--- a/electron/main/cert.ts
+++ b/electron/main/cert.ts
@@ -9,51 +9,62 @@ export function checkCertInstalled() {
return fs.existsSync(CONFIG.INSTALL_CERT_FLAG)
}
-export async function installCert(checkInstalled = true) {
- if (checkInstalled && checkCertInstalled()) {
- return;
+export function installCert(checkInstalled = true) {
+ try {
+ if (checkInstalled && checkCertInstalled()) {
+ return;
+ }
+ mkdirp.sync(path.dirname(CONFIG.INSTALL_CERT_FLAG))
+
+ if (process.platform === 'darwin') {
+ handleMacCertInstallation()
+ } else if (process.platform === 'win32') {
+ handleWindowsCertInstallation()
+ } else {
+ handleOtherCertInstallation()
+ }
+ } catch (e) {
+ handleOtherCertInstallation()
}
- mkdirp.sync(path.dirname(CONFIG.INSTALL_CERT_FLAG))
-
- if (process.platform === 'darwin') {
- return new Promise((resolve, reject) => {
- clipboard.writeText(
- `echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${CONFIG.CERT_PUBLIC_PATH}" && touch ${CONFIG.INSTALL_CERT_FLAG} && echo "安装完成"`,
- )
- dialog.showMessageBoxSync({
- type: "info",
- message: `命令已复制到剪贴板,粘贴命令到终端并运行以安装并信任证书`,
- });
-
- reject()
- });
- } else if (process.platform === 'linux') {
- return new Promise((resolve, reject) => {
- clipboard.writeText(
- "https://github.com/putyy/res-downloader/blob/master/electron/res/keys/public.pem",
- )
- dialog.showMessageBoxSync({
- type: "info",
- message: `Linux系统请手动安装证书,已复制下载地址`,
- });
-
- reject()
- });
+}
+
+
+// MacOS 证书安装处理
+function handleMacCertInstallation() {
+ clipboard.writeText(
+ `echo "输入本地登录密码" && sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${CONFIG.CERT_PUBLIC_PATH}" && touch ${CONFIG.INSTALL_CERT_FLAG} && echo "安装完成"`
+ );
+
+ dialog.showMessageBoxSync({
+ type: 'info',
+ message: '命令已复制到剪贴板,粘贴到终端并运行以安装并信任证书',
+ });
+}
+
+// Linux 证书安装处理
+function handleOtherCertInstallation() {
+ clipboard.writeText(CONFIG.CERT_PUBLIC_PATH);
+
+ dialog.showMessageBoxSync({
+ type: "info",
+ message: `请手动安装证书,证书文件路径:${CONFIG.CERT_PUBLIC_PATH} 已复制到剪贴板`,
+ });
+}
+
+// Windows 证书安装处理
+function handleWindowsCertInstallation() {
+ const result = spawn.sync(CONFIG.WIN_CERT_INSTALL_HELPER, [
+ '-c',
+ '-add',
+ CONFIG.CERT_PUBLIC_PATH,
+ '-s',
+ 'root',
+ ]);
+
+ if (result.stdout.toString().includes('Succeeded')) {
+ fs.writeFileSync(CONFIG.INSTALL_CERT_FLAG, '');
} else {
- return new Promise((resolve: any, reject) => {
- const result = spawn.sync(CONFIG.WIN_CERT_INSTALL_HELPER, [
- '-c',
- '-add',
- CONFIG.CERT_PUBLIC_PATH,
- '-s',
- 'root',
- ]);
- if (result.stdout.toString().indexOf('Succeeded') > -1) {
- fs.writeFileSync(CONFIG.INSTALL_CERT_FLAG, '')
- resolve()
- } else {
- reject()
- }
- })
+ handleOtherCertInstallation();
}
}
+
diff --git a/electron/main/index.ts b/electron/main/index.ts
index dcb1580..dd647a1 100644
--- a/electron/main/index.ts
+++ b/electron/main/index.ts
@@ -7,6 +7,8 @@ import {closeProxy} from "./setProxy"
import log from "electron-log"
import path from 'path'
import {spawn} from 'child_process'
+import {startServer} from "./proxyServer";
+import fs from "fs";
// The built directory structure
//
@@ -56,6 +58,16 @@ const preload = join(__dirname, '../preload/index.js')
const url = process.env.VITE_DEV_SERVER_URL
const indexHtml = join(process.env.DIST, 'index.html')
+global.videoList = {}
+global.isStartProxy = false
+global.isSettingProxy = false
+global.resdConfig = {
+ save_dir: "",
+ quality: "-1",
+ proxy: "",
+ port: 8899,
+}
+
// app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
@@ -100,8 +112,10 @@ function createWindow() {
mainWindow = new BrowserWindow({
title: 'Main window',
icon: join(process.env.VITE_PUBLIC, 'favicon.ico'),
- width: 800,
- height: 600,
+ width: 1024,
+ minWidth: 960,
+ height: 768,
+ minHeight: 640,
webPreferences: {
preload,
// Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
@@ -159,14 +173,11 @@ function createPreviewWindow(parent: BrowserWindow) {
previewWin.setTitle("预览")
previewWin.on("page-title-updated", (event) => {
- // 阻止该事件
event.preventDefault()
})
previewWin.on("close", (event) => {
- // 不关闭窗口
event.preventDefault()
- // 影藏窗口
previewWin.hide()
})
}
@@ -183,14 +194,12 @@ function createAria2Process() {
aria2Path = path.join(CONFIG.EXECUTABLE_PATH, `./${process.platform}/aria2` + (CONFIG.IS_DEV ? `/${process.arch}` : '/') + "/aria2c");
aria2Conf = path.join(CONFIG.EXECUTABLE_PATH, `./${process.platform}/aria2/aria2.conf`)
}
- // 启动 aria2
- console.log("启动 aria2")
aria2Process = spawn(aria2Path, [`--conf-path=${aria2Conf}`, `--rpc-listen-port=${CONFIG.ARIA_PORT}`], {
windowsHide: false,
stdio: CONFIG.IS_DEV ? 'pipe' : 'ignore'
});
if(!aria2Process){
- console.log("启动 aria2 失败")
+ console.log("start aria2 error")
}
if (CONFIG.IS_DEV) {
aria2Process.stdout.on('data', (data) => {
@@ -200,16 +209,35 @@ function createAria2Process() {
console.log(`aria2 error: ${data}`);
});
}
- console.log("aria2 成功启动")
} catch (e) {
console.log(`aria2 process start err`, e);
}
}
+function initConfig(){
+ const configPath = path.join(app.getPath('userData'), 'resd_config.json')
+ if (!fs.existsSync(configPath)) {
+ return
+ }
+ const buff = fs.readFileSync(configPath);
+ if (buff) {
+ try {
+ const jsonData = JSON.parse(buff)
+ global.resdConfig = Object.assign({}, global.resdConfig, jsonData)
+ if (!global.resdConfig.port) {
+ global.resdConfig.port = 8899
+ }
+ } catch (parseErr) {
+ }
+ }
+}
+
app.whenReady().then(() => {
- initIPC()
createWindow()
createPreviewWindow(mainWindow)
- createAria2Process()
setWin(mainWindow, previewWin)
+ initConfig()
+ initIPC()
+ startServer(mainWindow)
+ createAria2Process()
})
\ No newline at end of file
diff --git a/electron/main/ipc.ts b/electron/main/ipc.ts
index 4b988e1..4927e23 100755
--- a/electron/main/ipc.ts
+++ b/electron/main/ipc.ts
@@ -7,10 +7,12 @@ import {hexMD5} from '../../src/common/md5'
import {Aria2RPC} from './aria2Rpc'
import fs from "fs"
import urlTool from "url";
+import {closeProxy, setProxy} from "./setProxy";
+import path from 'path'
let win: BrowserWindow
let previewWin: BrowserWindow
-let isStartProxy = false
+
const aria2RpcClient = new Aria2RPC()
export default function initIPC() {
@@ -21,23 +23,54 @@ export default function initIPC() {
ipcMain.handle('invoke_init_app', (event, arg) => {
// 开始 初始化应用 安装证书相关
- installCert(false).then(r => {
- })
+ installCert(false)
+ })
+
+ ipcMain.handle('invoke_set_config', (event, data) => {
+ const filePath = path.join(app.getPath('userData'), 'resd_config.json');
+ fs.writeFile(filePath, JSON.stringify(data), ()=>{})
+ global.resdConfig = Object.assign({}, global.resdConfig, data)
+ global.resdConfig.port = parseInt(global.resdConfig.port)
+ return true
})
- ipcMain.handle('invoke_start_proxy', (event, arg) => {
+ ipcMain.handle('invoke_set_proxy', async (event, arg) => {
// 启动代理服务
- if (isStartProxy) {
- return
+ if (!global.isStartProxy) {
+ dialog.showMessageBoxSync({
+ type: "error",
+ message: "代理未启动",
+ });
+ return false
}
- isStartProxy = true
- return startServer({
- win: win,
- upstreamProxy: arg.upstream_proxy ? arg.upstream_proxy : "",
- setProxyErrorCallback: err => {
- console.log('setProxyErrorCallback', err)
- },
- })
+ try {
+ if (arg.proxy) {
+ await setProxy('127.0.0.1', global.resdConfig.port)
+ }else{
+ await closeProxy('127.0.0.1', global.resdConfig.port)
+ }
+ return true
+ } catch (err) {
+ console.error(err);
+ dialog.showMessageBoxSync({
+ type: "error",
+ message: err.toString(),
+ });
+ return false
+ }
+ // let upstream_proxy = ""
+ // if (arg.upstream_proxy && !arg.upstream_proxy.includes(':8899')) {
+ // upstream_proxy = arg.upstream_proxy
+ // }
+ //
+ // global.isStartProxy = true
+ // return startServer({
+ // win: win,
+ // upstreamProxy: upstream_proxy,
+ // setProxyErrorCallback: err => {
+ // console.log('setProxyErrorCallback', err)
+ // },
+ // })
})
ipcMain.handle('invoke_select_down_dir', async (event, arg) => {
@@ -72,7 +105,7 @@ export default function initIPC() {
resolve(false);
});
}
- if(quality === "0" && data.decode_key){
+ if (quality === "0" && data.decode_key) {
const urlInfo = urlTool.parse(down_url, true);
console.log('urlInfo', urlInfo)
if (urlInfo.query["token"] && urlInfo.query["encfilekey"]) {
@@ -103,18 +136,18 @@ export default function initIPC() {
return new Promise((resolve, reject) => {
- if (down_url.includes("douyin")) {
- headers['Referer'] = down_url
+ if (data?.referer) {
+ headers['Referer'] = data?.referer
}
aria2RpcClient.addUri([down_url], save_path, fileName, headers).then((response) => {
- let currentGid = response.result // 保存当前下载的 gid
+ let currentGid = response.result
let progressIntervalId = null
// // 开始定时查询下载进度
progressIntervalId = setInterval(() => {
aria2RpcClient.tellStatus(currentGid).then((status) => {
if (status.result.status !== "complete") {
- const progress = aria2RpcClient.calculateDownloadProgress(status.result.bitfield);
+ const progress = aria2RpcClient.calculateDownloadProgress(status.result.bitfield)
win?.webContents.send('on_down_file_schedule', {schedule: `已下载${progress}%`})
} else {
clearInterval(progressIntervalId);
@@ -123,26 +156,26 @@ export default function initIPC() {
decodeWxFile(save_path_file, data.decode_key, save_path_file.replace(".mp4", "_wx.mp4")).then((res) => {
fs.unlink(save_path_file, (err) => {
})
- resolve(res);
+ resolve(res)
}).catch((error) => {
console.log("err:", error)
resolve(false);
- });
+ })
} else {
resolve({
fullFileName: save_path_file,
- });
+ })
}
}
}).catch((error) => {
- console.error(error);
- clearInterval(progressIntervalId);
- resolve(false);
+ console.error(error)
+ clearInterval(progressIntervalId)
+ resolve(false)
});
- }, 1000);
+ }, 1000)
}).catch((error) => {
console.log("err:", error)
- resolve(false);
+ resolve(false)
});
});
});
diff --git a/electron/main/proxyServer.ts b/electron/main/proxyServer.ts
index a3929b3..4a120cb 100755
--- a/electron/main/proxyServer.ts
+++ b/electron/main/proxyServer.ts
@@ -1,7 +1,6 @@
import fs from 'fs'
import log from 'electron-log'
import CONFIG from './const'
-import {setProxy} from './setProxy'
import * as urlTool from "url"
import {toSize, typeSuffix} from "./utils"
// @ts-ignore
@@ -10,10 +9,6 @@ import pkg from '../../package.json'
const hoXy = require('hoxy')
-const port = 8899
-
-global.videoList = {}
-
if (process.platform === 'win32') {
process.env.OPENSSL_BIN = CONFIG.OPEN_SSL_BIN_PATH
process.env.OPENSSL_CONF = CONFIG.OPEN_SSL_CNF_PATH
@@ -22,6 +17,7 @@ if (process.platform === 'win32') {
const resObject = {
url: "",
url_sign: "",
+ referer: "",
cover_url: "",
file_format: "",
platform: "",
@@ -34,144 +30,144 @@ const resObject = {
description: ""
}
-const vv = hexMD5(pkg.version) + (CONFIG.IS_DEV ? Math.random() :"")
+const vv = hexMD5(pkg.version) + (CONFIG.IS_DEV ? Math.random() : "")
-export async function startServer({win, upstreamProxy, setProxyErrorCallback = f => f,}) {
- return new Promise(async (resolve: any, reject) => {
- try {
- const proxy = hoXy.createServer({
- upstreamProxy: upstreamProxy,
- certAuthority: {
- key: fs.readFileSync(CONFIG.CERT_PRIVATE_PATH),
- cert: fs.readFileSync(CONFIG.CERT_PUBLIC_PATH),
- },
+export function startServer(win) {
+ try {
+ let upstreamProxy = ""
+ if (global.resdConfig.proxy && !global.resdConfig.proxy.includes(':' + global.resdConfig.port)) {
+ upstreamProxy = global.resdConfig?.proxy
+ }
+ console.log("global.resdConfig.port:", global.resdConfig.port)
+ const proxy = hoXy.createServer({
+ upstreamProxy: upstreamProxy,
+ certAuthority: {
+ key: fs.readFileSync(CONFIG.CERT_PRIVATE_PATH),
+ cert: fs.readFileSync(CONFIG.CERT_PUBLIC_PATH),
+ },
+ })
+ .listen(global.resdConfig.port, () => {
+ global.isStartProxy = true
})
- .listen(port, async () => {
- try {
- await setProxy('127.0.0.1', port)
- resolve()
- } catch (err) {
- console.error(err);
- setProxyErrorCallback(err)
- reject("请手动设置系统代理" + err.toString())
- }
- })
- .on('error', err => {
- setProxyErrorCallback(err)
- reject('proxy service err: ' + err.toString())
- })
+ .on('error', err => {
+ console.error("hoXy err:", err);
+ })
+ intercept(proxy, win)
+ } catch (e) {
+ console.error("--------------proxy catch err--------------");
+ }
+}
+function intercept(proxy, win) {
+ proxy.intercept(
+ {
+ phase: 'request',
+ hostname: 'res-downloader.666666.com',
+ as: 'json',
+ },
+ (req, res) => {
+ res.string = 'ok'
+ res.statusCode = 200
+ try {
+ if (req.json?.media?.length <= 0) {
+ return
+ }
+ const media = req.json?.media[0]
+ const url_sign: string = hexMD5(media.url)
+ if (!media?.decodeKey || global.videoList.hasOwnProperty(url_sign) === true) {
+ return
+ }
+ const urlInfo = urlTool.parse(media.url, true)
+ global.videoList[url_sign] = media.url
+ win.webContents.send('on_get_queue', Object.assign({}, resObject, {
+ url_sign: url_sign,
+ url: media.url + media.urlToken,
+ cover_url: media.coverUrl,
+ referer: "",
+ file_format: media.spec.map((res) => res.fileFormat).join('#'),
+ platform: urlInfo.hostname,
+ size: toSize(media.fileSize),
+ type: "video/mp4",
+ type_str: 'video',
+ decode_key: media.decodeKey,
+ description: req.json.description,
+ }))
+ } catch (e) {
+ log.log(e.toString())
+ }
+ },
+ )
- proxy.intercept(
- {
- phase: 'request',
- hostname: 'res-downloader.666666.com',
- as: 'json',
- },
- (req, res) => {
- res.string = 'ok'
- res.statusCode = 200
- try {
- if (req.json?.media?.length <= 0) {
- return
- }
- const media = req.json?.media[0]
- const url_sign: string = hexMD5(media.url)
- if (!media?.decodeKey || global.videoList.hasOwnProperty(url_sign) === true) {
- return
- }
- const urlInfo = urlTool.parse(media.url, true)
- global.videoList[url_sign] = media.url
+ proxy.intercept(
+ {
+ phase: 'response',
+ hostname: 'channels.weixin.qq.com',
+ as: 'string',
+ },
+ async (req, res) => {
+ if (req.url.includes('/web/pages/feed') || req.url.includes('/web/pages/home')) {
+ res.string = res.string.replaceAll('.js"', '.js?v=' + vv + '"')
+ res.statusCode = 200
+ }
+ },
+ )
+
+ proxy.intercept(
+ {
+ phase: 'response',
+ hostname: 'res.wx.qq.com',
+ as: 'string',
+ },
+ async (req, res) => {
+ if (req.url.endsWith('.js?v=' + vv)) {
+ res.string = res.string.replaceAll('.js"', '.js?v=' + vv + '"');
+ }
+ if (req.url.includes("web/web-finder/res/js/virtual_svg-icons-register.publish")) {
+ res.string = res.string.replace(/get\s*media\s*\(\)\s*\{/, `
+ get media(){
+ if(this.objectDesc){
+ fetch("https://res-downloader.666666.com", {
+ method: "POST",
+ mode: "no-cors",
+ body: JSON.stringify(this.objectDesc),
+ });
+ };
+ `)
+ }
+ }
+ );
+
+ proxy.intercept(
+ {
+ phase: 'response',
+ },
+ async (req, res) => {
+ try {
+ // 拦截响应
+ const contentType = res?._data?.headers?.['content-type']
+ const [resType, suffix] = typeSuffix(contentType)
+ if (resType) {
+ const url_sign: string = hexMD5(req.fullUrl())
+ const res_url = req.fullUrl()
+ const urlInfo = urlTool.parse(res_url, true)
+ const contentLength = res?._data?.headers?.['content-length']
+ if (global.videoList.hasOwnProperty(url_sign) === false) {
+ global.videoList[url_sign] = res_url
+ let referer = req?._data?.headers?.['referer']
win.webContents.send('on_get_queue', Object.assign({}, resObject, {
+ url: res_url,
url_sign: url_sign,
- url: media.url + media.urlToken,
- cover_url: media.coverUrl,
- file_format: media.spec.map((res)=> res.fileFormat).join('#'),
+ referer: referer ? referer : "",
platform: urlInfo.hostname,
- size: toSize(media.fileSize),
- type: "video/mp4",
- type_str: 'video',
- decode_key: media.decodeKey,
- description: req.json.description,
+ size: toSize(contentLength ? contentLength : 0),
+ type: contentType,
+ type_str: resType,
}))
- } catch (e) {
- log.log(e.toString())
- }
- },
- )
-
- proxy.intercept(
- {
- phase: 'response',
- hostname: 'channels.weixin.qq.com',
- as: 'string',
- },
- async (req, res) => {
- if (req.url.includes('/web/pages/feed') || req.url.includes('/web/pages/home')) {
- res.string = res.string.replaceAll('.js"', '.js?v=' + vv + '"')
- res.statusCode = 200
- }
- },
- )
-
- proxy.intercept(
- {
- phase: 'response',
- hostname: 'res.wx.qq.com',
- as: 'string',
- },
- async (req, res) => {
- if (req.url.endsWith('.js?v=' + vv)) {
- res.string = res.string.replaceAll('.js"', '.js?v=' + vv + '"');
- }
- if (req.url.includes("web/web-finder/res/js/virtual_svg-icons-register.publish")) {
- res.string = res.string.replace(/get\s*media\s*\(\)\s*\{/, `
- get media(){
- if(this.objectDesc){
- fetch("https://res-downloader.666666.com", {
- method: "POST",
- mode: "no-cors",
- body: JSON.stringify(this.objectDesc),
- });
- };
- `)
}
}
- );
-
- proxy.intercept(
- {
- phase: 'response',
- },
- async (req, res) => {
- try {
- // 拦截响应
- const contentType = res?._data?.headers?.['content-type']
- const [resType, suffix] = typeSuffix(contentType)
- if (resType) {
- const url_sign: string = hexMD5(req.fullUrl())
- const res_url = req.fullUrl()
- const urlInfo = urlTool.parse(res_url, true)
- const contentLength = res?._data?.headers?.['content-length']
- if (global.videoList.hasOwnProperty(url_sign) === false) {
- global.videoList[url_sign] = res_url
- win.webContents.send('on_get_queue', Object.assign({}, resObject, {
- url: res_url,
- url_sign: url_sign,
- platform: urlInfo.hostname,
- size: toSize(contentLength ? contentLength : 0),
- type: contentType,
- type_str: resType,
- }))
- }
- }
- } catch (e) {
- log.log(e.toString())
- }
- },
- )
- } catch (e) {
- log.log("--------------proxy catch err--------------", e)
- }
- })
+ } catch (e) {
+ log.log("--------------proxy response err--------------", e)
+ }
+ },
+ )
}
\ No newline at end of file
diff --git a/electron/main/setProxy.ts b/electron/main/setProxy.ts
index 1b36148..2524271 100755
--- a/electron/main/setProxy.ts
+++ b/electron/main/setProxy.ts
@@ -38,7 +38,7 @@ export async function setProxy(host, port) {
} else if (process.platform === 'linux') {
dialog.showMessageBoxSync({
type: "info",
- message: `请手动设置系统代理`,
+ message: `请手动设置系统代理 默认为: 127.0.0.1:8899`,
});
return new Promise((resolve, reject) => {})
} else {
diff --git a/electron/main/utils.ts b/electron/main/utils.ts
index e6c8f5a..5c2e86d 100755
--- a/electron/main/utils.ts
+++ b/electron/main/utils.ts
@@ -99,7 +99,7 @@ function toSize(size: number) {
}
function typeSuffix(type: string) {
- switch (type) {
+ switch (type ? type.toLowerCase() : type) {
case "video/mp4":
case "video/webm":
case "video/ogg":
@@ -111,7 +111,7 @@ function typeSuffix(type: string) {
case "video/x-matroska":
return ["video", ".mp4"];
case "audio/video":
- case "video/x-flv":
+ case "video/x-flv":
return ["live", ".mp4"];
case "image/png":
case "image/webp":
@@ -143,7 +143,7 @@ function typeSuffix(type: string) {
case "audio/mp4;charset=UTF-8":
return ["audio", ".mp3"];
case "application/vnd.apple.mpegurl":
- case "application/x-mpegURL":
+ case "application/x-mpegurl":
return ["m3u8", ".m3u8"];
case "application/pdf":
return ["pdf", ".pdf"];
diff --git a/package.json b/package.json
index 0d402ed..407a670 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "res-downloader",
- "version": "2.1.3",
+ "version": "2.2.0",
"main": "dist-electron/main/index.js",
"description": "res-downloader(爱享素材下载器),支持视频号、小程序、抖音、快手、小红书、酷狗音乐、qq音乐、qq短视频等",
"homepage": "https://github.com/putyy/res-downloader",
diff --git a/src/App.vue b/src/App.vue
index 4d0a6d8..d10c89c 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,8 +1,12 @@
-
+
+
+