Skip to content

Commit

Permalink
内置aria2下载、增加视频号画质设置、取消重复下载限制、优化下载命名等
Browse files Browse the repository at this point in the history
  • Loading branch information
putyy committed Aug 30, 2024
1 parent c1f0587 commit 6b79585
Show file tree
Hide file tree
Showing 44 changed files with 353 additions and 115 deletions.
25 changes: 23 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# V2.0重磅更新,所见即所得!
## res-downloader(爱享素材下载器)
## res-downloader(爱享素材下载器) 【[点击加入群聊](https://qm.qq.com/q/W8mVeZideE)
🎯 基于 [electron-vite-vue](https://github.com/electron-vite/electron-vite-vue.git)
📦 操作简单、可获取不同类型的资源
🖥️ 支持Win10、Win11、Mac
🌐 支持视频、音频、图片、m3u8等网络资源下载
💪 支持微信视频号、小程序、抖音、快手、小红书、酷狗音乐、qq音乐等网络资源下载
Expand Down Expand Up @@ -38,5 +39,25 @@ Win7无法使用
>> MAC: /Users/你的用户名称/.res-downloader@putyy/res-downloader-installed.lock
>> Win: C:\Users\Admin\.res-downloader@putyy/res-downloader-installed.lock
其他问题请留言 https://github.com/putyy/res-downloader/issues

## 二次开发
> ps: 打包慢的问题可以参考 https://www.putyy.com/articles/87
```sh
git clone https://github.com/putyy/res-downloader

cd res-downloader

yarn install

yarn run dev

# 打包mac
yarn run build --universal --mac

# 打包win
yarn run build --win
```

## 免责声明
本软件用于学习研究使用,若因使用本软件造成的一切法律责任均与本人无关!
3 changes: 3 additions & 0 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ 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']
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
Footer: typeof import('./src/components/layout/Footer.vue')['default']
Index: typeof import('./src/components/layout/Index.vue')['default']
Expand Down
33 changes: 27 additions & 6 deletions electron-builder.json5
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
{
"$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json",
"appId": "com.putyy.ResDownloader",
"appId": "com.putyy.res-downloader",
"asar": true,
"directories": {
"output": "release/${version}"
Expand All @@ -14,21 +14,35 @@
"electron/res/**/*"
],
"mac": {
"icon": "electron/res/icon/icons/mac/icon.icns",
"icon": "electron/res/icon/mac.icns",
"artifactName": "${productName}_${version}.${arch}.${ext}",
"singleArchFiles": "*",
"target": [
{
"target": "dmg",
"arch": [
'x64',
'arm64'
'arm64',
'universal'
]
}
],
"extraResources": [
{
"from": "electron/res/mac/aria2/aria2.conf",
"to": "electron/res/mac/aria2/aria2.conf",
"filter": ["**/*"]
},
{
"from": "electron/res/mac/aria2/${arch}/aria2c",
"to": "electron/res/mac/aria2/aria2c",
"filter": ["**/*"],
}
]
},
"win": {
"icon": "electron/res/icon/icons/win/icon.ico",
"icon": "electron/res/icon/win.ico",
"artifactName": "${productName}_${version}.${ext}",
"target": [
{
"target": "nsis",
Expand All @@ -37,7 +51,13 @@
]
}
],
"artifactName": "${productName}_${version}.${ext}"
"extraResources": [
{
"from": "electron/res/win",
"to": "electron/res/win",
"filter": ["**/*"],
}
]
},
"nsis": {
"oneClick": false,
Expand All @@ -47,6 +67,7 @@
"deleteAppDataOnUninstall": false
},
"extraResources": [
"electron/res"
"electron/res/icon",
"electron/res/keys",
]
}
51 changes: 51 additions & 0 deletions electron/main/aria2Rpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const axios = require('axios')
import CONFIG from './const'

