Compare commits

...

19 Commits

Author SHA1 Message Date
Azeufack Noupeu Willy 7e4cf93cae Merge branch 'feature/s4-07-parakeet' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/s4-07-parakeet 2026-01-08 15:26:59 +01:00
Azeufack Noupeu Willy fe86fa1a2f Implemented local Parakeet transcription module (S4-07) 2026-01-08 15:09:59 +01:00
Azeufack Noupeu Willy 1e4bde93b1 Merge branch 'develop' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into develop 2026-01-08 13:46:41 +01:00
Hughes, Mike c62ee5aa41 Merge branch 'fix/remove-misleading-env-file' into 'develop'
env example is in UTF 16 which, when copied and used as the .env, is...

See merge request proj-wise2526-video2document/video2document!79
2026-01-07 21:15:29 +01:00
MikeHughes-BIN 9c156a7df3 env example is in UTF 16 which, when copied and used as the .env, is unreadable and breaks the Programm 2025-12-23 13:48:27 +01:00
Hughes, Mike 797898fb8b Merge branch 'develop' into 'main'
Develop

See merge request proj-wise2526-video2document/video2document!78
2025-12-22 14:27:25 +01:00
Minning, Eric f81c9bc4e8 Merge branch 'fix/add-error-logging-main' into 'develop'
Add error logging to file submission process

See merge request proj-wise2526-video2document/video2document!77
2025-12-22 14:25:29 +01:00
Minning, Eric 7b630646cc Merge branch 'develop' into 'main'
Develop

See merge request proj-wise2526-video2document/video2document!76
2025-12-22 14:25:10 +01:00
MikeHughes-BIN b57972bf1b Add error logging to file submission process 2025-12-22 14:21:50 +01:00
Hughes, Mike a96a3bebd1 Merge branch 'fix/export_function_windows' into 'develop'
Fix/export function windows

See merge request proj-wise2526-video2document/video2document!75
2025-12-22 14:06:44 +01:00
MikeHughes-BIN 8c0130337e Fix for windows power shell command 2025-12-19 15:31:08 +01:00
Hughes, Mike 4a7aeec869 Merge branch 'develop' into 'main'
Add start scripts for Windows and Unix environments that checks if node is...

See merge request proj-wise2526-video2document/video2document!74
2025-12-19 09:48:39 +01:00
Hughes, Mike 4f3b03f881 Merge branch 'feature/starting-scripts' into 'develop'
Add start scripts for Windows and Unix environments that checks if node is...

See merge request proj-wise2526-video2document/video2document!73
2025-12-19 09:47:31 +01:00
Hughes, Mike 26ed7e3c58 Merge branch 'develop' into 'main'
Fixed the change speaker feature. every step till the point where its send to...

See merge request proj-wise2526-video2document/video2document!72
2025-12-17 16:58:15 +01:00
Hughes, Mike 853eb1a5eb Merge branch 'develop' into 'main'
New Stable Version 2.0

See merge request proj-wise2526-video2document/video2document!68
2025-12-16 19:20:19 +01:00
Azeufack Noupeu Willy ee31d26116 Implemented local Parakeet transcription module (S4-07) 2025-12-11 14:52:48 +01:00
Azeufack Noupeu Willy a13fea6734 Merge branch 'develop' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into develop 2025-12-06 14:51:45 +01:00
Azeufack Noupeu Willy e82cf779da Merge branch 'main' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into develop 2025-12-06 14:48:31 +01:00
Hughes, Mike 283b4ed6af Merge branch 'develop' into 'main'
Implemented the general modular framework.

