Skip to content

Commit

Permalink
Merge pull request #53 from xpadev-net/develop
Browse files Browse the repository at this point in the history
release: v0.0.23
  • Loading branch information
xpadev-net authored Dec 27, 2023
2 parents b87bf5c + 3923b29 commit 5db1eb6
Show file tree
Hide file tree
Showing 18 changed files with 218 additions and 438 deletions.
24 changes: 12 additions & 12 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2019,
"project": ["./tsconfig.eslint.json"]
"ecmaVersion": 2019,
"project": ["./tsconfig.eslint.json"]
},
"parser": "@typescript-eslint/parser",
"plugins": [
Expand All @@ -18,16 +18,16 @@
],
"rules": {
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": "error",
"@next/next/no-img-element": "off",
"no-unused-vars": "off",
"no-control-regex": "off",
"import/no-duplicates": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"@typescript-eslint/explicit-function-return-type": [
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": "error",
"@next/next/no-img-element": "off",
"no-unused-vars": "off",
"no-control-regex": "off",
"import/no-duplicates": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"@typescript-eslint/explicit-function-return-type": [
"error",
{
"allowTypedFunctionExpressions": true,
Expand Down
18 changes: 9 additions & 9 deletions electron/ffmpeg.ts → electron/assets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { AxiosProgressEvent, AxiosResponse } from "axios";
import axios from "axios";
import { app } from "electron";
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
Expand All @@ -11,6 +10,7 @@ import {
createBinaryDownloaderWindow,
sendMessageToBinaryDownloader,
} from "./binary-downloader-window";
import { basePath } from "./context";
import { spawn } from "./lib/spawn";

type lib = "ffmpeg" | "ffprobe";
Expand All @@ -19,11 +19,11 @@ let target: lib[] = [];

const ext = process.platform === "win32" ? ".exe" : "";

const basePath = path.join(__dirname, app.isPackaged ? "../../../" : "", "bin"),
ffmpegPath = path.join(basePath, `ffmpeg${ext}`),
ffprobePath = path.join(basePath, `ffprobe${ext}`);
const binPath = path.join(basePath, "bin"),
ffmpegPath = path.join(binPath, `ffmpeg${ext}`),
ffprobePath = path.join(binPath, `ffprobe${ext}`);

const baseUrl = {
const assetsBaseUrl = {
ffmpeg:
"https://github.com/descriptinc/ffmpeg-ffprobe-static/releases/download/b4.4.0-rc.11/",
};
Expand Down Expand Up @@ -74,20 +74,20 @@ const onStartUp = async (): Promise<void> => {
};

const downloadBinary = async (target: lib[]): Promise<void> => {
if (!fs.existsSync(basePath)) {
await fs.promises.mkdir(basePath, { recursive: true });
if (!fs.existsSync(binPath)) {
await fs.promises.mkdir(binPath, { recursive: true });
}
if (target.includes("ffmpeg")) {
await downloadFile(
"ffmpeg",
`${baseUrl.ffmpeg}ffmpeg-${distro.ffmpeg}`,
`${assetsBaseUrl.ffmpeg}ffmpeg-${distro.ffmpeg}`,
ffmpegPath,
);
}
if (target.includes("ffprobe")) {
await downloadFile(
"ffprobe",
`${baseUrl.ffmpeg}ffprobe-${distro.ffmpeg}`,
`${assetsBaseUrl.ffmpeg}ffprobe-${distro.ffmpeg}`,
ffprobePath,
);
}
Expand Down
5 changes: 4 additions & 1 deletion electron/context.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { app } from "electron";
import * as path from "path";

const baseUrl = app.isPackaged
? `file://${__dirname}/html/index.html`
: "http://localhost:5173";

const basePath = path.join(__dirname, app.isPackaged ? "../../../" : "");

const appPrefix = "niconicomments-convert";

export { appPrefix, baseUrl };
export { appPrefix, basePath, baseUrl };
20 changes: 17 additions & 3 deletions electron/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import type {
} from "@/@types/response.controller";
import type { SpawnResult } from "@/@types/spawn";

import { ffprobePath } from "./assets";
import { sendMessageToController } from "./controller-window";
import { ffprobePath } from "./ffmpeg";
import { encodeJson } from "./lib/json";
import { encodeError } from "./lib/json";
import { getLogger } from "./lib/log";
import { spawn } from "./lib/spawn";
import { store } from "./store";
import { identifyCommentFormat } from "./utils/niconicomments";

const logger = getLogger("[dialog]");

const selectFile = async (
pattern: Electron.FileFilter[],
): Promise<OpenDialogReturnValue> => {
Expand Down Expand Up @@ -59,6 +62,7 @@ const selectMovie = async (): Promise<
]).promise;
} catch (e: unknown) {
const error = e as SpawnResult;
logger.error("failed to execute ffprobe", "error:", error);
return {
type: "message",
title: "動画ファイルの解析に失敗しました",
Expand All @@ -68,17 +72,25 @@ const selectMovie = async (): Promise<
try {
metadata = JSON.parse(ffprobe.stdout) as FfprobeOutput;
} catch (e) {
logger.error(
"failed to parse ffprobe output",
"error:",
e,
"stdout:",
ffprobe.stdout,
);
return {
type: "message",
title: "動画ファイルの解析に失敗しました",
message: `ffprobeの出力のパースに失敗しました\nffprobeの出力:\n${
ffprobe.stdout
}\nエラー内容:\n${encodeJson(
}\nエラー内容:\n${encodeError(
e,
)}\ndialog / selectMovie / failed to parse ffprobe output`,
};
}
if (!metadata.streams || !Array.isArray(metadata.streams)) {
logger.error("movie source not found", "metadata:", metadata);
return {
type: "message",
title: "動画ファイルの解析に失敗しました",
Expand All @@ -101,6 +113,7 @@ const selectMovie = async (): Promise<
}
}
if (!(height && width && duration)) {
logger.error("failed to get resolution or duration", "metadata:", metadata);
return {
type: "message",
title: "動画ファイルの解析に失敗しました",
Expand Down Expand Up @@ -138,6 +151,7 @@ const selectComment = async (): Promise<
store.set("commentFileExt", ext);
const format = identifyCommentFormat(filePath);
if (!format) {
console.error("failed to identify comment format", "filePath:", filePath);
sendMessageToController({
type: "message",
title: "非対応のフォーマットです",
Expand Down
4 changes: 3 additions & 1 deletion electron/electron.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { app, BrowserWindow, globalShortcut } from "electron";

import { onStartUp } from "./assets";
import { createControllerWindow } from "./controller-window";
import { onStartUp } from "./ffmpeg";
import { registerListener } from "./ipc-manager";
import { initLogger } from "./lib/log";

app.on("window-all-closed", () => {
app.quit();
Expand Down Expand Up @@ -32,4 +33,5 @@ if (app.isPackaged) {
globalShortcut.unregister("F5");
});
}
initLogger();
registerListener();
51 changes: 23 additions & 28 deletions electron/ffmpeg-stream/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ import type { Readable, Writable } from "stream";
import { PassThrough } from "stream";
import { promisify } from "util";

import { sendMessageToController } from "../controller-window";
import { ffmpegPath } from "../ffmpeg";
import { encodeJson } from "../lib/json";
import { ffmpegPath } from "../assets";
import { getLogger } from "../lib/log";

const logger = getLogger("[ffmpeg-stream]");

const dbg = console.log;
const { FFMPEG_PATH = ffmpegPath } = process.env;
const EXIT_CODES = [0, 255];

function debugStream(stream: Readable | Writable, name: string): void {
stream.on("error", (err) => {
dbg(`${name} error: ${err.message}`);
logger.debug(`${name} error: ${err.message}`);
});
stream.on("data", (data: string | Buffer) => {
dbg(`${name} data: ${data.length} bytes`);
logger.debug(`${name} data: ${data.length} bytes`);
});
stream.on("finish", () => {
dbg(`${name} finish`);
logger.debug(`${name} finish`);
});
}

Expand Down Expand Up @@ -190,11 +190,11 @@ export class Converter {
const writer = createWriteStream(file);
stream.pipe(writer);
stream.on("end", () => {
dbg("input buffered stream end");
logger.debug("input buffered stream end");
resolve();
});
stream.on("error", (err) => {
dbg(`input buffered stream error: ${err.message}`);
logger.error(`input buffered stream error`, err);
return reject(err);
});
});
Expand All @@ -218,11 +218,11 @@ export class Converter {
const reader = createReadStream(file);
reader.pipe(stream);
reader.on("end", () => {
dbg("output buffered stream end");
logger.debug("output buffered stream end");
resolve();
});
reader.on("error", (err: Error) => {
dbg(`output buffered stream error: ${err.message}`);
logger.error(`output buffered stream error`, err);
reject(err);
});
});
Expand All @@ -236,15 +236,15 @@ export class Converter {
const pipes: Pipe[] = [];
try {
for (const pipe of this.pipes) {
dbg(`prepare ${pipe.type}`);
logger.debug(`prepare ${pipe.type}`);
await pipe.onBegin?.();
pipes.push(pipe);
}

const command = ["-y", "-v", "verbose", ...this.getSpawnArgs()];
const stdio = this.getStdioArg();
dbg(`spawn: ${FFMPEG_PATH} ${command.join(" ")}`);
dbg(`spawn stdio: ${stdio.join(" ")}`);
logger.log(`spawn: ${FFMPEG_PATH} ${command.join(" ")}`);
logger.log(`spawn stdio: ${stdio.join(" ")}`);
this.process = spawn(FFMPEG_PATH, command, { stdio });
const finished = this.handleProcess();

Expand All @@ -258,16 +258,15 @@ export class Converter {
}

await finished;
for (const pipe of pipes) {
await pipe.onFinish?.();
}
} catch (e) {
sendMessageToController({
type: "message",
title: "変換中にエラーが発生しました",
message: `エラー内容:\n${encodeJson(e)}`,
});
} finally {
for (const pipe of pipes) {
await pipe.onFinish?.();
}
logger.error(e);
throw e;
}
}

Expand Down Expand Up @@ -315,7 +314,6 @@ export class Converter {
private async handleProcess(): Promise<void> {
await new Promise<void>((resolve, reject): void => {
let logSectionNum = 0;
const logLines: string[] = [];

if (this.process == null) return reject(Error(`Converter not started`));

Expand All @@ -331,27 +329,24 @@ export class Converter {
if (/^\s/u.exec(line) == null) logSectionNum++;
// only log sections following the first one
if (logSectionNum > 1) {
dbg(`log: ${line}`);
logLines.push(line);
logger.log("[ffmpeg]", line);
}
}
});
}

this.process.on("error", (err) => {
dbg(`error: ${err.message}`);
logger.error("[ffmpeg]", err);
return reject(err);
});

this.process.on("exit", (code, signal) => {
dbg(`exit: code=${code ?? "unknown"} sig=${signal ?? "unknown"}`);
console.log(
logger.log(
`exit: code=${code ?? "unknown"} sig=${signal ?? "unknown"}`,
);
if (code == null) return resolve();
if (EXIT_CODES.includes(code)) return resolve();
const log = logLines.map((line) => ` ${line}`).join("\n");
reject(Error(`Converting failed\n${log}`));
reject(Error(`Converting failed`));
});
});
}
Expand Down
17 changes: 14 additions & 3 deletions electron/ipc-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { ipcMain } from "electron";
import { sendMessageToController } from "./controller-window";
import { selectComment, selectFile, selectMovie, selectOutput } from "./dialog";
import { getAvailableProfiles } from "./lib/cookie";
import { encodeJson } from "./lib/json";
import { encodeError, encodeJson } from "./lib/json";
import { getLogger } from "./lib/log";
import { getMetadata } from "./lib/niconico";
import {
appendFrame,
Expand All @@ -16,10 +17,12 @@ import {
import { store } from "./store";
import { typeGuard } from "./type-guard";

const logger = getLogger("[ipcManager]");

const registerListener = (): void => {
ipcMain.handle("request", async (_, args) => {
const value = (args as { data: unknown[] }).data[0];
try {
const value = (args as { data: unknown[] }).data[0];
if (typeGuard.renderer.blob(value)) {
appendFrame(value.frameId, value.data);
} else if (typeGuard.renderer.end(value)) {
Expand Down Expand Up @@ -54,6 +57,7 @@ const registerListener = (): void => {
} else if (typeGuard.renderer.message(value)) {
sendMessageToController(value);
} else {
logger.error("unknown ipc message", "ipcMessage:", value);
sendMessageToController({
type: "message",
title: "未知のエラーが発生しました",
Expand All @@ -63,12 +67,19 @@ const registerListener = (): void => {
});
}
} catch (e: unknown) {
logger.error(
"failed to process ipc message",
"ipcMessage:",
value,
"error:",
e,
);
sendMessageToController({
type: "message",
title: "予期しないエラーが発生しました",
message: `IPCメッセージ:\n${encodeJson(
args,
)}\nエラー内容:\n${encodeJson(e)}\nipcManager / catchError`,
)}\nエラー内容:\n${encodeError(e)}\nipcManager / catchError`,
});
}
});
Expand Down
7 changes: 6 additions & 1 deletion electron/lib/json.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
const encodeJson = (input: unknown): string => {
return JSON.stringify(input, null, "\t");
};
export { encodeJson };

const encodeError = (input: unknown): string => {
return JSON.stringify(input, Object.getOwnPropertyNames(input), "\t");
};

export { encodeError, encodeJson };
Loading

0 comments on commit 5db1eb6

Please sign in to comment.