mirror of
https://gitlab.rlp.net/proj-wise2526-video2document/video2document.git
synced 2026-06-15 18:01:52 +02:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 791dbab739 | |||
| c497fa9532 | |||
| 3ce632bf8d | |||
| 6512b50d83 | |||
| faee605f12 | |||
| 037d29e656 | |||
| 8c201db539 | |||
| 882b49a489 | |||
| 25d11d74a3 | |||
| 0d3535128d | |||
| e661aefbe8 | |||
| ed94928953 | |||
| 8adf470f18 | |||
| f858f2edbb | |||
| 05c04aaef2 | |||
| 84cc94aa34 | |||
| 16f319f89f | |||
| 9ab98825a2 | |||
| 9a0a349813 | |||
| 9dfc05e987 | |||
| a5a60635fc | |||
| af13907fdc | |||
| 812bca8cfb | |||
| 34d644d7d7 | |||
| e73a2a8203 | |||
| 2f5efee9c7 | |||
| 465fe8bd41 | |||
| 0f689e2846 | |||
| b87bfd444d | |||
| 97b571b7f9 | |||
| 455147a41b | |||
| 9441699561 |
+16
-2
@@ -963,9 +963,23 @@ app.*.symbols
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
!/dev/ci/**/Gemfile.lock
|
||||
|
||||
#Storage files
|
||||
storage/
|
||||
# Storage files
|
||||
storage/documents/*
|
||||
storage/transcriptionSummaries/*
|
||||
storage/transcripts/*
|
||||
storage/video/*
|
||||
# The inverse for the .gitkeep files, to make sure the folders are there but not the local files
|
||||
!storage/documents/.gitkeep
|
||||
!storage/transcriptionSummaries/.gitkeep
|
||||
!storage/transcripts/.gitkeep
|
||||
!storage/video/.gitkeep
|
||||
|
||||
*.mp4
|
||||
*.webm
|
||||
*.mp3
|
||||
*.mov
|
||||
*.wav
|
||||
*.flac
|
||||
|
||||
|
||||
!testvideo.mp4
|
||||
|
||||
+19
-25
@@ -1,33 +1,27 @@
|
||||
workflow:
|
||||
rules:
|
||||
# Run the pipeline for merge requests or when committing to a branch
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
- if: $CI_COMMIT_BRANCH
|
||||
|
||||
image: python:3.14.0
|
||||
image: node:latest
|
||||
|
||||
stages:
|
||||
- setup
|
||||
# - install
|
||||
- test
|
||||
|
||||
setup_environment:
|
||||
stage: setup
|
||||
script:
|
||||
- pip install --upgrade pip
|
||||
- pip install -r requirements.txt
|
||||
- echo "Dependencies installed successfully."
|
||||
# job-install:
|
||||
# stage: install
|
||||
# script:
|
||||
# - npm install
|
||||
# artifacts:
|
||||
# untracked: false
|
||||
# when: on_success
|
||||
# access: all
|
||||
# expire_in: "30 days"
|
||||
# paths:
|
||||
# - node_modules
|
||||
|
||||
only:
|
||||
- main
|
||||
- feature/ci-pipeline-s1-09a-1 # You can add more branches if needed
|
||||
|
||||
test_app:
|
||||
|
||||
job-test:
|
||||
stage: test
|
||||
script:
|
||||
- echo "Running V2D Framework basic test..."
|
||||
- python -m unittest discover || echo "No tests found."
|
||||
|
||||
only:
|
||||
- main
|
||||
- feature/ci-pipeline-s1-09a-1
|
||||
|
||||
- npm install
|
||||
- echo "ASSEMBLYAI_API_KEY=$apikey_assembly" > .env
|
||||
- echo "GOOGLE_API_KEY=$apikey_gemini" >> .env
|
||||
- npm test
|
||||
@@ -21,7 +21,9 @@
|
||||
<select name="transkript_type" id="transkript_type">
|
||||
</select>
|
||||
<select name="output_type" id="output_type">
|
||||
<option value="mp4">mp4</option>
|
||||
<option value="flac">flac</option>
|
||||
<option value="mp3">mp3</option>
|
||||
<option value="wav">wav</option>
|
||||
</select>
|
||||
<select name="language_option" id="language_option">
|
||||
</select>
|
||||
|
||||
@@ -12,7 +12,7 @@ function checkBoxes() {
|
||||
}
|
||||
});
|
||||
|
||||
if(isChecked){
|
||||
if (isChecked) {
|
||||
//Code to submit the video
|
||||
var selectedCheckboxes = {};
|
||||
checkboxes.forEach(function(checkbox){
|
||||
@@ -59,6 +59,8 @@ function checkBoxes() {
|
||||
}else{
|
||||
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
//language only english at the moment
|
||||
alert('Please select at least one document type.');
|
||||
@@ -115,7 +117,7 @@ function handleFiles(files) {
|
||||
}
|
||||
|
||||
//function to regulate the progress on the progressbar
|
||||
function updateProgressBar(bar, value){
|
||||
function updateProgressBar(bar, value) {
|
||||
try {
|
||||
value = Math.round(value);
|
||||
bar.querySelector(".progress_fill").style.width = `${value}%`;
|
||||
|
||||
@@ -35,6 +35,8 @@ console.log("-------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------- CLI COMMANDS --------------------------------------------------------- //
|
||||
|
||||
const rl = readline.createInterface({
|
||||
@@ -127,7 +129,7 @@ electron.ipcMain.handle('get-module-names', async () => {
|
||||
electron.ipcMain.on("file_submit", async (event, args) => {
|
||||
try {
|
||||
let curstep = 0
|
||||
let totalsteps = 2 + args.document.styles.length
|
||||
let totalsteps = 3 + args.document.styles.length
|
||||
|
||||
if(args.document.styles.length == 0)
|
||||
throw new Error("At least one Document Style needed");
|
||||
@@ -137,9 +139,10 @@ electron.ipcMain.on("file_submit", async (event, args) => {
|
||||
let audiopath = ""
|
||||
let transcriptpath = ""
|
||||
|
||||
console.log("\n\n Running the Video to Audio Extractor");
|
||||
// This code handles the Video to Audio extraction module call
|
||||
await mapFunctions.get("module-handler").function(args.video.module, {inputVideoPath: args.video.inputVideoPath, outputType: args.video.outputType}).then(resp => {
|
||||
// console.log(resp);
|
||||
await mapFunctions.get("module-handler").function(args.video.module, {inputVideoPath: args.video.inputVideoPath, outputType: mapFunctions.get(args.transcription.module).audioformat}).then(resp => {
|
||||
console.log(resp);
|
||||
audiopath = resp
|
||||
curstep++
|
||||
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
@@ -149,31 +152,67 @@ electron.ipcMain.on("file_submit", async (event, args) => {
|
||||
})
|
||||
|
||||
|
||||
console.log("\n\n Running the Audio to Transcription module");
|
||||
// TODO implement transcription module
|
||||
// // This code handles the Audio to Text transcription module call
|
||||
// await mapFunctions.get("module-handler").function(args.transcription.module, audiopath).then(resp => {
|
||||
// console.log(resp);
|
||||
// transcriptpath = resp
|
||||
// curstep++
|
||||
// mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
// }).catch(err => {
|
||||
// mainWindow.webContents.send("error", err)
|
||||
// return
|
||||
// })
|
||||
// This code handles the Audio to Text transcription module call
|
||||
await mapFunctions.get("module-handler").function(args.transcription.module, audiopath).then(resp => {
|
||||
console.log(resp);
|
||||
transcriptpath = resp
|
||||
curstep++
|
||||
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
}).catch(err => {
|
||||
mainWindow.webContents.send("error", err)
|
||||
return
|
||||
})
|
||||
|
||||
|
||||
console.log("\n\n Running the Transcription Summarizer module");
|
||||
// This code summarises the transcript, so that it can be used by an llm
|
||||
// await mapFunctions.get("summarize-transcription").function('A:\\programing\\@projects\\video2document\\storage\\transcripts\\IMG_2978.json').then(resp => {
|
||||
await mapFunctions.get("summarize-transcription2").function(transcriptpath).then(resp => {
|
||||
console.log(resp);
|
||||
transcriptpath = resp
|
||||
curstep++
|
||||
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
}).catch(err => {
|
||||
mainWindow.webContents.send("error", err)
|
||||
return
|
||||
})
|
||||
|
||||
console.log("\n\n Running the LLM module");
|
||||
// TODO implement documentation module
|
||||
// // This code handles the Text to Document processing module call
|
||||
// for (let i = 0; i < args.document.styles.length; i++) {
|
||||
// await mapFunctions.get("module-handler").function(args.document.module, {prompt: args.document.styles[i].prompt, transcript: transcriptpath}).then(resp => {
|
||||
// console.log(resp);
|
||||
// transcriptpath = resp
|
||||
// curstep++
|
||||
// mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
// }).catch(err => {
|
||||
// mainWindow.webContents.send("error", err)
|
||||
// return
|
||||
// })
|
||||
// }
|
||||
// This code handles the Text to Document processing module call
|
||||
for (let i = 0; i < args.document.styles.length; i++) {
|
||||
console.log(`\n\n Running the LLM for Document Style ${i+1}`);
|
||||
|
||||
await mapFunctions.get("module-handler").function(args.document.module, {inputTranscriptPath: transcriptpath, documentTypePath: "./storage/documentType/meetingReport.json", language: "en"}).then(resp => {
|
||||
console.log(resp);
|
||||
transcriptpath = resp
|
||||
curstep++
|
||||
mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
}).catch(err => {
|
||||
mainWindow.webContents.send("error", err)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
// TODO actually implement this functionality
|
||||
// Module to get the first few lines for each speaker to send to the frontend
|
||||
// await mapFunctions.get("speaker-getter-idfk").function(transcriptpath).then(resp => {
|
||||
// console.log(resp);
|
||||
// transcriptpath = resp
|
||||
// curstep++
|
||||
// mainWindow.webContents.send("progress", {curstep:curstep, totalsteps:totalsteps})
|
||||
|
||||
// // {
|
||||
// // speakerA: {source: "Pfad zur Audio File"},
|
||||
// // speakerB:.....
|
||||
// // }
|
||||
mainWindow.webContents.send("speakers", {speakerA:"pfad1", speakerB:"pfad2"})
|
||||
// }).catch(err => {
|
||||
// mainWindow.webContents.send("error", err)
|
||||
// return
|
||||
// })
|
||||
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Generated
+602
-40
@@ -11,12 +11,13 @@
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.30.0",
|
||||
"@types/axios": "^0.9.36",
|
||||
"cli-progress": "^3.12.0",
|
||||
"axios": "^1.13.2",
|
||||
"dotenv": "^17.2.3",
|
||||
"electron": "^39.1.1",
|
||||
"express": "^5.1.0",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"fluent-ffmpeg": "^2.1.3"
|
||||
"fluent-ffmpeg": "^2.1.3",
|
||||
"mocha": "^11.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cli-progress": "^3.11.6",
|
||||
@@ -396,11 +397,31 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
|
||||
"integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ=="
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz",
|
||||
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -434,22 +455,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||
"integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz",
|
||||
"integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bytes": "^3.1.2",
|
||||
"content-type": "^1.0.5",
|
||||
"debug": "^4.4.0",
|
||||
"debug": "^4.4.3",
|
||||
"http-errors": "^2.0.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"iconv-lite": "^0.7.0",
|
||||
"on-finished": "^2.4.1",
|
||||
"qs": "^6.14.0",
|
||||
"raw-body": "^3.0.0",
|
||||
"type-is": "^2.0.0"
|
||||
"raw-body": "^3.0.1",
|
||||
"type-is": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/boolean": {
|
||||
@@ -467,6 +493,11 @@
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/browser-stdout": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
|
||||
},
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
@@ -546,22 +577,118 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/cli-progress": {
|
||||
"version": "3.12.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz",
|
||||
"integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==",
|
||||
"license": "MIT",
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.3"
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui/node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/clone-response": {
|
||||
@@ -591,6 +718,17 @@
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
|
||||
@@ -700,6 +838,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
|
||||
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
@@ -767,6 +916,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
@@ -795,7 +952,6 @@
|
||||
"version": "17.2.3",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
|
||||
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -922,12 +1078,34 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-error": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
|
||||
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
@@ -937,7 +1115,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -1080,6 +1257,29 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/find-up": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
|
||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||
"dependencies": {
|
||||
"locate-path": "^6.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/flat": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
||||
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
||||
"bin": {
|
||||
"flat": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/fluent-ffmpeg": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz",
|
||||
@@ -1093,6 +1293,25 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
@@ -1108,6 +1327,40 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data/node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data/node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/formdata-polyfill": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||
@@ -1203,6 +1456,14 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
@@ -1393,6 +1654,14 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
@@ -1416,6 +1685,20 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
@@ -1427,6 +1710,14 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||
"bin": {
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
|
||||
@@ -1496,14 +1787,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
|
||||
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
@@ -1529,11 +1825,38 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-path-inside": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-obj": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
|
||||
"integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-promise": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -1554,6 +1877,17 @@
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/json-bigint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||
@@ -1592,11 +1926,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
|
||||
"integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.0",
|
||||
"jwa": "^2.0.1",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
@@ -1608,6 +1943,35 @@
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||
"dependencies": {
|
||||
"p-locate": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/log-symbols": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
"is-unicode-supported": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lowercase-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||
@@ -1716,6 +2080,49 @@
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "11.7.5",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz",
|
||||
"integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==",
|
||||
"dependencies": {
|
||||
"browser-stdout": "^1.3.1",
|
||||
"chokidar": "^4.0.1",
|
||||
"debug": "^4.3.5",
|
||||
"diff": "^7.0.0",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"find-up": "^5.0.0",
|
||||
"glob": "^10.4.5",
|
||||
"he": "^1.2.0",
|
||||
"is-path-inside": "^3.0.3",
|
||||
"js-yaml": "^4.1.0",
|
||||
"log-symbols": "^4.1.0",
|
||||
"minimatch": "^9.0.5",
|
||||
"ms": "^2.1.3",
|
||||
"picocolors": "^1.1.1",
|
||||
"serialize-javascript": "^6.0.2",
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"supports-color": "^8.1.1",
|
||||
"workerpool": "^9.2.0",
|
||||
"yargs": "^17.7.2",
|
||||
"yargs-parser": "^21.1.1",
|
||||
"yargs-unparser": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"_mocha": "bin/_mocha",
|
||||
"mocha": "bin/mocha.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/diff": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
|
||||
"integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@@ -1824,6 +2231,34 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
|
||||
"dependencies": {
|
||||
"yocto-queue": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-locate": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
|
||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||
"dependencies": {
|
||||
"p-limit": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
@@ -1842,6 +2277,14 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
@@ -1879,6 +2322,11 @@
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
|
||||
@@ -1900,6 +2348,11 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
|
||||
@@ -1934,6 +2387,14 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
@@ -1956,21 +2417,6 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body/node_modules/iconv-lite": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
|
||||
"integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
@@ -1985,6 +2431,26 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
|
||||
"engines": {
|
||||
"node": ">= 14.18.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-alpn": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
|
||||
@@ -2122,6 +2588,14 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/serialize-javascript": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
||||
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
|
||||
"dependencies": {
|
||||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
|
||||
@@ -2314,6 +2788,17 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/sumchecker": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
|
||||
@@ -2325,6 +2810,20 @@
|
||||
"node": ">= 8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
@@ -2485,6 +2984,11 @@
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/workerpool": {
|
||||
"version": "9.3.4",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz",
|
||||
"integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg=="
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
@@ -2603,6 +3107,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-unparser": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
|
||||
"integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
|
||||
"dependencies": {
|
||||
"camelcase": "^6.0.0",
|
||||
"decamelize": "^4.0.0",
|
||||
"flat": "^5.0.2",
|
||||
"is-plain-obj": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
@@ -2621,6 +3172,17 @@
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -2,12 +2,13 @@
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.30.0",
|
||||
"@types/axios": "^0.9.36",
|
||||
"cli-progress": "^3.12.0",
|
||||
"axios": "^1.13.2",
|
||||
"dotenv": "^17.2.3",
|
||||
"electron": "^39.1.1",
|
||||
"express": "^5.1.0",
|
||||
"ffmpeg-static": "^5.2.0",
|
||||
"fluent-ffmpeg": "^2.1.3"
|
||||
"fluent-ffmpeg": "^2.1.3",
|
||||
"mocha": "^11.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cli-progress": "^3.11.6",
|
||||
@@ -26,7 +27,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "electron main.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "mocha ./test/unit/test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
fastapi
|
||||
uvicorn
|
||||
pytest
|
||||
+5
-1
@@ -11,9 +11,13 @@ config = require("./config/config")
|
||||
ffmpegPath = require('ffmpeg-static');
|
||||
ffmpeg = require('fluent-ffmpeg');
|
||||
path = require('path');
|
||||
cliProgress = require('cli-progress');
|
||||
// cliProgress = require('cli-progress');
|
||||
|
||||
// { app, BrowserWindow, ipcMain, dialog } = require('electron');
|
||||
|
||||
electron = require('electron');
|
||||
genai = require("@google/genai");
|
||||
|
||||
axios = require("axios")
|
||||
|
||||
console.log(require('dotenv').config({path: __dirname + '/.env'}));
|
||||
@@ -24,17 +24,11 @@ module.exports = {
|
||||
outputType: String // Audio file output format
|
||||
}
|
||||
*/
|
||||
let progressBar = new cliProgress.SingleBar({
|
||||
format: 'Processing |{bar}| {percentage}% | {timemark}',
|
||||
barCompleteChar: '\u2588',
|
||||
barIncompleteChar: '\u2591',
|
||||
hideCursor: true
|
||||
});
|
||||
try {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.extractAudioFromVideo(parameter.inputVideoPath, progressBar, parameter.outputType)
|
||||
this.extractAudioFromVideo(parameter.inputVideoPath, parameter.outputType)
|
||||
.then((resp) => resolve(resp))
|
||||
.catch((err) => console.error(err));
|
||||
.catch((err) => {reject(err)});
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(parameter.outputType);
|
||||
@@ -52,7 +46,7 @@ module.exports = {
|
||||
* - Shows CLI progress bar
|
||||
* - Handles errors gracefully (without errors)
|
||||
*/
|
||||
extractAudioFromVideo: async function (videoFilePath, progressBar, outputType){
|
||||
extractAudioFromVideo: async function (videoFilePath, outputType){
|
||||
let inputVideoName = path.basename(videoFilePath, path.extname(videoFilePath));
|
||||
let outputAudioPath = path.join(outputDir, `${inputVideoName}.${outputType}`);
|
||||
|
||||
@@ -63,28 +57,17 @@ module.exports = {
|
||||
// .audioCodec('pcm_s16le')
|
||||
.audioChannels(1)
|
||||
.audioFrequency(16000)
|
||||
// .setFfmpegPath("./ffmpeg.exe")
|
||||
.on('progress', (progress) => {
|
||||
if (!progressBar.isActive) progressBar.start(100, 0, { timemark: '00:00:00' });
|
||||
if (progress.percent) {
|
||||
progressBar.update(progress.percent, { timemark: progress.timemark });
|
||||
}
|
||||
})
|
||||
.on('end', () => {
|
||||
progressBar.update(100, { timemark: 'done' });
|
||||
progressBar.stop();
|
||||
console.log(`Extraction completed: ${outputAudioPath}`);
|
||||
resolve(outputAudioPath);
|
||||
})
|
||||
.on('error', (err) => {
|
||||
progressBar.stop();
|
||||
console.error(`failed_audio_extraction on type ${outputType}: ${err.message}`);
|
||||
// console.error(`failed_audio_extraction on type ${outputType}: ${err.message}`);
|
||||
reject(err);
|
||||
})
|
||||
.save(outputAudioPath);
|
||||
|
||||
} catch (error) {
|
||||
console.log();
|
||||
// console.log(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
// Prepare output directory (always storage/transcriptionSummaries under project root)
|
||||
const outputDir = `${__dirname}/../../../storage/transcriptionSummaries`;
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
//Speaker, ALL-Sentences, Start, End
|
||||
|
||||
module.exports = {
|
||||
name: "summarize-transcription", // Unique name for our function that will later be used to get the function from the map via "mapFunctions.get("example").function()"
|
||||
type: "summarizer", // value used to differentiate each module to order them in the UI
|
||||
displayname: "Summarizer", // The displayname used within the UI
|
||||
async function(args) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let inputJson = args.json;
|
||||
|
||||
//JSON Path
|
||||
if (args.jsonPath) {
|
||||
try {
|
||||
const raw = fs.readFileSync(args.jsonPath, "utf-8");
|
||||
inputJson = JSON.parse(raw);
|
||||
} catch (e) {
|
||||
// console.error("Failed to load JSON from file:", e);
|
||||
reject(e)
|
||||
return
|
||||
}
|
||||
}
|
||||
// JSON parsen
|
||||
if (typeof args === "string") {
|
||||
try {
|
||||
await new Promise((res, rej) => {
|
||||
fs.readFile(args, 'utf8', function (err, data) {
|
||||
if (err){
|
||||
rej(err)
|
||||
return
|
||||
}
|
||||
inputJson = JSON.parse(data);
|
||||
res()
|
||||
});
|
||||
})
|
||||
} catch (e) {
|
||||
// console.log("Invalid JSON in summarize-transcription");
|
||||
// console.log(e)
|
||||
reject(e)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const words = inputJson.words;
|
||||
if (!Array.isArray(words)) {
|
||||
reject("No words Array found")
|
||||
return
|
||||
}
|
||||
|
||||
const ENDINGS = [".", "!", "?"]; // '...' auch als Satzende ?
|
||||
const ABBREVIATIONS = new Set(["z.B.", "bzw.", "u.a.", "Dr.", "Mr.", "Mrs.", "Prof.", "etc."]); //TODO weitere Ergaenzen
|
||||
|
||||
const result = [];
|
||||
let currentSentence = "";
|
||||
let currentSpeaker = null;
|
||||
let startTime = null;
|
||||
let endTime = null;
|
||||
|
||||
for (const w of words) {
|
||||
if (!currentSpeaker) currentSpeaker = w.speaker;
|
||||
if (startTime === null) startTime = w.start;
|
||||
endTime = w.end;
|
||||
|
||||
//speaker changing
|
||||
if (currentSpeaker !== w.speaker && currentSentence) {
|
||||
const lastEntry = result[result.length - 1];
|
||||
if (lastEntry && lastEntry.speaker === currentSpeaker) {
|
||||
lastEntry.sentence += " " + currentSentence;
|
||||
lastEntry.end = endTime;
|
||||
} else {
|
||||
result.push({
|
||||
speaker: currentSpeaker,
|
||||
sentence: currentSentence,
|
||||
start: startTime,
|
||||
end: endTime
|
||||
});
|
||||
}
|
||||
currentSentence = "";
|
||||
startTime = w.start;
|
||||
}
|
||||
currentSpeaker = w.speaker;
|
||||
currentSentence += (currentSentence ? " " : "") + w.text; //sentence beginning or not
|
||||
const lastWord = w.text.trim();
|
||||
const lastChar = lastWord.slice(-1);
|
||||
const isAbbreviation = ABBREVIATIONS.has(lastWord);
|
||||
|
||||
//sentence ending
|
||||
if (ENDINGS.includes(lastChar) && !isAbbreviation) {
|
||||
const lastEntry = result[result.length - 1];
|
||||
if (lastEntry && lastEntry.speaker === currentSpeaker) {
|
||||
lastEntry.sentence += " " + currentSentence;
|
||||
lastEntry.end = endTime;
|
||||
} else {
|
||||
result.push({
|
||||
speaker: currentSpeaker,
|
||||
sentence: currentSentence,
|
||||
start: startTime,
|
||||
end: endTime
|
||||
});
|
||||
}
|
||||
currentSentence = "";
|
||||
startTime = null;
|
||||
endTime = null;
|
||||
currentSpeaker = null;
|
||||
}
|
||||
}
|
||||
|
||||
// safe last sentence
|
||||
if (currentSentence) {
|
||||
const lastEntry = result[result.length - 1];
|
||||
if (lastEntry && lastEntry.speaker === currentSpeaker) {
|
||||
lastEntry.sentence += " " + currentSentence;
|
||||
lastEntry.end = endTime;
|
||||
} else {
|
||||
result.push({
|
||||
speaker: currentSpeaker,
|
||||
sentence: currentSentence,
|
||||
start: startTime,
|
||||
end: endTime
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Output as Text
|
||||
const output = result.map(r =>
|
||||
`Sprecher ${r.speaker} [${r.start.toFixed(2)} - ${r.end.toFixed(2)}]: ${r.sentence}`
|
||||
);
|
||||
|
||||
// Output on cosole
|
||||
//console.log("\n------------\nMerged Transcription Result:\n", output, "\n------------\n");
|
||||
|
||||
try {
|
||||
const jsonPath = path.join(outputDir, "transcription_result.json");
|
||||
fs.writeFileSync(jsonPath, JSON.stringify(result, null, 2), "utf-8");
|
||||
|
||||
const txtPath = path.join(outputDir, "transcription_result.txt");
|
||||
fs.writeFileSync(txtPath, output.join("\n"), "utf-8");
|
||||
|
||||
// console.log(`Summary successfully saved:\n- ${jsonPath}\n- ${txtPath}`);
|
||||
|
||||
resolve(jsonPath);
|
||||
} catch (err) {
|
||||
// console.error("Error saving Summary:", err);
|
||||
reject(err);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
// Prepare output directory (always storage/transcriptionSummaries under project root)
|
||||
const outputDir = `${__dirname}/../../../storage/transcriptionSummaries`;
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
function getSessionId(inputPath) {
|
||||
try {
|
||||
const parsed = new URL(inputPath);
|
||||
const base = path.basename(parsed.pathname);
|
||||
return base.replace(/\.[^.]+$/, '');
|
||||
} catch {
|
||||
return path.basename(inputPath, path.extname(inputPath));
|
||||
}
|
||||
}
|
||||
|
||||
//Speaker, Sentence, Start, End
|
||||
|
||||
module.exports = {
|
||||
name: "summarize-transcription2", // Unique name for our function that will later be used to get the function from the map via "mapFunctions.get("example").function()"
|
||||
type: "summarizer", // value used to differentiate each module to order them in the UI
|
||||
displayname: "Summarizer", // The displayname used within the UI
|
||||
async function(args) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let inputJson = args.json;
|
||||
|
||||
//JSON Path
|
||||
if (args.jsonPath) {
|
||||
try {
|
||||
const raw = fs.readFileSync(args.jsonPath, "utf-8");
|
||||
inputJson = JSON.parse(raw);
|
||||
} catch (e) {
|
||||
console.error("Failed to load JSON from file:", e);
|
||||
reject("Could not read JSON from file path.")
|
||||
return
|
||||
}
|
||||
}
|
||||
// JSON parsen
|
||||
if (typeof args === "string") {
|
||||
try {
|
||||
await new Promise((res, rej) => {
|
||||
fs.readFile(args, 'utf8', function (err, data) {
|
||||
if (err){
|
||||
rej(err)
|
||||
return
|
||||
}
|
||||
inputJson = JSON.parse(data);
|
||||
res()
|
||||
});
|
||||
})
|
||||
} catch (e) {
|
||||
// console.log("Invalid JSON in summarize-transcription");
|
||||
// console.log(e)
|
||||
reject(e)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const words = inputJson.words;
|
||||
if (!Array.isArray(words)) {
|
||||
reject("No words Array found")
|
||||
return;
|
||||
}
|
||||
|
||||
const ENDINGS = [".", "!", "?"]; // '...' auch als Satzende ?
|
||||
const ABBREVIATIONS = new Set(["z.B.", "bzw.", "u.a.", "Dr.", "Mr.", "Mrs.", "Prof.", "etc."]); //TODO weitere Ergaenzen
|
||||
|
||||
const result = [];
|
||||
let currentSentence = "";
|
||||
let currentSpeaker = null;
|
||||
let startTime = null;
|
||||
let endTime = null;
|
||||
|
||||
for (const w of words) {
|
||||
if (!currentSpeaker) currentSpeaker = w.speaker;
|
||||
if (startTime === null) startTime = w.start;
|
||||
endTime = w.end;
|
||||
|
||||
//speaker changing
|
||||
if (currentSpeaker !== w.speaker && currentSentence) {
|
||||
result.push({
|
||||
speaker: currentSpeaker,
|
||||
sentence: currentSentence,
|
||||
start: startTime,
|
||||
end: endTime
|
||||
});
|
||||
currentSentence = "";
|
||||
startTime = w.start;
|
||||
}
|
||||
currentSpeaker = w.speaker;
|
||||
currentSentence += (currentSentence ? " " : "") + w.text; //sentence beginning or not
|
||||
const lastWord = w.text.trim();
|
||||
const lastChar = lastWord.slice(-1);
|
||||
const isAbbreviation = ABBREVIATIONS.has(lastWord);
|
||||
|
||||
//sentence ending
|
||||
if (ENDINGS.includes(lastChar) && !isAbbreviation) {
|
||||
result.push({
|
||||
speaker: currentSpeaker,
|
||||
sentence: currentSentence,
|
||||
start: startTime,
|
||||
end: endTime
|
||||
});
|
||||
currentSentence = "";
|
||||
startTime = null;
|
||||
endTime = null;
|
||||
currentSpeaker = null;
|
||||
}
|
||||
}
|
||||
|
||||
// safe last sentence
|
||||
if (currentSentence) {
|
||||
result.push({
|
||||
speaker: currentSpeaker,
|
||||
sentence: currentSentence,
|
||||
start: startTime,
|
||||
end: endTime
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Output as Text
|
||||
const output = result.map(r =>
|
||||
`Sprecher ${r.speaker} [${r.start.toFixed(2)} - ${r.end.toFixed(2)}]: ${r.sentence}`
|
||||
);
|
||||
|
||||
// Output on cosole
|
||||
//console.log("\n------------\nMerged Transcription Result:\n", output, "\n------------\n");
|
||||
|
||||
try {
|
||||
|
||||
let filename = getSessionId(args);
|
||||
|
||||
const jsonPath = path.join(outputDir, `${filename}-${new Date().getTime()}.json`);
|
||||
fs.writeFileSync(jsonPath, JSON.stringify(result, null, 2), "utf-8");
|
||||
|
||||
const txtPath = path.join(outputDir, `${filename}-${new Date().getTime()}.txt`);
|
||||
fs.writeFileSync(txtPath, output.join("\n"), "utf-8");
|
||||
|
||||
// console.log(`Summary successfully saved:\n- ${jsonPath}\n- ${txtPath}`);
|
||||
resolve(jsonPath);
|
||||
} catch (err) {
|
||||
// console.error("Error saving Summary:", err);
|
||||
reject(err);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,10 @@ if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true }); // Create output directory if it doesn't exist
|
||||
}
|
||||
|
||||
const ai = new genai.GoogleGenAI({
|
||||
apiKey: process.env.GOOGLE_API_KEY // Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here"
|
||||
});
|
||||
// Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here"
|
||||
|
||||
const GEMINI_API_KEY = process.env.GOOGLE_API_KEY; // Ensure Google API key is set in environment variables: export GOOGLE_API_KEY="your_api_key_here"
|
||||
const GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent"; //URL for the REST call, used model and action
|
||||
|
||||
module.exports = {
|
||||
name: "llm-gemini",
|
||||
@@ -15,41 +16,69 @@ module.exports = {
|
||||
description: "Generates documents using Google Gemini LLM",
|
||||
|
||||
async function(parameter) {
|
||||
try {
|
||||
console.log("Gemini LLM module invoked with parameters:", parameter);
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
// console.log("Gemini LLM module invoked with parameters:", parameter);
|
||||
|
||||
await this.createDocumentFromTranscript( //Call the function to create document with transcript, document type and language
|
||||
parameter.inputTranscriptPath, // Path to input transcript file
|
||||
parameter.documentTypePath, // Path to document type file which is chosen in the front end by the user
|
||||
parameter.language // Language for the document which is chosen in the front end by the user
|
||||
);
|
||||
resolve(await this.createDocumentFromTranscript( //Call the function to create document with transcript, document type and language
|
||||
parameter.inputTranscriptPath, // Path to input transcript file
|
||||
parameter.documentTypePath, // Path to document type file which is chosen in the front end by the user
|
||||
parameter.language // Language for the document which is chosen in the front end by the user
|
||||
));
|
||||
|
||||
} catch (error) {
|
||||
// console.error("Error in Gemini LLM module:", error);
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error in Gemini LLM module:", error);
|
||||
}
|
||||
},
|
||||
|
||||
createDocumentFromTranscript: async function(transcriptPath, documentTypePath, language = "en") { // default language is English
|
||||
try {
|
||||
const transcript = await fs.promises.readFile(transcriptPath, "utf-8");
|
||||
const documentType = await fs.promises.readFile(documentTypePath, "utf-8");
|
||||
return new Promise(async(resolve, reject) => {
|
||||
try {
|
||||
const transcript = await fs.promises.readFile(transcriptPath, "utf-8"); //read transcript file from Path
|
||||
const documentType = await fs.promises.readFile(documentTypePath, "utf-8"); //read document type from Path
|
||||
const promptText = `${documentType}, in language ${language}, transcript:\n\n${transcript}`; //combine doc type, language and transcript - Change prompt here if needed
|
||||
|
||||
const promptText = `${documentType}, in language ${language}, transcript:\n\n${transcript}`;
|
||||
// --- REST CALL ---
|
||||
const response = await fetch(`${GEMINI_URL}?key=${GEMINI_API_KEY}`, { //safe model response in variable
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
contents: [
|
||||
{
|
||||
parts: [
|
||||
{ text: promptText } // Input prompt for content generation
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
const response = await ai.models.generateContent({
|
||||
model: "gemini-2.5-flash", // Specify the Gemini model to use
|
||||
contents: promptText // Input prompt for content generation
|
||||
});
|
||||
if (!response.ok) { //ok is true when a responce was successfull
|
||||
const text = await response.text();
|
||||
throw new Error(`Gemini API error (${response.status}): ${text}`);
|
||||
}
|
||||
|
||||
const output = response.text || ""; // Get generated text from response or default to empty string (if null)
|
||||
const data = await response.json();
|
||||
|
||||
const outPath = path.join(outputDir, "test.md"); // Output file path & name TO BE DONE to make dynamic out of input transcript name
|
||||
fs.writeFileSync(outPath, output, "utf8"); // Write output to file
|
||||
// Get generated text from response or default to empty string (if null)
|
||||
const output = data?.candidates?.[0]?.content?.parts?.[0]?.text || "";
|
||||
let inputTranscriptName = path.basename(transcriptPath, path.extname(transcriptPath)); // Name for the output file
|
||||
// console.log(inputTranscriptName);
|
||||
const outPath = path.join(outputDir, `${inputTranscriptName}.md`); // Output file path & name to make naming dynamic. Pulled from input transcript name
|
||||
fs.writeFileSync(outPath, output, "utf8"); // Write output to file
|
||||
|
||||
console.log("Generated document written to:", outPath);
|
||||
// console.log("Generated document written to:", outPath);
|
||||
resolve(outPath)
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error generating Gemini content:", error);
|
||||
}
|
||||
} catch (error) {
|
||||
// console.error("Error generating Gemini content:", error);
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
@@ -1,8 +1,125 @@
|
||||
module.exports = {
|
||||
name:"assembly", // Unique name for our function that will later be used to get the function from the map via "mapFunctions.get("example").function()"
|
||||
type:"transcription", // value used to differentiate each module to order them in the UI
|
||||
displayname:"Assembly", // The displayname used within the UI
|
||||
async function(parameter){
|
||||
// TODO add code to actually process the audio file
|
||||
const API_KEY = process.env.ASSEMBLYAI_API_KEY;
|
||||
const BASE_URL = 'https://api.assemblyai.com/v2';
|
||||
|
||||
//---------------------------------------------------Upload audio---------------------------------------------------
|
||||
|
||||
async function uploadAudio(audioPath) {
|
||||
const audioData = fs.readFileSync(audioPath);
|
||||
|
||||
const response = await axios.post(`${BASE_URL}/upload`, audioData, {
|
||||
headers: {
|
||||
authorization: API_KEY,
|
||||
'content-type': 'application/octet-stream'
|
||||
}
|
||||
});
|
||||
|
||||
return response.data.upload_url;
|
||||
}
|
||||
|
||||
////---------------------------------------------------Extract session id---------------------------------------------------
|
||||
|
||||
function getSessionId(inputPath) {
|
||||
try {
|
||||
const parsed = new URL(inputPath);
|
||||
const base = path.basename(parsed.pathname);
|
||||
return base.replace(/\.[^.]+$/, '');
|
||||
} catch {
|
||||
return path.basename(inputPath, path.extname(inputPath));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------Create transcript---------------------------------------------------
|
||||
|
||||
async function createTranscript(audioUrl) {
|
||||
const response = await axios.post(
|
||||
`${BASE_URL}/transcript`,
|
||||
{
|
||||
audio_url: audioUrl,
|
||||
speaker_labels: true,
|
||||
language_detection: true
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
authorization: API_KEY,
|
||||
'content-type': 'application/json'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return response.data.id;
|
||||
}
|
||||
|
||||
//---------------------------------------------------Poll transcript---------------------------------------------------
|
||||
|
||||
async function pollTranscript(transcriptId) {
|
||||
while (true) {
|
||||
const response = await axios.get(`${BASE_URL}/transcript/${transcriptId}`, {
|
||||
headers: { authorization: API_KEY }
|
||||
});
|
||||
|
||||
const status = response.data.status;
|
||||
|
||||
if (status === 'completed') return response.data;
|
||||
if (status === 'error') throw new Error(`Transcription failed: ${response.data.error}`);
|
||||
|
||||
await new Promise(res => setTimeout(res, 3000));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------Save transcript---------------------------------------------------
|
||||
|
||||
function saveTranscript(transcript, sessionId) {
|
||||
const outputDir = path.join(__dirname, '../../../storage/transcripts');
|
||||
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
const outputPath = path.join(outputDir, `${sessionId}.json`);
|
||||
fs.writeFileSync(outputPath, JSON.stringify(transcript, null, 2));
|
||||
|
||||
// console.log(`Transcript saved: ${outputPath}`);
|
||||
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
//---------------------------------------------------Modul---------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
name: 'assembly',
|
||||
type: 'transcription',
|
||||
displayname: 'AssemblyAI',
|
||||
audioformat: "mp3",
|
||||
|
||||
async function(audioFileName) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
// audioFileName ist nur "datei.mp3"
|
||||
const audioPath = audioFileName;
|
||||
|
||||
let audioUrl;
|
||||
|
||||
if (/^https?:\/\//i.test(audioFileName)) {
|
||||
audioUrl = audioFileName;
|
||||
} else {
|
||||
if (!fs.existsSync(audioPath)) {
|
||||
throw new Error(`Audio file not found: ${audioPath}`);
|
||||
}
|
||||
audioUrl = await uploadAudio(audioPath);
|
||||
}
|
||||
|
||||
const transcriptId = await createTranscript(audioUrl);
|
||||
const transcript = await pollTranscript(transcriptId);
|
||||
|
||||
const sessionId = getSessionId(audioFileName);
|
||||
|
||||
resolve(saveTranscript(transcript, sessionId));
|
||||
|
||||
} catch (error) {
|
||||
// console.error('Transcription error:', error.message);
|
||||
reject(error);
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
module.exports = {
|
||||
name:"Startup_function",
|
||||
async function(){
|
||||
@@ -6,6 +7,13 @@ module.exports = {
|
||||
// We are now calling the example function from the example folder
|
||||
mapFunctions.get("example").function("Startup")
|
||||
|
||||
// let transcript = await mapFunctions.get("assembly").function('../../storage/audio/IMG_2978.wav');
|
||||
|
||||
// let summary = await mapFunctions.get("summarize-transcription").function({jsonPath:'/Users/santa/Proj25/video2document/storage/transcripts/IMG_2978.json'});
|
||||
|
||||
|
||||
|
||||
|
||||
// mapFunctions.get("extraction-video-to-audio").function({inputVideoPath:"./a.mp4", outputType:"wav"})
|
||||
// mapFunctions.get("extraction-video-to-audio").function({inputVideoPath:"./b.mp4", outputType:"wav"})
|
||||
// mapFunctions.get("extraction-video-to-audio").function({inputVideoPath:"./b.mp4", outputType:"flac"})
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"FORMAT": "markdown",
|
||||
"GOAL":"Generate a structured meeting report (Markdown). **Output ONLY:** final .md. No meta.",
|
||||
"STRUCTURE": {
|
||||
"titlepage": ["title","date","start","end","duration","location","host","participants"],
|
||||
"toc": "[section](#anchor) — HH:MM:SS",
|
||||
"section": {
|
||||
"h2": "<topic> — HH:MM:SS",
|
||||
"summary": "1 sentence",
|
||||
"key_points": "<=5 bullets, quotes optional",
|
||||
"decisions": "list: text | owner | due",
|
||||
"actions": "table: id | task | owner | due | status"
|
||||
},
|
||||
"exec_summary": "3 short sentences",
|
||||
"consolidated": ["decisions", "actions"],
|
||||
"appendix": "optional"
|
||||
},
|
||||
|
||||
"STYLE": {
|
||||
"tone": "neutral, concise",
|
||||
"ts_format": "HH:MM:SS",
|
||||
"no_meta": true
|
||||
},
|
||||
|
||||
"PROCESS": {
|
||||
"timestamps": "use if present; else estimate minimal",
|
||||
"speakers": "use labels; else Speaker X",
|
||||
"long_transcripts": "chunk → summarize → merge",
|
||||
"unclear": "UNKLAR:<reason>"
|
||||
},
|
||||
|
||||
"JSON_OUTPUT_OPTIONAL": true,
|
||||
|
||||
"PROMPT_SNIPPET": "Generate meeting report in markdown using STRUCTURE and STYLE. Output only the report."
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
require('dotenv').config();
|
||||
const path = require('path');
|
||||
const assemblyModule = require('../../services/modules/transcription-remote/assembly.js');
|
||||
|
||||
// Audio-Datei oder URL aus Kommandozeile, Standard: test.wav
|
||||
const audioPath = process.argv[2] || './storage/audio/IMG_2978.wav';
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const transcript = await assemblyModule.run(audioPath);
|
||||
|
||||
console.log('Transcription succesful');
|
||||
console.log('Transcript ID:', transcript?.id);
|
||||
console.log('Speaker labels:', transcript?.utterances?.length || 0);
|
||||
} catch (error) {
|
||||
console.error('Error in Transcription:', error?.message || error);
|
||||
}
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
const fs = require('fs');
|
||||
const transSummarizer = require("../../services/modules/jsonTools/transcriptionSummarizer.js");
|
||||
|
||||
// JSON-Datei laden
|
||||
const inputJson = JSON.parse(fs.readFileSync("./testFile.json", "utf8"));
|
||||
|
||||
// Übergabe an den Summarizer
|
||||
transSummarizer.function({
|
||||
json: inputJson
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
from fastapi.testclient import TestClient
|
||||
from app.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
def test_health():
|
||||
response = client.get("/health")
|
||||
assert response.status_code == 200
|
||||
@@ -0,0 +1,170 @@
|
||||
// DO NOT TOUCH THIS
|
||||
require("../../requires.js")
|
||||
|
||||
mapFunctions = new Map()
|
||||
// Loading the Function Map
|
||||
var path = `${mainDir}/services/modules`
|
||||
var folders = fs.readdirSync(path).filter(function (file) {
|
||||
return fs.statSync(path+'/'+file).isDirectory();
|
||||
});
|
||||
folders.forEach(element => {
|
||||
var commandFiles = fs.readdirSync(`${path}/${element}`).filter(file => file.endsWith('.js') && !file.startsWith("index"));
|
||||
for (const file of commandFiles) {
|
||||
delete require.cache[require.resolve(`${path}/${element}/${file}`)];
|
||||
const command = require(`${path}/${element}/${file}`);
|
||||
mapFunctions.set(command.name, command);
|
||||
}
|
||||
});
|
||||
// You can touch beyond this point
|
||||
|
||||
let audiopath
|
||||
let transcriptPath
|
||||
let summarizePath
|
||||
let llmpath
|
||||
|
||||
describe("Unit Tests", function() {
|
||||
|
||||
describe('Audio Extraction', function () {
|
||||
this.slow(1000)
|
||||
this.timeout(3000)
|
||||
it('Extract .mp4 to .mp3', function (done) {
|
||||
|
||||
mapFunctions.get("extraction-video-to-audio").function({inputVideoPath: __dirname.replaceAll("\\","/")+"/testvideo.mp4", outputType: "mp3"}).then(resp => {
|
||||
audiopath = resp
|
||||
// console.log(resp);
|
||||
done()
|
||||
}).catch(err => {
|
||||
throw err;
|
||||
})
|
||||
})
|
||||
it('Extract .mp4 to .flac', function (done) {
|
||||
|
||||
mapFunctions.get("extraction-video-to-audio").function({inputVideoPath: __dirname.replaceAll("\\","/")+"/testvideo.mp4", outputType: "flac"}).then(resp => {
|
||||
// console.log(resp);
|
||||
done()
|
||||
}).catch(err => {
|
||||
throw err;
|
||||
})
|
||||
})
|
||||
it('Extracting to a nonexistant format', function (done) {
|
||||
|
||||
mapFunctions.get("extraction-video-to-audio").function({inputVideoPath: __dirname.replaceAll("\\","/")+"/testvideo.mp4", outputType: "qqq"}).then(resp => {
|
||||
// console.log(resp);
|
||||
done("Didnt crash")
|
||||
}).catch(err => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
it('Extracting from nonexistant file', function (done) {
|
||||
|
||||
mapFunctions.get("extraction-video-to-audio").function({inputVideoPath: "a", outputType: "mp3"}).then(resp => {
|
||||
// console.log(resp);
|
||||
done("Didnt crash")
|
||||
}).catch(err => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
it('Extracting from nonexistant file to nonexistant format', function (done) {
|
||||
|
||||
mapFunctions.get("extraction-video-to-audio").function({inputVideoPath: "a", outputType: "qqq"}).then(resp => {
|
||||
// console.log(resp);
|
||||
done("Didnt crash")
|
||||
}).catch(err => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
describe("Audio Transcription", function() {
|
||||
this.slow(20000)
|
||||
this.timeout(120000)
|
||||
|
||||
it('Assembly', function (done) {
|
||||
mapFunctions.get("assembly").function(audiopath).then(resp => {
|
||||
// console.log(resp);
|
||||
transcriptPath = resp
|
||||
done()
|
||||
}).catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
|
||||
it('Assembly Wrong file', function (done) {
|
||||
mapFunctions.get("assembly").function("a").then(resp => {
|
||||
// console.log(resp);
|
||||
// transcriptPath = resp
|
||||
done("Didnt crash")
|
||||
}).catch(err => {
|
||||
// console.log(err);
|
||||
done()
|
||||
})
|
||||
})
|
||||
// TODO add more Transcription Tool tests here
|
||||
})
|
||||
|
||||
describe("Transcript Summarizer", function() {
|
||||
this.slow(100)
|
||||
this.timeout(1000)
|
||||
|
||||
it("Summarizer 1", function (done){
|
||||
mapFunctions.get("summarize-transcription").function(transcriptPath).then(resp => {
|
||||
done()
|
||||
}).catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
|
||||
it("Summarizer 1 Wrong File", function (done){
|
||||
mapFunctions.get("summarize-transcription").function("a").then(resp => {
|
||||
done("Didnt crash")
|
||||
}).catch(err => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it("Summarizer 2 (Main)", function (done){
|
||||
mapFunctions.get("summarize-transcription2").function(transcriptPath).then(resp => {
|
||||
summarizePath = resp
|
||||
done()
|
||||
}).catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
|
||||
it("Summarizer 2 (Main) Wrong File", function (done){
|
||||
mapFunctions.get("summarize-transcription2").function("a").then(resp => {
|
||||
done("Didnt crash")
|
||||
}).catch(err => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Large Language Model", function() {
|
||||
this.slow(30000)
|
||||
this.timeout(120000)
|
||||
|
||||
// it("ChatGPT", function (done){
|
||||
// mapFunctions.get("chatgpt").function({inputTranscriptPath: summarizePath, documentTypePath: "./storage/documentType/meetingReport.json", language: "en"}).then(resp => {
|
||||
// done()
|
||||
// }).catch(err => {
|
||||
// throw err
|
||||
// })
|
||||
// })
|
||||
|
||||
it("Gemini", function (done){
|
||||
mapFunctions.get("llm-gemini").function({inputTranscriptPath: summarizePath, documentTypePath: "./storage/documentType/meetingReport.json", language: "en"}).then(resp => {
|
||||
llmpath = resp
|
||||
done()
|
||||
}).catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
})
|
||||
after(function() {
|
||||
console.log(`\n\n\n${audiopath} \n${transcriptPath} \n${summarizePath} \n${llmpath}`);
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user