diff --git a/packages/main/bin/win32/NO_UPDATE b/packages/main/bin/win32/NO_UPDATE
deleted file mode 100644
index e69de29b..00000000
diff --git a/packages/main/bin/win32/N_m3u8DL-CLI.exe b/packages/main/bin/win32/N_m3u8DL-CLI.exe
deleted file mode 100644
index 30acb3b9..00000000
Binary files a/packages/main/bin/win32/N_m3u8DL-CLI.exe and /dev/null differ
diff --git a/packages/main/bin/win32/N_m3u8DL-RE.exe b/packages/main/bin/win32/N_m3u8DL-RE.exe
new file mode 100644
index 00000000..73c8119d
Binary files /dev/null and b/packages/main/bin/win32/N_m3u8DL-RE.exe differ
diff --git a/packages/main/package.json b/packages/main/package.json
index f54ddb70..557448ab 100644
--- a/packages/main/package.json
+++ b/packages/main/package.json
@@ -47,8 +47,6 @@
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "6.1.1",
"gulp": "^5.0.0",
- "gulp-chmod": "^4.0.0",
- "gulp-if": "^3.0.0",
"prebuild-install": "^7.1.1",
"prettier": "3.2.5",
"semver": "^7.5.4",
@@ -75,6 +73,6 @@
"node-pty": "^1.0.0",
"reflect-metadata": "^0.2.1",
"strip-ansi": "^7.1.0",
- "typeorm": "^0.3.19"
+ "typeorm": "0.3.17"
}
}
diff --git a/packages/main/scripts/config.ts b/packages/main/scripts/config.ts
index 7970f660..d98606ec 100644
--- a/packages/main/scripts/config.ts
+++ b/packages/main/scripts/config.ts
@@ -22,7 +22,7 @@ function getConfig(): esbuild.BuildOptions {
process.env.NODE_ENV === "development"
? {
// 开发环境中二进制可执行文件的路径
- __bin__: `"${mainResolve("bin", process.platform).replace(/\\/g, "\\\\")}"`,
+ __bin__: `"${mainResolve("app/bin").replace(/\\/g, "\\\\")}"`,
}
: {
...env,
diff --git a/packages/main/scripts/index.ts b/packages/main/scripts/index.ts
index 0e6d24b1..3c3d4866 100644
--- a/packages/main/scripts/index.ts
+++ b/packages/main/scripts/index.ts
@@ -1,14 +1,15 @@
import { deleteSync } from "del";
-import { ElectronApp, mainResolve, Env, isMac, isLinux } from "./utils";
+import { ElectronApp, mainResolve, Env, isWin } from "./utils";
import gulp from "gulp";
-import chmod from "gulp-chmod";
import * as esbuild from "esbuild";
import consola from "consola";
import { browserOptions, nodeOptions, getReleaseConfig } from "./config";
-import gulpIf from "gulp-if";
import semver from "semver";
import pkg from "../app/package.json";
import * as builder from "electron-builder";
+import glob from "glob";
+import path from "path";
+import fs from "fs";
process.env.NODE_ENV = "development";
@@ -23,25 +24,40 @@ async function clean() {
]);
}
-// function copySqlLite() {
-// const path = "build/Release/better_sqlite3.node";
-// const from = mainResolve("node_modules/better-sqlite3", path);
-// const to = mainResolve("app/build/Release");
-// return gulp.src(from).pipe(gulp.dest(to));
-// }
-
-function copyBin() {
- return gulp
- .src(mainResolve("bin", process.platform, "*"), {
- ignore: [".gitignore", "Logs/**/*"],
- })
- .pipe(gulp.dest(mainResolve("app/bin")));
+async function copyBin() {
+ const sourceDir = mainResolve("bin", process.platform);
+ const targetDir = mainResolve("app/bin");
+
+ // 获取源目录下的所有文件
+ const files = glob.sync(path.join(sourceDir, "*"));
+
+ // 遍历每个文件
+ for (const file of files) {
+ // 忽略 .gitignore 文件和 Logs 文件夹
+ if (file.endsWith(".gitignore") || file.includes("Logs")) {
+ continue;
+ }
+
+ // 计算目标文件的路径
+ const targetFile = path.join(targetDir, path.basename(file));
+ // 如果没有文件夹则创建文件夹
+ if (!fs.existsSync(targetDir)) {
+ fs.mkdirSync(targetDir);
+ }
+
+ // 复制文件
+ fs.copyFileSync(file, targetFile);
+ }
}
-function chmodBin() {
- return gulp
- .src(mainResolve("app/bin/*"))
- .pipe(gulpIf(isMac || isLinux, chmod(0o777)));
+async function chmodBin() {
+ // 遍历文件夹下的所有文件,将文件的权限设置为 777
+ if (isWin) return;
+
+ const files = glob.sync(mainResolve("app/bin/*"));
+ for (const file of files) {
+ fs.chmodSync(file, 0o777);
+ }
}
const copy = gulp.parallel(copyBin);
diff --git a/packages/main/src/helper/variables.ts b/packages/main/src/helper/variables.ts
index 71df23fd..534596d2 100644
--- a/packages/main/src/helper/variables.ts
+++ b/packages/main/src/helper/variables.ts
@@ -39,11 +39,9 @@ export const PERSIST_WEBVIEW = "persist:webview";
export const db = resolve(workspace, "app.db");
// bin path
-const downloaderBinName = isWin ? "N_m3u8DL-CLI" : "N_m3u8DL-RE";
export const ffmpegPath = resolveBin("ffmpeg");
export const biliDownloaderBin = resolveBin("BBDown");
-export const m3u8DownloaderBin = resolveBin(downloaderBinName);
-export const videoServerBin = resolveBin("server");
+export const m3u8DownloaderBin = resolveBin("N_m3u8DL-RE");
// plugin path
export const pluginPath = resolveStatic("plugin/index.js");
diff --git a/packages/main/src/repository/VideoRepository.ts b/packages/main/src/repository/VideoRepository.ts
index a337c445..9f6c2a6a 100644
--- a/packages/main/src/repository/VideoRepository.ts
+++ b/packages/main/src/repository/VideoRepository.ts
@@ -114,12 +114,12 @@ export default class VideoRepository {
async changeVideoStatus(id: number | number[], status: DownloadStatus) {
const ids = !Array.isArray(id) ? [id] : id;
- return this.db.appDataSource
- .createQueryBuilder()
- .update(Video)
- .set({ status })
- .where({ id: In(ids) })
- .execute();
+ const videoRepository = this.db.appDataSource.getRepository(Video);
+ const videos = await videoRepository.findBy({ id: In(ids) });
+ for (const video of videos) {
+ video.status = status;
+ }
+ await videoRepository.save(videos);
}
async changeVideoIsLive(id: number) {
diff --git a/packages/main/src/services/DownloadService.ts b/packages/main/src/services/DownloadService.ts
index 61d901b5..31d49af5 100644
--- a/packages/main/src/services/DownloadService.ts
+++ b/packages/main/src/services/DownloadService.ts
@@ -49,39 +49,7 @@ interface Schema {
const processList: Schema[] = [
{
type: "m3u8",
- platform: [Platform.Windows],
- bin: m3u8DownloaderBin,
- args: {
- url: {
- argsName: null,
- },
- localDir: {
- argsName: ["--workDir"],
- },
- name: {
- argsName: ["--saveName"],
- },
- // headers: {
- // argsName: ["--headers"],
- // },
- deleteSegments: {
- argsName: ["--enableDelAfterDone"],
- },
- proxy: {
- argsName: ["--proxyAddress"],
- },
- },
- consoleReg: {
- percent: "([\\d.]+)%",
- speed: "([\\d.]+\\s[GMK]B/s)",
- error: "ERROR",
- start: "开始下载文件|开始录制",
- isLive: "识别为直播流, 开始录制",
- },
- },
- {
- type: "m3u8",
- platform: [Platform.MacOS, Platform.Linux],
+ platform: [Platform.MacOS, Platform.Linux, Platform.Windows],
bin: m3u8DownloaderBin,
args: {
url: {
diff --git a/packages/renderer/src/App.tsx b/packages/renderer/src/App.tsx
index 2cd98d93..6d44fc4b 100644
--- a/packages/renderer/src/App.tsx
+++ b/packages/renderer/src/App.tsx
@@ -1,8 +1,7 @@
import { ConfigProvider, theme } from "antd";
import React, { FC, Suspense, lazy, useEffect } from "react";
-import AppLayout from "./layout/App";
import { useDispatch } from "react-redux";
-import { RouterProvider, createHashRouter } from "react-router-dom";
+import { BrowserRouter, Route, Routes } from "react-router-dom";
import { DownloadFilter } from "./nodes/HomePage";
import { setAppStore, increase } from "./store";
import "dayjs/locale/zh-cn";
@@ -11,63 +10,11 @@ import "./App.scss";
import useElectron from "./hooks/electron";
import Loading from "./components/Loading";
+const AppLayout = lazy(() => import("./layout/App"));
const HomePage = lazy(() => import("./nodes/HomePage"));
const SourceExtract = lazy(() => import("./nodes/SourceExtract"));
const SettingPage = lazy(() => import("./nodes/SettingPage"));
-const router = createHashRouter([
- {
- path: "/",
- element: ,
- children: [
- {
- index: true,
- element: (
- }>
-
-
- ),
- },
- {
- path: "done",
- element: (
- }>
-
-
- ),
- },
- {
- path: "source",
- element: (
- }>
-
-
- ),
- },
- {
- path: "settings",
- element: (
- }>
-
-
- ),
- },
- ],
- },
- {
- path: "/browser",
- element: (
- }>
-
-
- ),
- },
- {
- path: "*",
- element:
404
,
- },
-]);
-
function getAlgorithm(appTheme: "dark" | "light") {
return appTheme === "dark" ? theme.darkAlgorithm : theme.defaultAlgorithm;
}
@@ -125,7 +72,60 @@ const App: FC = () => {
componentSize="small"
theme={{ algorithm: getAlgorithm(appTheme) }}
>
-
+
+
+ }>
+
+
+ }
+ >
+ }>
+
+
+ }
+ />
+ }>
+
+
+ }
+ />
+ }>
+
+
+ }
+ />
+ }>
+
+
+ }
+ />
+ 404} />
+
+ }>
+
+
+ }
+ />
+
+
);
};
diff --git a/packages/renderer/src/nodes/HomePage/index.tsx b/packages/renderer/src/nodes/HomePage/index.tsx
index 650b06d8..e1774708 100644
--- a/packages/renderer/src/nodes/HomePage/index.tsx
+++ b/packages/renderer/src/nodes/HomePage/index.tsx
@@ -26,9 +26,9 @@ import {
import { useSelector } from "react-redux";
import { selectAppStore } from "../../store";
import DownloadFrom from "../../components/DownloadForm";
-import dayjs from "dayjs";
import { Trans, useTranslation } from "react-i18next";
import Terminal from "../../components/Terminal";
+import { moment } from "../../utils";
const { Text } = Typography;
@@ -60,7 +60,12 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => {
} = useElectron();
const appStore = useSelector(selectAppStore);
const { t } = useTranslation();
- const { data, loading, pagination, refresh } = usePagination(
+ const {
+ data = { total: 0, list: [] },
+ loading,
+ pagination,
+ refresh,
+ } = usePagination(
({ current, pageSize }) => {
return getDownloadItems({
current,
@@ -84,7 +89,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => {
log: "",
});
- const onDownloadProgress = (e: any, progress: DownloadProgress) => {
+ const onDownloadProgress = (e: unknown, progress: DownloadProgress) => {
setProgress((curProgress) => ({
...curProgress,
[progress.id]: progress,
@@ -411,9 +416,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => {
const items = batchList.split("\n").map((item: any) => {
let [url, name] = item.split(" ");
url = url ? url.trim() : "";
- name = name
- ? name.trim()
- : dayjs().format("YYYY-MM-DDTHH:mm:ssZ");
+ name = name ? name.trim() : moment();
return {
url,
name,
@@ -423,7 +426,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => {
await addDownloadItems(items);
} else {
await addDownloadItem({
- name: values.name || dayjs().format("YYYY-MM-DDTHH:mm:ssZ"),
+ name: values.name || moment(),
url: values.url,
headers: values.headers,
type: DownloadType.m3u8,
@@ -464,7 +467,7 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => {
}}
rowKey="id"
rowSelection={rowSelection}
- dataSource={data?.list || []}
+ dataSource={data.list || []}
tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => {
if (selectedRowKeys.length === 0) {
return null;
@@ -496,11 +499,11 @@ const HomePage: FC = ({ filter = DownloadFilter.list }) => {
tableAlertRender={({ selectedRows }) => {
return (
<>
- {data?.list.length !== 0 && (
+ {data.list.length !== 0 && (