* escape space in command line

* disable record button when no reference

* notify when transcription working too long

* fix release CI

* fix UI & remove deprecated codes

* clear zombie transcribe process when started

* fix remove file when added a duplicated audio/video

* update latest whisper for win32
This commit is contained in:
an-lee
2024-01-18 18:21:55 +08:00
committed by GitHub
parent 8f4503db37
commit f04dd1e3c8
20 changed files with 120 additions and 349 deletions

View File

@@ -80,12 +80,24 @@ class AudiosHandler {
});
}
audio.transcribe().catch((err) => {
const timeout = setTimeout(() => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
type: "warning",
message: t("stillTranscribing"),
});
}, 1000 * 10);
audio
.transcribe()
.catch((err) => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
});
})
.finally(() => {
clearTimeout(timeout);
});
});
}
private async create(

View File

@@ -1,6 +1,7 @@
import { ipcMain, IpcMainEvent } from "electron";
import { Transcription, Audio, Video } from "@main/db/models";
import { WhereOptions, Attributes } from "sequelize";
import { t } from "i18next";
import log from "electron-log/main";
const logger = log.scope("db/handlers/transcriptions-handler");
@@ -30,12 +31,24 @@ class TranscriptionsHandler {
});
if (transcription.state === "pending") {
transcription.process().catch((err) => {
const timeout = setTimeout(() => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
type: "warning",
message: t("stillTranscribing"),
});
}, 1000 * 10);
transcription
.process()
.catch((err) => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
});
})
.finally(() => {
clearTimeout(timeout);
});
});
}
return transcription.toJSON();
@@ -86,7 +99,24 @@ class TranscriptionsHandler {
throw new Error("models.transcription.notFound");
}
transcription.process({ force: true });
const timeout = setTimeout(() => {
event.sender.send("on-notification", {
type: "warning",
message: t("stillTranscribing"),
});
}, 1000 * 10);
transcription
.process({ force: true })
.catch((err) => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
});
})
.finally(() => {
clearTimeout(timeout);
});
})
.catch((err) => {
logger.error(err);

View File

@@ -80,12 +80,24 @@ class VideosHandler {
});
}
video.transcribe().catch((err) => {
const timeout = setTimeout(() => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
type: "warning",
message: t("stillTranscribing"),
});
}, 1000 * 10);
video
.transcribe()
.catch((err) => {
event.sender.send("on-notification", {
type: "error",
message: err.message,
});
})
.finally(() => {
clearTimeout(timeout);
});
});
}
private async create(

View File

@@ -65,19 +65,20 @@ db.connect = async () => {
await sequelize.sync();
await sequelize.authenticate();
// TODO:
// clear the large waveform data in DB.
// Remove this in next release
const caches = await CacheObject.findAll({
attributes: ["id", "key"],
// kill the zombie transcribe processes
Transcription.findAll({
where: {
state: "processing",
},
}).then((transcriptions) => {
transcriptions.forEach((transcription) => {
if (transcription.result) {
transcription.update({ state: "finished" });
} else {
transcription.update({ state: "pending" });
}
});
});
const cacheIds: string[] = [];
caches.forEach((cache) => {
if (cache.key.startsWith("waveform")) {
cacheIds.push(cache.id);
}
});
await CacheObject.destroy({ where: { id: cacheIds } });
// vacuum the database
await sequelize.query("VACUUM");

View File

@@ -257,6 +257,16 @@ export class Audio extends Model<Audio> {
const md5 = await hashFile(filePath, { algo: "md5" });
// check if file already exists
const existing = await Audio.findOne({
where: {
md5,
},
});
if (existing) {
throw new Error(t("audioAlreadyAddedToLibrary", { file: filePath }));
}
// Generate ID
const userId = settings.getSync("user.id");
const id = uuidv5(`${userId}/${md5}`, uuidv5.URL);

View File

@@ -279,6 +279,16 @@ export class Video extends Model<Video> {
const md5 = await hashFile(filePath, { algo: "md5" });
// check if file already exists
const existing = await Video.findOne({
where: {
md5,
},
});
if (existing) {
throw new Error(t("videoAlreadyAddedToLibrary", { file: filePath }));
}
// Generate ID
const userId = settings.getSync("user.id");
const id = uuidv5(`${userId}/${md5}`, uuidv5.URL);

View File

@@ -73,11 +73,11 @@ class Whipser {
);
const command = [
this.binMain,
`"${this.binMain}"`,
`--file "${waveFile}"`,
`--model ${settings.whisperModelPath()}`,
`--model "${settings.whisperModelPath()}"`,
"--output-json",
`--output-file ${path.join(tmpDir, filename)}`,
`--output-file "${path.join(tmpDir, filename)}"`,
...extra,
].join(" ");