See merge request proj-wise2526-video2document/video2document!22
2025-11-15 15:14:24 +01:00
6 changed files with 152 additions and 19 deletions
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+5
View File
@@ -160,6 +160,7 @@ electron.ipcMain.on("file_submit", async (event, args) => {
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
}).catch(err => { }).catch(err => {
mainWindow.webContents.send("error", err) mainWindow.webContents.send("error", err)
console.log(err);
return return
}) })
@@ -174,6 +175,7 @@ electron.ipcMain.on("file_submit", async (event, args) => {
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
}).catch(err => { }).catch(err => {
mainWindow.webContents.send("error", err) mainWindow.webContents.send("error", err)
console.log(err);
return return
}) })
@@ -188,6 +190,7 @@ electron.ipcMain.on("file_submit", async (event, args) => {
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
}).catch(err => { }).catch(err => {
mainWindow.webContents.send("error", err) mainWindow.webContents.send("error", err)
console.log(err);
return return
}) })
@@ -204,6 +207,7 @@ electron.ipcMain.on("file_submit", async (event, args) => {
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps}) mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
}).catch(err => { }).catch(err => {
mainWindow.webContents.send("error", err) mainWindow.webContents.send("error", err)
console.log(err);
return return
}) })
@@ -212,6 +216,7 @@ electron.ipcMain.on("file_submit", async (event, args) => {
mainWindow.webContents.send("speakerAudios", resp) mainWindow.webContents.send("speakerAudios", resp)
}).catch(err => { }).catch(err => {
mainWindow.webContents.send("error", err) mainWindow.webContents.send("error", err)
console.log(err);
return return
}) })
} catch (error) { } catch (error) {
+22 -19
View File
@@ -30,25 +30,28 @@ async function showSaveDialog(defaultName, format) {
throw err; throw err;
} }
} else if (platform === 'win32') { } else if (platform === 'win32') {
// Windows const safeName = decodeURIComponent(defaultName);
const powershell = `
Add-Type -AssemblyName System.Windows.Forms const powershell = `
$dialog = New-Object System.Windows.Forms.SaveFileDialog Add-Type -AssemblyName System.Windows.Forms;
$dialog.FileName = "${defaultName}.${format}" $dialog = New-Object System.Windows.Forms.SaveFileDialog;
$dialog.Filter = "${format.toUpperCase()} Dateien (*.${format})|*.${format}|Alle Dateien (*.*)|*.*" $dialog.FileName = '${safeName}.${format}';
$dialog.Title = "Dokument speichern als" $dialog.Filter = '${format.toUpperCase()} Dateien (*.${format})|*.${format}|Alle Dateien (*.*)|*.*';
$result = $dialog.ShowDialog() $dialog.Title = 'Dokument speichern als';
if ($result -eq 'OK') { $dialog.FileName } $result = $dialog.ShowDialog();
`; if ($result -eq 'OK') { $dialog.FileName }
`;
try {
const result = execSync(`powershell -Command "${powershell.replace(/\n/g, '; ')}"`, { try {
encoding: 'utf8' const result = execSync(
}); `powershell -NoProfile -Command "${powershell.replace(/\r?\n/g, ' ')}"`,
return result.trim() || null; { encoding: 'utf8' }
} catch (err) { );
throw err; return result.trim() || null;
} } catch (err) {
if (err.status === 1) return null; // User cancelled
throw new Error("Save dialog failed: " + err.message);
}
} else { } else {
// Linux - zenity oder kdialog // Linux - zenity oder kdialog
try { try {
@@ -0,0 +1,54 @@
// -----------------------------------------------------------
// Parakeet (Step 3A: spawn Python minimal integration)
// -----------------------------------------------------------
const fs = require("fs");
const path = require("path");
const { spawn } = require("child_process");
module.exports = {
name: "parakeet",
type: "transcription",
displayname: "NVIDIA Parakeet",
async function(audioFilePath) {
console.log("🦜 [Parakeet] Starting test integration (spawn only)...");
console.log("🦜 Input audio:", audioFilePath);
// Check audio exists
if (!fs.existsSync(audioFilePath)) {
throw new Error("Audio file does not exist: " + audioFilePath);
}
// Output path in storage/transcripts
const sessionId = path.basename(audioFilePath).replace(/\.[^.]+$/, "");
const outputDir = path.join(__dirname, "../../../storage/transcripts");
fs.mkdirSync(outputDir, { recursive: true });
const outputPath = path.join(outputDir, `${sessionId}.json`);
// -------------------------------------------------------
// SPAWN PYTHON SCRIPT (step 3A — dummy script)
// -------------------------------------------------------
return new Promise((resolve, reject) => {
const python310 = "C:\\Users\\smith\\AppData\\Local\\Programs\\Python\\Python310\\python.exe";
const py = spawn(python310, [
path.join(__dirname, "parakeet_transcribe.py"),
audioFilePath,
outputPath
]);
py.stdout.on("data", data => console.log("🦜 [Python]", data.toString().trim()));
py.stderr.on("data", data => console.error("🦜 [Python ERR]", data.toString().trim()));
py.on("close", code => {
if (code === 0) {
console.log("🦜 [Parakeet] Done (spawn test). Output:", outputPath);
resolve(outputPath);
} else {
reject(new Error("Python script failed with exit code " + code));
}
});
});
}
};
@@ -0,0 +1,71 @@
# -----------------------------------------------------------
# Parakeet Real Transcriber (NVIDIA NeMo + PyTorch GPU)
# -----------------------------------------------------------
import sys
import json
import soundfile as sf
import torch
from nemo.collections.asr.models import ASRModel
# Args:
# sys.argv[1] = input audio path
# sys.argv[2] = output JSON path
audio_path = sys.argv[1]
output_path = sys.argv[2]
print("🔥 Starting Parakeet model...")
device = "cuda" if torch.cuda.is_available() else "cpu"
print("🔥 Using device:", device)
# -----------------------------------------------------------
# Load Parakeet model (NVIDIA pretrained ASR)
# -----------------------------------------------------------
model = ASRModel.from_pretrained(model_name="nvidia/parakeet-ctc-0.6b")
model = model.to(device)
model.eval()
# -----------------------------------------------------------
# Load audio
# -----------------------------------------------------------
print("🎧 Loading audio:", audio_path)
audio, sr = sf.read(audio_path)
# model expects mono float32
if len(audio.shape) > 1:
audio = audio.mean(axis=1)
audio = audio.astype("float32")
# -----------------------------------------------------------
# Run inference
# -----------------------------------------------------------
print("🧠 Running inference...")
with torch.no_grad():
hyp = model.transcribe([audio])[0]
# Extract only the text
if hasattr(hyp, "text"):
transcript = hyp.text
else:
# fallback: convert to string (rare)
transcript = str(hyp)
print("📄 Transcript:", transcript)
# -----------------------------------------------------------
# Save JSON format compatible with V2D pipeline
# -----------------------------------------------------------
result = {
"id": output_path.split("/")[-1].replace(".json", ""),
"tool": "nemo_parakeet",
"status": "completed",
"text": transcript,
"words": [] # Parakeet XS doesnt return word timestamps
}
with open(output_path, "w", encoding="utf-8") as f:
json.dump(result, f, indent=2, ensure_ascii=False)
print("✔ JSON saved at:", output_path)