Skip to content

Commit

Permalink
[wip] refactor: replace from dataurl to uint8array
Browse files Browse the repository at this point in the history
  • Loading branch information
xpadev-net committed Oct 18, 2023
1 parent 181d87a commit 5e1b297
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 38 deletions.
8 changes: 4 additions & 4 deletions electron/ipcManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getAvailableProfiles } from "./lib/cookie";
import { encodeJson } from "./lib/json";
import { getMetadata } from "./lib/niconico";
import {
appendBuffers,
appendFrame,
appendQueue,
markAsCompleted,
processOnLoad,
Expand All @@ -18,10 +18,10 @@ const registerListener = (): void => {
ipcMain.handle("request", async (IpcMainEvent, args) => {
try {
const value = (args as { data: unknown[] }).data[0];
if (typeGuard.renderer.buffer(value)) {
appendBuffers(value.data);
if (typeGuard.renderer.blob(value)) {
appendFrame(value.frameId, value.data);
} else if (typeGuard.renderer.end(value)) {
markAsCompleted();
markAsCompleted(value.frameId);
} else if (typeGuard.controller.selectComment(value)) {
return await selectComment();
} else if (typeGuard.controller.selectMovie(value)) {
Expand Down
68 changes: 42 additions & 26 deletions electron/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { inputStream, startConverter } from "./converter";
import { encodeJson } from "./lib/json";
import { download, downloadComment } from "./lib/niconico";
import { createRendererWindow, sendMessageToRenderer } from "./rendererWindow";
import { base64ToUint8Array } from "./utils";

const queueList: Queue[] = [];
const queueLists: QueueLists = {
Expand All @@ -19,6 +18,9 @@ const queueLists: QueueLists = {
};
let convertQueue = Promise.resolve();
let processingQueue: ConvertQueue;
let lastFrame = 0;
let endFrame = -1;
const frameQueue: { [key: number]: Uint8Array } = {};
const appendQueue = (queue: Queue): void => {
queueList.push(queue);
if (queue.type === "convert") {
Expand Down Expand Up @@ -126,6 +128,7 @@ const startConvert = async (): Promise<void> => {
processingQueue = queued[0];
processingQueue.status = "processing";
processingQueue.progress = 0;
lastFrame = 0;
createRendererWindow();
sendProgress();
await startConverter(queued[0]);
Expand All @@ -136,32 +139,45 @@ const startConvert = async (): Promise<void> => {
sendProgress();
void startConvert();
};
const appendBuffers = (blobs: string[]): void => {
for (const item of blobs) {
const base64Image = item.split(";base64,").pop();
if (!base64Image) continue;
convertQueue = convertQueue.then(() =>
new Promise<void>((fulfill, reject) => {
const myStream = new Stream.Readable();
myStream._read = () => {
const u8 = base64ToUint8Array(base64Image);
myStream.push(u8);
myStream.push(null);
};
processingQueue.progress++;
sendProgress();
return myStream
.on("end", () => fulfill())
.on("error", () => reject())
.pipe(inputStream, { end: false });
}).catch((e) => {
console.warn(e);
}),
);

const appendFrame = (frameId: number, data: Uint8Array): void => {
frameQueue[frameId] = data;
console.log("receive: ", frameId, lastFrame, endFrame);
if (frameId !== lastFrame + 1) {
return;
}
while (frameQueue[lastFrame + 1]) {
lastFrame++;
console.log("process: ", frameId, lastFrame, endFrame);
processFrame(frameQueue[lastFrame]);
delete frameQueue[lastFrame];
}
if (lastFrame === endFrame) {
void convertQueue.then(() => inputStream.end());
}
};

const processFrame = (data: Uint8Array): void => {
convertQueue = convertQueue.then(() =>
new Promise<void>((fulfill, reject) => {
const myStream = new Stream.Readable();
myStream._read = () => {
myStream.push(data);
myStream.push(null);
};
processingQueue.progress++;
sendProgress();
return myStream
.on("end", () => fulfill())
.on("error", () => reject())
.pipe(inputStream, { end: false });
}).catch((e) => {
console.warn(e);
}),
);
};
const markAsCompleted = (): void => {
void convertQueue.then(() => inputStream.end());
const markAsCompleted = (frameId: number): void => {
endFrame = frameId;
};
const sendProgress = (): void => {
sendMessageToController({
Expand All @@ -186,7 +202,7 @@ const processOnLoad = (): ApiResponseLoad => {
};

export {
appendBuffers,
appendFrame,
appendQueue,
markAsCompleted,
processingQueue,
Expand Down
5 changes: 5 additions & 0 deletions electron/typeGuard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type {
ApiRequestLoad,
} from "@/@types/request.renderer";
import type { ApiRequestMessage } from "@/@types/request.renderer";
import type { ApiRequestBlob } from "@/@types/request.renderer";

const typeGuard = {
controller: {
Expand Down Expand Up @@ -85,6 +86,10 @@ const typeGuard = {
typeof i === "object" &&
(i as ApiRequestFromRenderer).host === "renderer" &&
(i as ApiRequestBuffer).type === "buffer",
blob: (i: unknown): i is ApiRequestBlob =>
typeof i === "object" &&
(i as ApiRequestFromRenderer).host === "renderer" &&
(i as ApiRequestBlob).type === "blob",
end: (i: unknown): i is ApiRequestEnd =>
typeof i === "object" &&
(i as ApiRequestFromRenderer).host === "renderer" &&
Expand Down
9 changes: 8 additions & 1 deletion src/@types/request.renderer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ export type ApiRequestBuffer = {
type: "buffer";
data: string[];
};
export type ApiRequestBlob = {
type: "blob";
frameId: number;
data: Uint8Array;
};
export type ApiRequestEnd = {
type: "end";
frameId: number;
};
export type ApiRequestLoad = {
type: "load";
Expand All @@ -22,4 +28,5 @@ export type ApiRequestsFromRenderer =
| ApiRequestBuffer
| ApiRequestEnd
| ApiRequestLoad
| ApiRequestMessage;
| ApiRequestMessage
| ApiRequestBlob;
32 changes: 25 additions & 7 deletions src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,16 @@ const startRenderer = async (): Promise<void> => {
let inProgress = false;
let convertedFrames = 0;

const sendBuffer = (buffer: string[]): void => {
void window.api.request({ type: "buffer", host: "renderer", data: buffer });
const sendBlob = (frameId: number, blob: Blob): void => {
console.log("sendblob", frameId);
void blob.arrayBuffer().then((buffer) => {
void window.api.request({
type: "blob",
host: "renderer",
frameId: frameId + 1,
data: new Uint8Array(buffer),
});
});
};

const { commentData, queue } = (await window.api.request({
Expand All @@ -71,7 +79,9 @@ const startRenderer = async (): Promise<void> => {
...queue.option.options,
format,
});
const emptyBuffer = canvas.toDataURL("image/png");
const emptyBuffer: Blob | null = await new Promise((resolve) =>
canvas.toBlob((blob) => resolve(blob)),
);
message.innerText = "";
let generatedFrames = 0,
offset = Math.ceil((queue.option.ss || 0) * 100);
Expand All @@ -83,16 +93,24 @@ const startRenderer = async (): Promise<void> => {
const process = async (): Promise<void> => {
for (let i = 0; i < targetFrameRate; i++) {
const vpos = Math.ceil(i * (100 / targetFrameRate)) + offset;
const frame = generatedFrames;
// eslint-disable-next-line
if ((nico["timeline"][vpos]?.length || 0) === 0) {
sendBuffer([emptyBuffer]);
if ((nico["timeline"][vpos]?.length || 0) === 0 && emptyBuffer) {
sendBlob(frame, emptyBuffer);
} else {
nico.drawCanvas(vpos);
sendBuffer([canvas.toDataURL("image/png")]);
canvas.toBlob((blob) => {
if (!blob) return;
sendBlob(frame, blob);
});
}
generatedFrames++;
if (generatedFrames >= totalFrames) {
await window.api.request({ type: "end", host: "renderer" });
await window.api.request({
type: "end",
host: "renderer",
frameId: generatedFrames,
});
inProgress = false;
message.innerText = "変換の終了を待っています...";
return;
Expand Down

0 comments on commit 5e1b297

Please sign in to comment.