Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🪩 add whisper support #467

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
7 changes: 1 addition & 6 deletions app/ipc/ipc_main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { setMenuBar, showMenuBar, showContextMenu } from '../main_process/menu';
import { sendAll } from '../main_process/windowList';
import { serverInfo } from '../main_process/server';
import { ServerInfo } from '../main_process/types';
import { logLine, logFilePath, LogLevel, LogSource } from '../src/util/log';
import { logFilePath } from '../src/util/log';

ipcMain.handle('open-file', (event, options) => {
const win = BrowserWindow.fromWebContents(event.sender);
Expand Down Expand Up @@ -104,8 +104,3 @@ export function exportDebugLog(window: BrowserWindow): void {
ipcMain.handle('get-home-path', () => {
return app.getPath('home');
});

ipcMain.handle('log-line', (_event, source: LogSource, level: LogLevel, ...args: any[]) => {
assertSome(logLine);
logLine(source, level, ...args.map((x) => JSON.stringify(x)));
});
10 changes: 9 additions & 1 deletion app/main_process/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ export const createWindow = (): void => {
show: false,
});

let dontSendLog = false;
window.webContents.on('console-message', (_e, level, message) => {
if (message == 'server stderr') dontSendLog = true;
logLine && !dontSendLog && logLine(LogSource.RendererProcess, NumericLogLevels[level], message);

if (message == 'console.groupEnd') dontSendLog = false;
});

window.webContents.on('new-window', (event, url, frameName, disposition, options) => {
if (frameName === 'modal') {
event.preventDefault();
Expand Down Expand Up @@ -151,4 +159,4 @@ import './server';
import { windowList } from './windowList';
import { applyMenuBar, setMenuBar } from './menu';
import { isRunningInTest } from '../src/util';
import { initMainProcessLog } from '../src/util/log';
import { LogSource, NumericLogLevels, initMainProcessLog, logLine } from '../src/util/log';
5 changes: 3 additions & 2 deletions app/main_process/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { app, dialog } from 'electron';
import { publishServerInfo, publishServerStderr } from '../ipc/ipc_main';
import { ServerInfo } from './types';
import { isRunningInTest } from '../src/util';
import { LogLevel, LogSource, logLine } from '../src/util/log';

function findServer() {
const possibilities = [
Expand Down Expand Up @@ -74,7 +75,7 @@ function startServer() {
return;
}
serverProcess.stdout.on('data', (data: Buffer) => {
console.log('server-stdout', data.toString());
logLine && logLine(LogSource.ServerProcess, LogLevel.Log, data);
try {
const parsed_data: ServerStartingMessage | ServerStartedMessage = JSON.parse(data.toString());
if (parsed_data.msg == 'server_starting') {
Expand All @@ -88,7 +89,7 @@ function startServer() {
});

serverProcess.stderr.on('data', (data: Buffer) => {
console.log(`server-stderr: \n${data}`);
logLine && logLine(LogSource.ServerProcess, LogLevel.Error, data);
publishServerStderr(data.toString());
});

Expand Down
25 changes: 6 additions & 19 deletions app/scripts/dev.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
const { createServer, build, createLogger } = require('vite');
const { createServer, build } = require('vite');
const electronPath = require('electron');
const { spawn } = require('child_process');
const mode = (process.env.MODE = process.env.MODE || 'development');
const LOG_LEVEL = 'warn';
const sharedConfig = {
mode,
build: {
watch: {},
},
logLevel: LOG_LEVEL,
logLevel: 'warn',
};

const getWatcher = ({ name, configFile, writeBundle }) => {
Expand All @@ -29,10 +28,6 @@ const setupMainPackageWatcher = (viteDevServer) => {
process.env.VITE_DEV_SERVER_URL = `${protocol}//${host}:${port}${path}`;
}

const logger = createLogger(LOG_LEVEL, {
prefix: '[main]',
});

let spawnProcess = null;

return getWatcher({
Expand All @@ -44,18 +39,10 @@ const setupMainPackageWatcher = (viteDevServer) => {
spawnProcess = null;
}

spawnProcess = spawn(String(electronPath), [
`${dir}/start.cjs.js`,
`--remote-debugging-port=${process.env.DEBUGGER_PORT}`,
]);

spawnProcess.stdout.on(
'data',
(d) => d.toString().trim() && logger.warn(d.toString(), { timestamp: true })
);
spawnProcess.stderr.on(
'data',
(d) => d.toString().trim() && logger.error(d.toString(), { timestamp: true })
spawnProcess = spawn(
String(electronPath),
[`${dir}/start.cjs.js`, `--remote-debugging-port=${process.env.DEBUGGER_PORT}`],
{ stdio: 'inherit' }
);
},
});
Expand Down
4 changes: 1 addition & 3 deletions app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import * as ReactDOM from 'react-dom';
import './index.css';

import App from './components/App';
import { exportDebugLogsToDisk, initRendererLog } from './util/log';
import { exportDebugLogsToDisk } from './util/log';
import { subscribeExportDebugLog } from '../ipc/ipc_renderer';

initRendererLog();

subscribeExportDebugLog((event, mainProcessLogPath) => exportDebugLogsToDisk(mainProcessLogPath));

const anyModule = module as any;
Expand Down
50 changes: 31 additions & 19 deletions app/src/pages/LanguageSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,23 @@ function ModelTable({
isDefault={null}
action={
<Tooltip content={`downloading model ${Math.round(model.progress * 100)}%`}>
<HoverSwitcher
onClick={() => dispatch(cancelDownload(model.task_uuid))}
hoverChild={<IconButton icon={StopIcon} />}
defaultChild={
<Button appearance={'minimal'} padding={0}>
<Circle
style={{ height: majorScale(3) }}
percent={model.progress * 100}
strokeWidth={50}
trailWidth={0}
strokeLinecap={'butt'}
/>
</Button>
}
/>
<Pane>
<HoverSwitcher
onClick={() => dispatch(cancelDownload(model.task_uuid))}
hoverChild={<IconButton icon={StopIcon} />}
defaultChild={
<Button appearance={'minimal'} padding={0}>
<Circle
style={{ height: majorScale(3) }}
percent={model.progress * 100}
strokeWidth={50}
trailWidth={0}
strokeLinecap={'butt'}
/>
</Button>
}
/>
</Pane>
</Tooltip>
}
key={model.model_id}
Expand Down Expand Up @@ -221,19 +223,19 @@ function HoverSwitcher({
hoverChild: JSX.Element;
defaultChild: JSX.Element;
}): JSX.Element {
const [shownChild, setShownChild] = useState(defaultChild);
const [hover, setHover] = useState(false);

return (
<Pane
{...switcherProps}
onMouseLeave={() => {
setShownChild(defaultChild);
setHover(false);
}}
onMouseOver={() => {
setShownChild(hoverChild);
setHover(true);
}}
>
{shownChild}
{hover ? hoverChild : defaultChild}
</Pane>
);
}
Expand Down Expand Up @@ -262,6 +264,16 @@ export function LanguageSettingsPage(): JSX.Element {
<MainMaxWidthContainer>
<BackButton id={'back' /* for tour */} />

<Heading marginTop={majorScale(3)} marginBottom={majorScale(2)} paddingLeft={majorScale(1)}>
Whisper Models for {language.lang}
</Heading>
<ModelTable
models={language.whisper_models}
lang={language.lang}
type={'whisper'}
id={'whisper_table'}
/>

<Heading marginTop={majorScale(3)} marginBottom={majorScale(2)} paddingLeft={majorScale(1)}>
Transcription Models for {language.lang}
</Heading>
Expand Down
6 changes: 6 additions & 0 deletions app/src/pages/ModelManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function ModelManagerPage(): JSX.Element {
<Table.Head padding={0}>
<Table.TextHeaderCell {...firstColumnProps}>Language</Table.TextHeaderCell>
<Table.TextHeaderCell>Transcription Models</Table.TextHeaderCell>
<Table.TextHeaderCell>Whisper Models</Table.TextHeaderCell>
<Table.TextHeaderCell {...lastColumnProps} />
</Table.Head>

Expand All @@ -61,6 +62,11 @@ export function ModelManagerPage(): JSX.Element {
lang={lang.lang}
downloaded={downloaded}
/>
<ModelNumberTextCell
models={lang.whisper_models}
lang={lang.lang}
downloaded={downloaded}
/>
<Table.Cell {...lastColumnProps}>
<Tooltip content={'manage language'}>
<Icon color={theme.colors.default} icon={ChevronRightIcon} />
Expand Down
1 change: 1 addition & 0 deletions app/src/state/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Model {
export interface Language {
lang: string;
transcription_models: Model[];
whisper_models: Model[];
}

export type DownloadingModel = Model & {
Expand Down
81 changes: 39 additions & 42 deletions app/src/util/log.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
import fs, { createWriteStream } from 'fs';
import path from 'path';
import JSZip from 'jszip';
import { getHomePath, saveFile, sendLogLine } from '../../ipc/ipc_renderer';
import { getHomePath, saveFile } from '../../ipc/ipc_renderer';
import { isRunningInTest } from './index';
import glob from 'glob';
import { app } from 'electron';

export enum LogLevel {
Log,
Trace,
Debug,
Info,
Warn,
Error,
GroupCollapsed,
GroupEnd,
}

export const NumericLogLevels = [LogLevel.Log, LogLevel.Info, LogLevel.Warn, LogLevel.Error];

export enum LogSource {
MainProcess,
RendererProcess,
ServerProcess,
}

export let logFilePath: string | null = null;
let oldLog: ((...args: any[]) => void) | null = null;

const buffer: string[] = [];
function write(str: string) {
buffer.push(str);

const try_fn = () => {
if (process.stdout.writableLength == 0) {
process.stdout.write(buffer.shift() || '');
} else {
setTimeout(try_fn, 10);
}
};
try_fn();
}

function log(file: number, source: LogSource, level: LogLevel, ...args: any[]) {
const date = new Date().toISOString();
Expand All @@ -36,7 +48,23 @@ function log(file: number, source: LogSource, level: LogLevel, ...args: any[]) {
level: level_str,
args: string_args,
});
if (oldLog !== null) oldLog(log_line);

const FgGreen = '\x1b[32m';
const FgBlue = '\x1b[34m';
const FgYellow = '\x1b[33m';
const Reset = '\x1b[0m';
const source_color = [FgGreen, FgBlue, FgYellow][source];

write(
args
.join('\n')
.split('\n')
.map(
(line) =>
`${source_color}[${source_str.substring(0, 4)}]${Reset} ${level_str.padEnd(5)} | ${line}`
)
.join('\n') + '\n'
);
fs.writeSync(file, log_line + '\n');
fs.fsyncSync(file);
}
Expand Down Expand Up @@ -64,24 +92,15 @@ export function initMainProcessLog(): void {
logFilePath = path.join(log_dir, fileName);
const file = fs.openSync(logFilePath, 'w');
console.log('Init logging into', logFilePath);
oldLog = console.log;
console.log = (...args) => log(file, LogSource.MainProcess, LogLevel.Log, ...args);
console.trace = (...args) => log(file, LogSource.MainProcess, LogLevel.Trace, ...args);
console.debug = (...args) => log(file, LogSource.MainProcess, LogLevel.Debug, ...args);
console.trace = (...args) => log(file, LogSource.MainProcess, LogLevel.Log, ...args);
console.debug = (...args) => log(file, LogSource.MainProcess, LogLevel.Log, ...args);
console.info = (...args) => log(file, LogSource.MainProcess, LogLevel.Info, ...args);
console.warn = (...args) => log(file, LogSource.MainProcess, LogLevel.Warn, ...args);
console.error = (...args) => log(file, LogSource.MainProcess, LogLevel.Error, ...args);
logLine = (...args) => log(file, ...args);
const oldGroupCollapsed = console.groupCollapsed;
console.groupCollapsed = (...args) => {
log(file, LogSource.MainProcess, LogLevel.GroupCollapsed, ...args);
oldGroupCollapsed(...args);
};
const oldGroupEnd = console.groupEnd;
console.groupEnd = (...args) => {
log(file, LogSource.MainProcess, LogLevel.GroupEnd, ...args);
oldGroupEnd(...args);
};
console.groupCollapsed = () => {};
console.groupEnd = () => {};
}

export async function exportDebugLogsToDisk(file: string): Promise<void> {
Expand All @@ -108,25 +127,3 @@ export async function exportDebugLogsToDisk(file: string): Promise<void> {
.on('error', reject);
});
}

type KeyOfType<T, V> = keyof {
[P in keyof T as T[P] extends V ? P : never]: any;
};

function _mapLogFn(key: KeyOfType<typeof console, (...args: any[]) => void>, level: LogLevel) {
const _oldFn: (...args: any[]) => void = console[key];
console[key] = (...args: any[]) => {
_oldFn(...args);
sendLogLine(level, ...args);
};
}
export function initRendererLog(): void {
_mapLogFn('log', LogLevel.Log);
_mapLogFn('trace', LogLevel.Trace);
_mapLogFn('debug', LogLevel.Debug);
_mapLogFn('info', LogLevel.Info);
_mapLogFn('warn', LogLevel.Warn);
_mapLogFn('error', LogLevel.Error);
_mapLogFn('groupCollapsed', LogLevel.GroupCollapsed);
_mapLogFn('groupEnd', LogLevel.GroupEnd);
}
Loading