Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AveRenderer, Grid, Window, getAppContext, IIconResource, IWindowCompone
import { App, ThemePredefined_Dark } from "ave-ui";
import { containerLayout, controlLayout } from "./layout";
import { iconResource } from "./resource";
import { safe } from "./common";
import { safe, sleep } from "./common";
import axios from "axios";
import { ProgressType, Whisper } from "./whisper";
import { useDragDrop } from "./hooks";
Expand All @@ -23,9 +23,10 @@ function initTheme() {
themeDark.SetStyle(themeImage, 0);
}

enum ButtonText {
enum Text {
GenerateSubtitle = "生成字幕",
OpenFile = "选择文件"
OpenFile = "选择文件",
ProgressLabel = "进度",
}

const modelOptions = getModelList().map((each, index) => {
Expand All @@ -47,11 +48,18 @@ export function Heard() {
const [title, setTitle] = useState("Heard");
const [whisperReady, setwhisperReady] = useState(false);
const [src, setSrc] = useState<string>("");
const [srcDesc, setSrcDesc] = useState<string>("");
const [srcList, setSrcList] = useState<Array<string>>([""]);
const promptRef = useRef<string>("");
useDragDrop((path) => setSrc(path));
useDragDrop((pathList) => {
setSrcList(pathList);
setSrcDesc(pathList.length === 1 ? pathList[0] : `${pathList.length} files`);
setProgressLabelText(`${Text.ProgressLabel}: 0/${pathList.length}`);
});

const [progress, setProgress] = useState<ProgressType>(ProgressType.None);
const [progressText, setProgressText] = useState<string>("");
const [progressLabelText, setProgressLabelText] = useState<string>(Text.ProgressLabel);
const [defaultSelectedKey, setDefaultSelectedKey] = useState<string>("1");
const [hintText, setHintText] = useState<string>("初始化中...");

Expand All @@ -64,7 +72,9 @@ export function Heard() {
console.log(`open file: ${filePath}`);

if (filePath) {
setSrc(filePath);
setSrcList([filePath]);
setSrcDesc(filePath);
setProgressLabelText(Text.ProgressLabel);
}
}),
[]
Expand All @@ -75,19 +85,27 @@ export function Heard() {
if (progress !== ProgressType.None) {
return;
}
whisper.transcribe(src, promptRef.current).then(
safe((response) => {

for (let i = 0; i < srcList.length; ++i) {
try {
const src = srcList[i];
setSrc(src);
setProgressLabelText(`${Text.ProgressLabel}: ${i + 1}/${srcList.length}: ${src}`);
const response = await whisper.transcribe(src, promptRef.current);
const data = response.data;
const dirName = path.dirname(src);
const fileName = path.basename(src);
console.log(`save subtitle json`, { dirName, fileName });

const outPath = path.resolve(dirName, `${fileName}.subtitle.json`);
fs.writeFileSync(outPath, JSON.stringify(data, null, 4), "utf8");
})
);
await sleep(1500);
} catch (error) {
console.error(error?.message);
}
}
}),
[src]
[srcList]
);

const startWhisper = safe(() => {
Expand Down Expand Up @@ -174,10 +192,10 @@ export function Heard() {
<Grid style={{ layout: containerLayout }}>
<Grid style={{ area: containerLayout.areas.control, layout: controlLayout }}>
<Grid style={{ area: controlLayout.areas.openFile }}>
<Button text={ButtonText.OpenFile} langKey="OpenFile" iconInfo={{ name: "open-file" }} onClick={onOpenFile}></Button>
<Button text={Text.OpenFile} langKey="OpenFile" iconInfo={{ name: "open-file" }} onClick={onOpenFile}></Button>
</Grid>
<Grid style={{ area: controlLayout.areas.filePath, margin: "12dpx 0 0 0" }}>
<TextBox readonly border={false} text={src}></TextBox>
<TextBox readonly border={false} text={srcDesc}></TextBox>
</Grid>
{whisperReady ? (
<>
Expand All @@ -191,10 +209,10 @@ export function Heard() {
<TextBox ime onChange={onChangePrompt}></TextBox>
</Grid>
<Grid style={{ area: controlLayout.areas.generate, margin: "12dpx 0 0 0" }}>
<Button enable={progress === ProgressType.None} text={ButtonText.GenerateSubtitle} iconInfo={{ name: "cc", size: 16 }} onClick={onTranscribe}></Button>
<Button enable={progress === ProgressType.None} text={Text.GenerateSubtitle} iconInfo={{ name: "cc", size: 16 }} onClick={onTranscribe}></Button>
</Grid>
<Grid style={{ area: controlLayout.areas.progressLabel }}>
<TextBox readonly border={false} text="进度"></TextBox>
<TextBox readonly border={false} text={progressLabelText}></TextBox>
</Grid>
<Grid style={{ area: controlLayout.areas.progress }}>
<TextBox readonly border={false} text={progressText}></TextBox>
Expand Down
31 changes: 18 additions & 13 deletions src/hooks/useDragDrop.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { getAppContext } from "ave-react";
import { useEffect, useState } from "react";
import { DragDropImage, DropBehavior } from "ave-ui";
import { safe } from "../common";

export function useDragDrop(onPathChange?: (path: string) => void) {
const [path, setPath] = useState("");
export function useDragDrop(onPathChange?: (pathList: Array<string>) => void) {
const [pathList, setPathList] = useState([""]);

useEffect(() => {
const context = getAppContext();
const window = context.getWindow();

window.OnDragMove((sender, dc) => {
if (1 === dc.FileGetCount()) {
dc.SetDropTip(DragDropImage.Copy, "打开此文件");
window.OnDragMove(
safe((sender, dc) => {
const fileCount = dc.FileGetCount();
dc.SetDropTip(DragDropImage.Copy, fileCount === 1 ? "选择此文件" : `选择文件x${fileCount}`);
dc.SetDropBehavior(DropBehavior.Copy);
}
});
})
);

window.OnDragDrop((sender, dc) => {
const filePath = dc.FileGet()[0];
setPath(path);
onPathChange?.(filePath ?? "");
});
window.OnDragDrop(
safe((sender, dc) => {
const filePaths = dc.FileGet();
console.log(`on drap drop, file paths:`, { filePaths });
setPathList(filePaths);
onPathChange?.(filePaths ?? [""]);
})
);
}, []);

return { path };
return { pathList };
}
2 changes: 1 addition & 1 deletion src/layout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const controlLayout = {
selectModel: { row: 5, column: 0, columnSpan: 3 },
generate: { row: 5, column: 3, columnSpan: 5 },

progressLabel: { row: 7, column: 0, columnSpan: 4 },
progressLabel: { row: 7, column: 0, columnSpan: 8 },
progress: { row: 9, column: 0, columnSpan: 8 }
},
};
2 changes: 1 addition & 1 deletion src/whisper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class Whisper {
const exePath = path.resolve(dir, "./Whisper-API.exe");
if (fs.existsSync(dir) && fs.existsSync(exePath)) {
return new Promise((resolve, reject) => {
console.log("asrDir exists, start asr server", dir);
console.log("whisper dir exists, start whisper server", dir);

const name = getModel();
console.log("start whisper server with model: ", name);
Expand Down