export class Aria2RPC {
constructor() {
this.url = `http://127.0.0.1:${CONFIG.ARIA_PORT}/jsonrpc`
this.id = 1
}

call(method, params) {
const requestData = {
jsonrpc: "2.0",
method: method,
params: params,
id: this.id++
};
return axios.post(this.url, requestData, {
headers: {
'Content-Type': 'application/json'
},
}).then((response)=>{
return response.data
})
}

addUri(uri, dir, filename, headers = {}) {
return this.call('aria2.addUri', [uri, {
dir: dir,
out: filename,
headers: headers,
}]);
}

tellStatus(gid) {
return this.call('aria2.tellStatus', [gid]);
}

calculateDownloadProgress(bitfield) {
// 将十六进制的 bitfield 转换为二进制字符串
const totalPieces = bitfield.length * 4; // 每个十六进制字符对应 4 位
const binaryString = bitfield.split('').map(hex => parseInt(hex, 16).toString(2).padStart(4, '0')).join('');

// 计算已下载的部分数
const downloadedPieces = binaryString.split('').filter(bit => bit === '1').length;

// 计算进度百分比
const progressPercentage = (downloadedPieces / totalPieces) * 100;

return progressPercentage.toFixed(2); // 保留两位小数
}
}
2 changes: 1 addition & 1 deletion electron/main/cert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function installCert(checkInstalled = true) {
`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',
type: "info",
message: `命令已复制到剪贴板,粘贴命令到终端并运行以安装并信任证书`,
});

Expand Down
13 changes: 7 additions & 6 deletions electron/main/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ export default {
IS_DEV: isDev,
EXECUTABLE_PATH,
HOME_PATH,
APP_CN_NAME: '爱享素材下载器',
APP_EN_NAME: 'ResDownloader',
CERT_PRIVATE_PATH: path.join(EXECUTABLE_PATH, './keys/private.pem'),
CERT_PUBLIC_PATH: path.join(EXECUTABLE_PATH, './keys/public.pem'),
INSTALL_CERT_FLAG: path.join(HOME_PATH, './res-downloader-installed.lock'),
WIN_CERT_INSTALL_HELPER: path.join(EXECUTABLE_PATH, './w_c.exe'),
APP_CN_NAME: '爱享素材下载器',
APP_EN_NAME: 'ResDownloader',
REGEDIT_VBS_PATH: path.join(EXECUTABLE_PATH, './regedit-vbs'),
OPEN_SSL_BIN_PATH: path.join(EXECUTABLE_PATH, './openssl/openssl.exe'),
OPEN_SSL_CNF_PATH: path.join(EXECUTABLE_PATH, './openssl/openssl.cnf'),
WIN_CERT_INSTALL_HELPER: path.join(EXECUTABLE_PATH, './win/w_c.exe'),
REGEDIT_VBS_PATH: path.join(EXECUTABLE_PATH, './win/regedit-vbs'),
OPEN_SSL_BIN_PATH: path.join(EXECUTABLE_PATH, './win/openssl/openssl.exe'),
OPEN_SSL_CNF_PATH: path.join(EXECUTABLE_PATH, './win/openssl/openssl.cnf'),
ARIA_PORT: "18899",
};
66 changes: 51 additions & 15 deletions electron/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import {release} from 'node:os'
import {join} from 'node:path'
import CONFIG from './const'
import initIPC, {setWin} from './ipc'
import {closeProxy} from "./setProxy"
import log from "electron-log"
import path from 'path'
import {spawn} from 'child_process'

// The built directory structure
//
Expand Down Expand Up @@ -45,6 +49,7 @@ process.on('unhandledRejection', () => {

let mainWindow: BrowserWindow | null = null
let previewWin: BrowserWindow | null = null
let aria2Process

// Here, you can also use other preload
const preload = join(__dirname, '../preload/index.js')
Expand Down Expand Up @@ -77,21 +82,16 @@ app.on('activate', () => {
}
})

// New window example arg: new windows url
ipcMain.handle('open-win', (_, arg) => {
const childWindow = new BrowserWindow({
webPreferences: {
preload,
nodeIntegration: true,
contextIsolation: false,
},
})

if (process.env.VITE_DEV_SERVER_URL) {
childWindow.loadURL(`${url}#${arg}`)
} else {
childWindow.loadFile(indexHtml, {hash: arg})
app.on('before-quit', async e => {
e.preventDefault()
try {
await closeProxy()
aria2Process && aria2Process.kill();
log.log("--------------closeProxy success--------------")
} catch (error) {
log.log("--------------proxy catch err--------------", error)
}
app.exit()
})

function createWindow() {
Expand Down Expand Up @@ -169,9 +169,45 @@ function createPreviewWindow(parent: BrowserWindow) {
})
}

function createArua2Process() {
// 根据操作系统选择 aria2 的路径
try {
let aria2Path, aria2Conf
if (process.platform === 'win32') {
// Windows
aria2Path = path.join(CONFIG.EXECUTABLE_PATH, "./win/aria2/aria2c.exe")
aria2Conf = path.join(CONFIG.EXECUTABLE_PATH, "./win/aria2/aria2.conf")
} else {
aria2Path = path.join(CONFIG.EXECUTABLE_PATH, "./mac/aria2" + (CONFIG.IS_DEV ? `/${process.arch}` : '/') + "/aria2c");
aria2Conf = path.join(CONFIG.EXECUTABLE_PATH, "./mac/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 失败")
}
if (CONFIG.IS_DEV) {
aria2Process.stdout.on('data', (data) => {
console.log(`aria2: ${data}`);
});
aria2Process.stderr.on('data', (data) => {
console.log(`aria2 error: ${data}`);
});
}
console.log("aria2 成功启动")
} catch (e) {
console.log(`aria2 process start err`, e);
}
}

app.whenReady().then(() => {
initIPC()
createWindow()
createPreviewWindow(mainWindow)
createArua2Process()
setWin(mainWindow, previewWin)
})
})
Loading

0 comments on commit 6b79585

Please sign in to comment.