Compare commits

...

41 Commits

Author SHA1 Message Date
MikeHughes-BIN 56d17de4a5 Refactor speaker management and replace functionality; add IPC for saving speaker mappings and update HTML structure 2026-01-10 15:03:35 +01:00
MikeHughes-BIN 3839feac19 created a new module that takes a html file path and a json path to replace all speakers. Currently only working on command line not integrated 2026-01-08 00:48:00 +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
MikeHughes-BIN 4e4308ae51 Included starting scripts 2025-12-19 09:45:11 +01:00
MikeHughes-BIN 01913590b0 Edited the README 2025-12-19 09:36:49 +01:00
MikeHughes-BIN f750966952 Add start scripts for Windows and Unix environments that checks if node is installed, installs dependencys and starts the programm 2025-12-18 22:55:26 +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 9e05c744aa Merge branch 'feature/ui-test' into 'develop'
Feature/ui test

See merge request proj-wise2526-video2document/video2document!71
2025-12-17 16:51:18 +01:00
Verena Schulz df7ca369de Merge branch 'feature/ui-test' of gitlab.rlp.net:proj-wise2526-video2document/video2document into feature/ui-test 2025-12-17 16:42:11 +01:00
Verena Schulz b6bf178c48 First restructure changes 2025-12-17 16:42:02 +01:00
Hughes, Mike 43749fd073 Merge branch 'feature/ui-test' into 'develop'
Fixed the change speaker feature. every step till the point where its send to...

See merge request proj-wise2526-video2document/video2document!70
2025-12-17 16:15:37 +01:00
Hughes, Mike f616e06a7e Merge branch 'develop' into 'feature/ui-test'
# Conflicts:
#   main.js
2025-12-17 16:14:18 +01:00
eric.minning de43bdd190 Small fix regarding an old line which caused an error 2025-12-17 16:09:06 +01:00
eric.minning b742411dcc Fixed the display and resetting of the audio 2025-12-17 15:55:00 +01:00
eric.minning bbaab9cd21 Merge branch 'feature/ui-test' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/ui-test 2025-12-17 15:29:18 +01:00
eric.minning fc8770e67f Fixed the change speaker feature. every step till the point where its send to the main functions now 2025-12-17 15:29:04 +01:00
Verena Schulz 958c9368d0 Added wrapper in step 2 2025-12-17 15:21:17 +01:00
Verena Schulz 145f91f091 centered custom_document.html 2025-12-17 14:49:32 +01:00
Verena Schulz fa429ec683 Linked Abbrechen button 2025-12-17 14:43:50 +01:00
Verena Schulz 6a8ce0a46d Linked custom_document.html with Custom docment button 2025-12-17 14:39:11 +01:00
Minning, Eric 2778626e4b Merge branch 'develop' into 'feature/ui-test'
Getting the ui-test up to date

See merge request proj-wise2526-video2document/video2document!69
2025-12-17 14:09:01 +01:00
Minning, Eric 0e746749e6 Getting the ui-test up to date 2025-12-17 14:09:00 +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
Hughes, Mike 3cba97a9d1 Merge branch 'fix/rename_document_type' into 'develop'
rename

See merge request proj-wise2526-video2document/video2document!67
2025-12-16 19:13:11 +01:00
MikeHughes-BIN 2900152945 rename 2025-12-16 19:11:11 +01:00
Minning, Eric 262cc2b4d6 Merge branch 'feature/ui-test' into 'develop'
Feature/ui test

See merge request proj-wise2526-video2document/video2document!66
2025-12-16 19:07:47 +01:00
eric.minning 292b893ed2 Merge branch 'feature/ui-test' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/ui-test 2025-12-16 19:01:12 +01:00
eric.minning d9c76e8890 Bug fixes in the speaker selection 2025-12-16 19:01:03 +01:00
Verena Schulz 1016d2ca86 Merge branch 'feature/ui-test' of gitlab.rlp.net:proj-wise2526-video2document/video2document into feature/ui-test 2025-12-16 18:44:27 +01:00
Verena Schulz a014c62ce3 Centered download button better 2025-12-16 18:44:14 +01:00
Spanier, Pit 0a2a8e603f Merge branch 'feature/cleanup-and-tests' into 'develop'
added test for qwen3 model and added a console log for debugging purposes to...

See merge request proj-wise2526-video2document/video2document!65
2025-12-16 18:33:55 +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
18 changed files with 524 additions and 201 deletions
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+44 -81
View File
@@ -1,93 +1,56 @@
# Video2Document # Video2Document
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin https://gitlab.rlp.net/proj-wise2526-video2document/video2document.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](https://gitlab.rlp.net/proj-wise2526-video2document/video2document/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation ## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage Follow the steps below to install Video2Document (v2d):
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support ### 1. Install Node.js
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap Download and install Node.js from [https://nodejs.org/en](https://nodejs.org/en)
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing ### 2. Clone the Repository
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. Clone the repository using Git:
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. ```bash
git clone https://gitlab.rlp.net/proj-wise2526-video2document/video2document.git
```
## Authors and acknowledgment Alternatively, you can download the ZIP file and extract it manually.
Show your appreciation to those who have contributed to the project.
## License ### 3. Start the Program
For open source projects, say how it is licensed.
## Project status The start scripts automatically install dependencies and launch the program. Choose the appropriate method for your operating system:
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
**Windows:**
```bash
start.bat
```
**Linux:**
```bash
./start.sh
```
**macOS:**
```bash
./start.sh
```
#### Alternative: Manual Installation and Start
If the start scripts don't work, you can manually install dependencies and start the program:
```bash
cd video2document
npm install
npm start
```
### 5. Install FFmpeg
Make sure that **ffmpeg** is installed on your system, as it may be required for video processing.
---
**Installation complete!** You're now ready to use Video2Document.
BIN
View File
Binary file not shown.
+161
View File
@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Document</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f0f2f5;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 30px;
margin-top: 50px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
width: 90%;
max-width: 600px;
}
h1 {
text-align: center;
color: #333;
}
label {
font-weight: bold;
margin-top: 15px;
display: block;
color: #555;
}
input[type="text"], textarea, select {
width: 100%;
padding: 10px;
margin-top: 5px;
border-radius: 6px;
border: 1px solid #ccc;
font-size: 14px;
}
textarea {
height: 120px;
resize: vertical;
}
.buttons {
display: flex;
justify-content: space-between;
margin-top: 25px;
}
button {
padding: 10px 20px;
font-size: 14px;
border: none;
border-radius: 6px;
cursor: pointer;
transition: 0.2s;
background-color: #007BFF;
color: white;
}
button:hover {
background-color: #0056b3;
}
@media (max-width: 500px) {
.buttons {
flex-direction: column;
}
.buttons button {
width: 100%;
margin-top: 10px;
}
}
#result {
margin-top: 20px;
color: #333;
word-break: break-word;
}
</style>
</head>
<body>
<div class="container">
<h1>Custom Document Generator</h1>
<label for="docName">Dokumentname:</label>
<input type="text" id="docName" placeholder="Gib hier den Dokumentnamen ein">
<label for="existingDocs">Vorhandene Dokumente auswählen (optional):</label>
<select id="existingDocs">
<option value="">-- Neues Dokument erstellen --</option>
<option value="meeting_report_001">Meeting Report 001</option>
<option value="summary_01">Summary 01</option>
<option value="project_plan_A">Project Plan A</option>
</select>
<label for="prompt">Dein Prompt:</label>
<textarea id="prompt" placeholder="Schreibe hier den Prompt für dein Dokument..."></textarea>
<div class="buttons">
<a href="index.html">
<button id="goBackBtn">Abbrechen</button>
</a>
<button id="generateBtn">Dokument speichern</button>
</div>
<div id="result"></div>
</div>
<script>
const goBackBtn = document.getElementById("goBackBtn");
const generateBtn = document.getElementById("generateBtn");
const existingDocs = document.getElementById("existingDocs");
const docNameInput = document.getElementById("docName");
const promptInput = document.getElementById("prompt");
const resultDiv = document.getElementById("result");
// Zurück zur Haupt-GUI
goBackBtn.addEventListener("click", () => {
window.electronAPI.goBackToMain();
});
// Generiere Dokument
generateBtn.addEventListener("click", () => {
const prompt = promptInput.value.trim();
let docName = docNameInput.value.trim();
const selectedExisting = existingDocs.value;
if (!prompt) {
alert("Bitte gib einen Prompt ein!");
return;
}
// Wenn ein vorhandenes Dokument ausgewählt wurde, hängt der Prompt daran
if (selectedExisting) {
docName = selectedExisting; // prompt wird an vorhandenes Dokument angehängt
} else if (!docName) {
alert("Bitte gib einen Dokumentnamen ein, wenn du ein neues Dokument erstellen möchtest!");
return;
}
// Demo-Ausgabe im Result-Div
resultDiv.innerHTML = `<strong>Dokumentname:</strong> ${docName}<br><strong>Prompt:</strong> ${prompt}`;
// Hier kannst du den Prompt an dein LLM oder Module-Handler senden
// z.B. window.submit.submit({documentName: docName, prompt: prompt})
});
</script>
</body>
</html>
+22 -16
View File
@@ -19,8 +19,8 @@
</label> </label>
<nav class="menu1"> <nav class="menu1">
<a href="index2.html" class="li1">Custom document</a> <a href="custom_document.html" class="li1">Manage document types</a>
<a href="index3.html" class="li1">Help</a> <a href="" class="li1">Help</a>
</nav> </nav>
</nav> </nav>
</section> </section>
@@ -57,26 +57,31 @@
</div> </div>
<div class="step" id="step2" style="display:none;"> <div class="step" id="step2" style="display:none;">
<div class="labelDiv" id="labelDiv"> <div class="KI-wrapper">
<label id="labelKI">Select ki:</label> <label id="labelKI">Select ki:</label>
<label id="labelTranscription">Select transcription:</label> <select name="ai_type" id="ai_type"></select>
<label id="labelType">Select type:</label>
<label id="labelLanguage">Select language:</label>
<img id="labelLanguageFlag" src="flags/united-kingdom-flag-png-large.jpg" width="20" height="10" >
</div> </div>
<div class="dropdownMenus" id="dropdownMenus">
<select name="ai_type" id="ai_type"> <div class="transcript-wrap">
</select> <label id="labelTranscription">Select transcription:</label>
<select name="transkript_type" id="transkript_type"> <select name="transkript_type" id="transkript_type"></select>
</select> </div>
<div class="type-wrapper">
<label id="labelType">Select type:</label>
<select name="output_type" id="output_type"> <select name="output_type" id="output_type">
<option value="pdf">.pdf</option> <option value="pdf">.pdf</option>
<option value="word">.word</option> <option value="word">.word</option>
<option value="txt">.txt</option> <option value="txt">.txt</option>
</select> </select>
</div>
<div class="language-wrapper">
<label id="labelLanguage">Select language:</label>
<img id="labelLanguageFlag" src="flags/united-kingdom-flag-png-large.jpg" width="20" height="10" >
<select name="language_option" id="language_option"> <select name="language_option" id="language_option">
</select> </select>
</div> </div>
</div> </div>
<div class="step" id="step3" style="display:none;"> <div class="step" id="step3" style="display:none;">
@@ -129,7 +134,6 @@
<div class="speakerView" id="speakerView"> <div class="speakerView" id="speakerView">
<label id="labelSpeaker">Select Speaker:</label> <label id="labelSpeaker">Select Speaker:</label>
<select name="cur_speaker" id="cur_speaker"> <select name="cur_speaker" id="cur_speaker">
<options>Stefan</options>
</select> </select>
</div> </div>
<div class="speakerAudio" id="speakerAutio"> <div class="speakerAudio" id="speakerAutio">
@@ -142,8 +146,10 @@
<label id="labelSpeakerWriter">Write name:</label> <label id="labelSpeakerWriter">Write name:</label>
<input type="text" id="newSpeaker"> <input type="text" id="newSpeaker">
</div> </div>
<button id="speakerLocker" onclick="rewriteSpeakerName()">Rename Speaker</button> <div class="speakerButton-group">
<button id="speakerResender" onclick="sendSpeakerPackages()">Rewrite document</button> <button id="speakerLocker" onclick="rewriteSpeakerName()">Rename Speaker</button>
<button id="speakerResender" onclick="sendSpeakerPackages()">Rewrite document</button>
</div>
</div> </div>
<div class="step" id="step6" style="display:none;"> <div class="step" id="step6" style="display:none;">
+20 -16
View File
@@ -3,35 +3,39 @@ const { contextBridge, ipcRenderer, webUtils } = require('electron')
try { try {
contextBridge.exposeInMainWorld("explorer", { contextBridge.exposeInMainWorld("explorer", {
onFileDrop: (file) => webUtils.getPathForFile(file) onFileDrop: (file) => webUtils.getPathForFile(file)
}) });
contextBridge.exposeInMainWorld("submit", { contextBridge.exposeInMainWorld("submit", {
submit: (meeting_specifications) => {ipcRenderer.send("file_submit", meeting_specifications)} submit: (meeting_specifications) => ipcRenderer.send("file_submit", meeting_specifications)
}) });
// ALLE electronAPI Funktionen in EINEM Objekt
contextBridge.exposeInMainWorld("electronAPI", { contextBridge.exposeInMainWorld("electronAPI", {
getFilePath: (file) => {return webUtils.getPathForFile(file)} getFilePath: (file) => webUtils.getPathForFile(file),
}) saveSpeakerMapping: (data) => ipcRenderer.send("save-speaker-mapping", data)
});
contextBridge.exposeInMainWorld("onStartup", { contextBridge.exposeInMainWorld("onStartup", {
getModuleNames: () => ipcRenderer.invoke('get-module-names') getModuleNames: () => ipcRenderer.invoke('get-module-names')
}) });
contextBridge.exposeInMainWorld('electron', { contextBridge.exposeInMainWorld('electron', {
progress: (callback) => ipcRenderer.on('progress', callback) progress: (callback) => ipcRenderer.on('progress', callback)
}) });
contextBridge.exposeInMainWorld('audios', { contextBridge.exposeInMainWorld('audios', {
speakerAudios: (callback) => ipcRenderer.on('speakerAudios', callback) speakerAudios: (callback) => ipcRenderer.on('speakerAudios', callback)
}) });
contextBridge.exposeInMainWorld("submitSpeaker", { contextBridge.exposeInMainWorld("submitSpeaker", {
submitSpeaker: (speaker_names) => {ipcRenderer.send("speaker_submit", speaker_names)} speaker_submit: (speaker_names) => ipcRenderer.send("speaker_submit", speaker_names)
}) });
contextBridge.exposeInMainWorld("download", { contextBridge.exposeInMainWorld("download", {
file_download: () => {ipcRenderer.send("file_download")} file_download: () => ipcRenderer.send("file_download")
}) });
ipcRenderer.on("error", (event, err) => { alert(err) });
ipcRenderer.on("error", (event, err) => {alert(err)})
} catch (error) { } catch (error) {
console.log("Error in preload.js"); console.log("Error in preload.js", error);
} }
+4 -4
View File
@@ -19,7 +19,6 @@ uploadContainer.addEventListener("drop", (e) => {
const testEndings = [".mp4", ".mov", ".avi", ".mkv"]; const testEndings = [".mp4", ".mov", ".avi", ".mkv"];
var pathToLower = filePath.toLowerCase(); var pathToLower = filePath.toLowerCase();
if(testEndings.some(e => pathToLower.endsWith(e))){ if(testEndings.some(e => pathToLower.endsWith(e))){
document.getElementById("progressbar").style.visibility = "visible";
const files1 = e.dataTransfer.files; const files1 = e.dataTransfer.files;
handleFiles(files1); handleFiles(files1);
}else{ }else{
@@ -28,6 +27,7 @@ uploadContainer.addEventListener("drop", (e) => {
} catch (error) { } catch (error) {
console.log("Error in renderer.js with the listerner for the drop function"); console.log("Error in renderer.js with the listerner for the drop function");
console.log(error);
} }
}) })
@@ -169,15 +169,15 @@ docFormatCustom.addEventListener("change", (e) =>{
//Speaker change listener //Speaker change listener
cur_speaker.addEventListener("change", (e) =>{ cur_speaker.addEventListener("change", (e) =>{
try { try {
document.getElementById("speakerAudioViewer").src = valy[e.target.value].source; document.getElementById("speakerAudioViewer").src = speakerAudios[document.getElementById("cur_speaker").value].src;
} catch (error) { } catch (error) {
} }
}); });
window.audios.speakerAudios((event, arg) => { window.audios.speakerAudios((event, arg) => {
setSpeakerAudiosValue(arg); loadSpeakerOptions(arg);
loadSpeakerOptions(arg); setSpeakerAudiosValue(arg);
}); });
window.electron.progress((event, arg) => { window.electron.progress((event, arg) => {
+65 -51
View File
@@ -5,8 +5,8 @@ function checkBoxes() {
const checkboxes = document.querySelectorAll('input[name="docFormat"]'); const checkboxes = document.querySelectorAll('input[name="docFormat"]');
let isChecked = false; let isChecked = false;
var checkedCounter = 0; var checkedCounter = 0;
checkboxes.forEach(function(checkbox){ checkboxes.forEach(function (checkbox) {
if(checkbox.checked){ if (checkbox.checked) {
isChecked = true; isChecked = true;
checkedCounter++; checkedCounter++;
} }
@@ -15,24 +15,24 @@ function checkBoxes() {
if (isChecked) { if (isChecked) {
//Code to submit the video //Code to submit the video
var selectedCheckboxes = {}; var selectedCheckboxes = {};
checkboxes.forEach(function(checkbox){ checkboxes.forEach(function (checkbox) {
if(checkbox.checked){ if (checkbox.checked) {
selectedCheckboxes[checkbox.nextElementSibling.textContent] = ""; selectedCheckboxes[checkbox.nextElementSibling.textContent] = "";
} }
}); });
const testEndings = [".mp4", ".mov", ".avi", ".mkv"]; const testEndings = [".mp4", ".mov", ".avi", ".mkv"];
var pathTest = window.electronAPI.getFilePath(videoUpload.files[0]); var pathTest = window.electronAPI.getFilePath(videoUpload.files[0]);
var pathToLower = pathTest.toLowerCase(); var pathToLower = pathTest.toLowerCase();
if(testEndings.some(e => pathToLower.endsWith(e))){ if (testEndings.some(e => pathToLower.endsWith(e))) {
//assembly of the json for the main //assembly of the json for the main
var typeCheckbox; var typeCheckbox;
if(document.getElementById("docFormat").checked) typeCheckbox = document.getElementById("docFormat").value; if (document.getElementById("docFormat").checked) typeCheckbox = document.getElementById("docFormat").value;
if(document.getElementById("docFormatSummary1").checked) typeCheckbox = document.getElementById("docFormatSummary1").value; if (document.getElementById("docFormatSummary1").checked) typeCheckbox = document.getElementById("docFormatSummary1").value;
if(document.getElementById("docFormatSummary2").checked) typeCheckbox = document.getElementById("docFormatSummary2").value; if (document.getElementById("docFormatSummary2").checked) typeCheckbox = document.getElementById("docFormatSummary2").value;
if(document.getElementById("docFormatSummary3").checked) typeCheckbox = document.getElementById("docFormatSummary3").value; if (document.getElementById("docFormatSummary3").checked) typeCheckbox = document.getElementById("docFormatSummary3").value;
if(document.getElementById("docFormatCustom").checked) typeCheckbox = document.getElementById("docFormatCustom").value; if (document.getElementById("docFormatCustom").checked) typeCheckbox = document.getElementById("docFormatCustom").value;
document.getElementById("testy").style.visibility = "visible" document.getElementById("testy").style.visibility = "visible"
document.getElementById("box1").style.backgroundColor = "red"; document.getElementById("box1").style.backgroundColor = "red";
@@ -45,20 +45,20 @@ function checkBoxes() {
const aiType = document.getElementById("ai_type"); const aiType = document.getElementById("ai_type");
const sendingPackage = { const sendingPackage = {
"video": { "video": {
"module":"extraction-video-to-audio", "module": "extraction-video-to-audio",
"inputVideoPath": pathTest "inputVideoPath": pathTest
}, },
"transcription": { "transcription": {
"module": transcriptionType.value "module": transcriptionType.value
}, },
"document": { "document": {
"module":aiType.value, "module": aiType.value,
"type": typeCheckbox, "type": typeCheckbox,
"outputType": outputType.value "outputType": outputType.value
} }
}; };
window.submit.submit(sendingPackage) window.submit.submit(sendingPackage)
}else{ } else {
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].'); alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
} }
@@ -71,7 +71,7 @@ function checkBoxes() {
console.log("Error in script.js checkBoxes function"); console.log("Error in script.js checkBoxes function");
console.log(error); console.log(error);
} }
} }
//language changing feature //language changing feature
@@ -95,7 +95,7 @@ function changeLanguage(language) {
console.log("Error in script.js changeLanguage function"); console.log("Error in script.js changeLanguage function");
console.log(error); console.log(error);
} }
} }
//function to display the file path in the drop down box //function to display the file path in the drop down box
@@ -129,17 +129,17 @@ function updateProgressBar(bar, value) {
console.log("Error in scripts.js updateProgressBar function"); console.log("Error in scripts.js updateProgressBar function");
console.log(error); console.log(error);
} }
} }
//function to load ai options to the drop down list //function to load ai options to the drop down list
function loadAiOptions(options){ function loadAiOptions(options) {
try { try {
var menu = document.getElementById('ai_type'); var menu = document.getElementById('ai_type');
var object_holdy; var object_holdy;
var choice ; var choice;
object_holdy = options object_holdy = options
for(i = 0; i < options.length; i++){ for (i = 0; i < options.length; i++) {
choice = document.createElement('option'); choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname; choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name; choice.value = object_holdy[i].name;
@@ -152,13 +152,13 @@ function loadAiOptions(options){
} }
//function to load transcription options to the drop down list //function to load transcription options to the drop down list
function loadTranscriptionOptions(options){ function loadTranscriptionOptions(options) {
try { try {
var menu = document.getElementById('transkript_type'); var menu = document.getElementById('transkript_type');
var object_holdy; var object_holdy;
var choice ; var choice;
object_holdy = options object_holdy = options
for(i = 0; i < options.length; i++){ for (i = 0; i < options.length; i++) {
choice = document.createElement('option'); choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname; choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name; choice.value = object_holdy[i].name;
@@ -171,13 +171,13 @@ function loadTranscriptionOptions(options){
} }
//function to load data type options to the drop down list //function to load data type options to the drop down list
function loadDataTypeOptions(options){ function loadDataTypeOptions(options) {
try { try {
var menu = document.getElementById('output_type'); var menu = document.getElementById('output_type');
var object_holdy; var object_holdy;
var choice ; var choice;
object_holdy = options object_holdy = options
for(i = 0; i < options.length; i++){ for (i = 0; i < options.length; i++) {
choice = document.createElement('option'); choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname; choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name; choice.value = object_holdy[i].name;
@@ -190,13 +190,13 @@ function loadDataTypeOptions(options){
} }
//function to load language options to the drop down list //function to load language options to the drop down list
function loadLanguageOptions(){ function loadLanguageOptions() {
try { try {
var menu = document.getElementById('language_option'); var menu = document.getElementById('language_option');
var object_holdy; var object_holdy;
var choice ; var choice;
object_holdy = Object.keys(languageOptions); object_holdy = Object.keys(languageOptions);
for(i = 0; i < object_holdy.length; i++){ for (i = 0; i < object_holdy.length; i++) {
choice = document.createElement('option'); choice = document.createElement('option');
choice.textContent = object_holdy[i]; choice.textContent = object_holdy[i];
choice.value = object_holdy[i]; choice.value = object_holdy[i];
@@ -209,18 +209,23 @@ function loadLanguageOptions(){
} }
//function to load speaker options to the drop down list //function to load speaker options to the drop down list
function loadSpeakerOptions(options){ function loadSpeakerOptions(options) {
try { try {
var menu = document.getElementById('speaker_option'); var menu = document.getElementById('cur_speaker');
var l = document.getElementById('cur_speaker').options.length - 1;
for (i = l; i >= 0; i--) {
menu.remove(i);
}
var object_holdy; var object_holdy;
var choice; var choice;
object_holdy = options.keys(); object_holdy = Object.keys(options);
for(i = 0; i < options.length; i++){ for (i = 0; i < object_holdy.length; i++) {
choice = document.createElement('option'); choice = document.createElement('option');
choice.textContent = options[object_holdy[i]].name; choice.textContent = options[object_holdy[i]].name;
choice.value = options[object_holdy[i]].name; choice.value = object_holdy[i];
menu.appendChild(choice); menu.appendChild(choice);
} }
document.getElementById("speakerAudioViewer").src = options.speakerA.src;
} catch (error) { } catch (error) {
console.log("Error in script.js loadSpeakerOptions function"); console.log("Error in script.js loadSpeakerOptions function");
console.log(error); console.log(error);
@@ -228,7 +233,7 @@ function loadSpeakerOptions(options){
} }
//function to load speaker audio file options to the drop down list //function to load speaker audio file options to the drop down list
function loadSpeakerAudio(option){ function loadSpeakerAudio(option) {
try { try {
var menu = document.getElementById('speakerAudioViewer'); var menu = document.getElementById('speakerAudioViewer');
var aud = document.createElement("source"); var aud = document.createElement("source");
@@ -241,7 +246,7 @@ function loadSpeakerAudio(option){
} }
function activateSubmitBtn(hasFile){ function activateSubmitBtn(hasFile) {
try { try {
document.getElementById("submitButton").disabled = !hasFile; document.getElementById("submitButton").disabled = !hasFile;
} catch (error) { } catch (error) {
@@ -249,7 +254,7 @@ function activateSubmitBtn(hasFile){
} }
} }
function deaktivateProgressbar(){ function deaktivateProgressbar() {
try { try {
document.getElementById("progressbar").style.visibility = "hidden"; document.getElementById("progressbar").style.visibility = "hidden";
} catch (error) { } catch (error) {
@@ -258,7 +263,7 @@ function deaktivateProgressbar(){
} }
//Video thumbnail generation //Video thumbnail generation
function generateThumbnail(path){ function generateThumbnail(path) {
const videoElement = document.getElementById("previewThumbnail"); const videoElement = document.getElementById("previewThumbnail");
while (videoElement.firstChild) videoElement.removeChild(videoElement.firstChild); while (videoElement.firstChild) videoElement.removeChild(videoElement.firstChild);
videoElement.src = path; videoElement.src = path;
@@ -276,18 +281,18 @@ let currentStep = 1;
const totalSteps = steps.length; const totalSteps = steps.length;
function showStep(stepNumber) { function showStep(stepNumber) {
if (stepNumber < 1 || stepNumber > totalSteps){ if (stepNumber < 1 || stepNumber > totalSteps) {
console.error("StepNumber out of Bounds", stepNumber); console.error("StepNumber out of Bounds", stepNumber);
return; return;
} }
steps.forEach(step => step.style.display = "none"); steps.forEach(step => step.style.display = "none");
document.getElementById("step" + stepNumber).style.display = "block"; document.getElementById("step" + stepNumber).style.display = "flex";
stepButtons.forEach(btn => btn.classList.remove("active")); stepButtons.forEach(btn => btn.classList.remove("active"));
document.querySelector(`.step-item[data-step="${stepNumber}"]`).classList.add("active"); document.querySelector(`.step-item[data-step="${stepNumber}"]`).classList.add("active");
const activeBtn = document.querySelector(`.step-item[data-step="${stepNumber}"]`); const activeBtn = document.querySelector(`.step-item[data-step="${stepNumber}"]`);
if(activeBtn) activeBtn.classList.add("active"); if (activeBtn) activeBtn.classList.add("active");
prevBtn.disabled = stepNumber == 1; prevBtn.disabled = stepNumber == 1;
nextBtn.disabled = stepNumber === totalSteps; nextBtn.disabled = stepNumber === totalSteps;
@@ -298,31 +303,40 @@ function showStep(stepNumber) {
//Audio value setter //Audio value setter
var speakerAudios = {}; var speakerAudios = {};
var speakerEndValues = {}; var speakerEndValues = {};
function setSpeakerAudiosValue(valy){ function setSpeakerAudiosValue(valy) {
try { try {
speakerAudios = valy; speakerAudios = valy;
speakerRewriten = valy; speakerRewriten = valy;
document.getElementById("speakerAudioViewer").src = valy.speakerA.src; document.getElementById("speakerAudioViewer").src = valy.speakerA.src;
} catch (error) { } catch (error) {
} }
} }
function rewriteSpeakerName(){ function rewriteSpeakerName() {
try { try {
var tempy = document.getElementById("cur_speaker").textContent; const oldKey = document.getElementById("cur_speaker").value;
speakerAudios[tempy].name = document.getElementById("newSpeaker").textContent; const newName = document.getElementById("newSpeaker").value;
document.getElementById("cur_speaker").textContent = document.getElementById("newSpeaker").textContent;
speakerAudios[oldKey].name = newName;
loadSpeakerOptions(speakerAudios);
// IPC-Aufruf an Electron main process
window.electronAPI.saveSpeakerMapping({
speakerId: oldKey,
speakerName: newName
});
} catch (error) { } catch (error) {
console.log(error);
} }
} }
function sendSpeakerPackages(){ function sendSpeakerPackages() {
try { try {
window.sendSpeakerPackages(speakerAudios); window.submitSpeaker.speaker_submit(speakerAudios);
} catch (error) { } catch (error) {
} }
} }
+40 -8
View File
@@ -17,7 +17,6 @@ body {
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
margin: 0; margin: 0;
z-index: 20; z-index: 20;
} }
#h1-wrapper { #h1-wrapper {
@@ -108,6 +107,14 @@ body {
.submit-btn:hover { .submit-btn:hover {
background-color: #0056b3; background-color: #0056b3;
} }
#step2 {
gap: 30px;
}
.KI-wrapper {
margin-top: 40px;
}
input[type="file"] { input[type="file"] {
display: none; display: none;
@@ -176,12 +183,10 @@ input[type="file"] {
.submit-btn { .submit-btn {
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
justify-content: center;
padding: 10px 20px; padding: 10px 20px;
margin-left: 300px; margin: 130px auto 10px auto;
margin-top: 30px;
margin-bottom: 70px;
background-color: #007BFF; background-color: #007BFF;
color: white; color: white;
border: none; border: none;
@@ -295,7 +300,6 @@ input[type="file"] {
margin-top: 70px; margin-top: 70px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center;
min-height: 400px; min-height: 400px;
} }
@@ -465,12 +469,29 @@ li {
font-size: larger; font-size: larger;
} }
#step4 {
align-items: center;
}
#step5 {
align-items: flex-start;
}
.button-group {
display: flex;
gap: 12px;
justify-content: center;
margin-top: 10px;
}
.download-btn { .download-btn {
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
padding: 10px 20px; padding: 10px 20px;
margin-left: 10px; margin-left: auto;
margin-top: 30px; margin-right: 0px;
margin-top: 130px;
margin-bottom: 10px; margin-bottom: 10px;
background-color: #007BFF; background-color: #007BFF;
color: white; color: white;
@@ -478,4 +499,15 @@ li {
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 14px;
}
#speakerLocker, #speakerResender{
padding: 10px 20px;
margin: 20px auto;
background-color: #007BFF;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
} }
+25 -2
View File
@@ -103,7 +103,23 @@ electron.ipcMain.handle('get-module-names', async () => {
return module_array return module_array
}); });
electron.ipcMain.on("save-speaker-mapping", (event, data) => {
const filePath = "/Users/mikehughes/PROJ/video2document/storage/speakerMapping/speakerMapping.json";
const payload = {
speakerId: data.speakerId,
speakerName: data.speakerName,
updated: new Date().toISOString()
};
try {
fs.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
console.log("Speaker mapping saved!");
} catch (error) {
console.error("Failed to save speaker mapping", error);
}
});
// electron.ipcMain.on("get_modules", async (event, args) => { // electron.ipcMain.on("get_modules", async (event, args) => {
// let module_array = { // let module_array = {
// "ai_modules":[], // "ai_modules":[],
@@ -160,6 +176,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 +191,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 +206,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,15 +223,16 @@ 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
}) })
await mapFunctions.get("extract-speaker-snippets").function({audioPath: audiopath, jsonPath: transcriptpath }).then(resp => { await mapFunctions.get("extract-speaker-snippets").function({audioPath: audiopath, jsonPath: transcriptpath }).then(resp => {
mainWindow.webContents.send("submitSpeaker", resp) mainWindow.webContents.send("speakerAudios", resp)
console.log(resp)
}).catch(err => { }).catch(err => {
mainWindow.webContents.send("error", err) mainWindow.webContents.send("error", err)
console.log(err);
return return
}) })
} catch (error) { } catch (error) {
@@ -224,6 +244,9 @@ electron.ipcMain.on("file_download", async() => {
await mapFunctions.get("htmlDocumentConverter").convert({inputPath:globalFinalHtmlPath, format: globalArgs.document.outputType, showDialog: true}); await mapFunctions.get("htmlDocumentConverter").convert({inputPath:globalFinalHtmlPath, format: globalArgs.document.outputType, showDialog: true});
}) })
electron.ipcMain.on("speaker_submit", async() => {
console.log("\n\n\nJa also hier kam was an \n\n\n");
})
let q = let q =
{ {
+8 -4
View File
@@ -450,6 +450,7 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz",
"integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"undici-types": "~7.16.0" "undici-types": "~7.16.0"
} }
@@ -1305,7 +1306,8 @@
"version": "0.0.1534754", "version": "0.0.1534754",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz",
"integrity": "sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ==", "integrity": "sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ==",
"license": "BSD-3-Clause" "license": "BSD-3-Clause",
"peer": true
}, },
"node_modules/diff": { "node_modules/diff": {
"version": "4.0.2", "version": "4.0.2",
@@ -3488,9 +3490,10 @@
} }
}, },
"node_modules/qs": { "node_modules/qs": {
"version": "6.14.0", "version": "6.14.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
"license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"side-channel": "^1.1.0" "side-channel": "^1.1.0"
}, },
@@ -4204,6 +4207,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
+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,70 @@
const fs = require('fs');
const path = require('path');
const module_exports = {
name: "replace_speaker",
type: "processor",
displayname: "Speaker Name Replacer",
description: "Replaces speaker placeholder names with actual names based on a mapping in HTML files",
async function({ inputHtmlPath, speakerMappingPath }) {
return await this.replaceNames(inputHtmlPath, speakerMappingPath);
},
replaceNames: async function(inputHtmlPath, speakerMappingPath) {
try {
const htmlContent = await fs.promises.readFile(inputHtmlPath, "utf-8");
const mappingData = await fs.promises.readFile(speakerMappingPath, "utf-8");
let speakerMap = {};
try {
const parsed = JSON.parse(mappingData);
if (parsed.speakerId && parsed.speakerName) {
speakerMap[parsed.speakerId] = parsed.speakerName;
} else {
Object.assign(speakerMap, parsed);
}
} catch (e) {
const lines = mappingData.trim().split('\n');
lines.forEach(line => {
const [placeholder, realName] = line.split(',').map(s => s.trim());
if (placeholder && realName) speakerMap[placeholder] = realName;
});
}
let outputContent = htmlContent;
Object.entries(speakerMap).forEach(([placeholder, realName]) => {
const regex = new RegExp(`[\$begin:math:text$\\\\\[\]\?\$\{placeholder\}\[\\$end:math:text$\\]]?`, 'g');
outputContent = outputContent.replace(regex, realName);
});
await fs.promises.writeFile(inputHtmlPath, outputContent, "utf-8");
return inputHtmlPath;
} catch (error) {
console.error("Error replacing speaker names:", error);
throw error;
}
}
};
module.exports = module_exports;
if (require.main === module) {
(async () => {
const args = process.argv.slice(2);
if (args.length < 2) process.exit(1);
const [inputHtmlPath, speakerMappingPath] = args;
if (!fs.existsSync(inputHtmlPath)) process.exit(1);
if (!fs.existsSync(speakerMappingPath)) process.exit(1);
try {
await module_exports.replaceNames(inputHtmlPath, speakerMappingPath);
} catch (err) {
process.exit(1);
}
})();
}
+23
View File
@@ -0,0 +1,23 @@
@echo off
cd /d %~dp0
:: Prüfen ob Node.js installiert ist
where node >nul 2>nul
if %errorlevel% neq 0 (
echo Node.js ist nicht installiert.
pause
exit /b 1
)
echo Node.js gefunden:
node -v
npm install
if %errorlevel% neq 0 (
echo npm install fehlgeschlagen.
pause
exit /b 1
)
npm start
pause
Executable
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
# Prüfen ob Node.js installiert ist
if ! command -v node >/dev/null 2>&1; then
echo "Node.js ist nicht installiert."
exit 1
fi
echo "Node.js gefunden: $(node -v)"
# Abhängigkeiten installieren
npm install || exit 1
# Projekt starten
npm start
@@ -0,0 +1,5 @@
{
"speakerId": "speakerB",
"speakerName": "Peter",
"updated": "2026-01-10T13:54:55.608Z"
}