first commit

This commit is contained in:
Yuriy 2024-01-14 21:39:35 -05:00
commit a7740292a7
9 changed files with 1005 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
Assets/Git.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

BIN
Assets/Main_Screen2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,97 @@
;---ENVIRONMENT---------------------------------------------------------------------
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn ; Enable warnings to assist with detecting common errors.
;DetectHiddenWindows, On
#SingleInstance, Force
DetectHiddenWindows, ON
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;SetKeyDelay, 500
CoordMode, ToolTip, Screen
CoordMode, Mouse, Screen
; #NoTrayIcon
; Menu, Tray, Icon, RMScriptManager.ico
;---Notes/Extra Info/#Includes------------------------------------------------------
; msgbox
;---VARIABLES-----------------------------------------------------------------------
/*ScriptToCompile = %1%
CompileType = %2% ; Testing OR Production
if(CompileType = "")
CompileType = Testing
; Msgbox % "CompileType: " CompileType
if(ScriptToCompile = "")
ExitApp
*/
; Msgbox % "ScriptToCompile: " ScriptToCompile
ScriptToCompile = SocialMediaPoster
; ScriptToCompile = ScriptUpdater
;---MAIN SCRIPT---------------------------------------------------------------------
AHKFilepath = %A_ScriptDir%\Whisper-AHK.ahk
Exefilepath = %A_ScriptDir%\Whisper-AHK.exe
icopath = %A_ScriptDir%\Assets\Elegantthemes-Beautiful-Flat-Speaker.ico
; Kill any active intances of the uploaders so the .exe file can be overwriten by the compilation
process, close, Whisper-AHK.exe
sleep, 1000
; Delete the .exe file so it can be repalced
if(FileExist(Exefilepath)){
FileDelete, %Exefilepath%
if(ErrorLevel){
msgbox, failed to delete Exe file. Please delete manually and re-run the compiler.
ExitApp
}
}
if(!FileExist(AHKFilepath)){
msgbox, %AHKFilepath% does not exist`nExiting
ExitApp
}
if(!FileExist(icopath)){
msgbox, %icopath% does not exist`nExiting
ExitApp
}
; create multiple exes for running multiple instances
loop, 5 {
SplitPath, Exefilepath, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive
LoopExeFilepath = %OutDir%/%OutNameNoExt%-%A_index%.exe
run, %comspec% /c ""C:\Program Files\AutoHotkey\Compiler\Ahk2Exe.exe" /in "%AHKFilepath%" /out "%LoopExeFilepath%" /icon "%icopath%""
}
; OldNotify(ScriptToCompile,"Compiled Successfully",5)
; sleep, 5000
ExitApp
;---FUNCTIONS-----------------------------------------------------------------------

50
Lib/RunCMD.ahk Normal file
View File

@ -0,0 +1,50 @@
; PowerShell
; https://www.autohotkey.com/boards/viewtopic.php?p=341237#p341237
RunCMD(CmdLine, WorkingDir:="", Codepage:="CP0", Fn:="RunCMD_Output") { ; RunCMD v0.94
Local ; RunCMD v0.94 by SKAN on D34E/D37C @ autohotkey.com/boards/viewtopic.php?t=74647
Global A_Args ; Based on StdOutToVar.ahk by Sean @ autohotkey.com/board/topic/15455-stdouttovar
Fn := IsFunc(Fn) ? Func(Fn) : 0
, DllCall("CreatePipe", "PtrP",hPipeR:=0, "PtrP",hPipeW:=0, "Ptr",0, "Int",0)
, DllCall("SetHandleInformation", "Ptr",hPipeW, "Int",1, "Int",1)
, DllCall("SetNamedPipeHandleState","Ptr",hPipeR, "UIntP",PIPE_NOWAIT:=1, "Ptr",0, "Ptr",0)
, P8 := (A_PtrSize=8)
, VarSetCapacity(SI, P8 ? 104 : 68, 0) ; STARTUPINFO structure
, NumPut(P8 ? 104 : 68, SI) ; size of STARTUPINFO
, NumPut(STARTF_USESTDHANDLES:=0x100, SI, P8 ? 60 : 44,"UInt") ; dwFlags
, NumPut(hPipeW, SI, P8 ? 88 : 60) ; hStdOutput
, NumPut(hPipeW, SI, P8 ? 96 : 64) ; hStdError
, VarSetCapacity(PI, P8 ? 24 : 16) ; PROCESS_INFORMATION structure
If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "Int",0, "Int",True
,"Int",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1, "UInt"), "Int",0
,"Ptr",WorkingDir ? &WorkingDir : 0, "Ptr",&SI, "Ptr",&PI)
Return Format("{1:}", "", ErrorLevel := -1
,DllCall("CloseHandle", "Ptr",hPipeW), DllCall("CloseHandle", "Ptr",hPipeR))
DllCall("CloseHandle", "Ptr",hPipeW)
, A_Args.RunCMD := { "PID": NumGet(PI, P8? 16 : 8, "UInt") }
, File := FileOpen(hPipeR, "h", Codepage)
, LineNum := 1, sOutput := ""
While (A_Args.RunCMD.PID + DllCall("Sleep", "Int",0))
and DllCall("PeekNamedPipe", "Ptr",hPipeR, "Ptr",0, "Int",0, "Ptr",0, "Ptr",0, "Ptr",0)
While A_Args.RunCMD.PID and (Line := File.ReadLine())
sOutput .= Fn ? Fn.Call(Line, LineNum++) : Line
A_Args.RunCMD.PID := 0
, hProcess := NumGet(PI, 0)
, hThread := NumGet(PI, A_PtrSize)
, DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode:=0)
, DllCall("CloseHandle", "Ptr",hProcess)
, DllCall("CloseHandle", "Ptr",hThread)
, DllCall("CloseHandle", "Ptr",hPipeR)
, ErrorLevel := ExitCode
Return sOutput
}

0
Models/.gitignore vendored Normal file
View File

58
Pull-Updates-From-Git.ahk Normal file
View File

@ -0,0 +1,58 @@
; ENVIRONMENT
;------------------------------------------------
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn ; Enable warnings to assist with detecting common errors.
;DetectHiddenWindows, On
#SingleInstance, Force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;SetKeyDelay, 500
CoordMode, ToolTip, Screen
CoordMode, Mouse, Screen
;#NoTrayIcon
; Notes/Extra Info/#Includes
;------------------------------------------------
Menu, Tray, Icon, %A_ScriptDir%\Assets\Git.ico
; VARIABLES
;------------------------------------------------
; MAIN SCRIPT
;------------------------------------------------
process, close,Whisper-AHK.exe
status := RunCMD("git pull")
MsgBox 0x0, Git Pull Result, %status%
run, %A_ScriptDir%\Whisper-AHK.exe
ExitApp
; Functions
;------------------------------------------------
; Misc
;------------------------------------------------
; Escape::ExitApp

39
README.md Normal file
View File

@ -0,0 +1,39 @@
# Whisper-AHK
Autohotkey based GUI for utilizing [Whisper.cpp](https://github.com/ggerganov/whisper.cpp) to transcribe audio files to text.
## Features
- Transcribe Audio Files using your preferred Whisper AI model.
- Automatically convert audio files to the 16-bit .wav file that Whisper.cpp requires, using FFMPEG
- Currently ffmpeg has to be installed manually and be added to system PATH
- The Transcriber will create a folder named `WAVFiles` and `Transcriptions` within the same directory as the selected audio files, where the converted .wav files and resulting transcriptions will get exported to.
## How to Use
- Download and install [ffmpeg](https://ffmpeg.org/download.html)(or choco install -y ffmpeg)
- Download and install the [Microsoft Visual C++ Redistributable](https://www.microsoft.com/en-us/Download/confirmation.aspx?id=48145)
- Git clone the repo to your computer with `git clone URL`
- Download and extract the contents of `whisper-bin-x64.zip` to `\Whisper\` from https://github.com/ggerganov/whisper.cpp/releases
- Download and move the whisper model you want to use to `\Whisper\` from https://github.com/ggerganov/whisper.cpp/blob/master/models
- Run `Whisper-AHK` to start the GUI.
- To download updates to the scripts, close all running Transcribers and run the `Pull-Updates-From-Git.exe` (must have git installed)
## Settings:
- Keep CMD Open After Model Completion
- Will Keep the Whisper/ffmpeg CMD window open after it finishes the task instead of closing instantly, so you can see any possible errors.
- The Transcriber will not move on to the next file until you close the CMD window manually
- Show Tooltip of progress at top of screen
- Will show a small tooltip at the top of your screen of what the script is currently doing
- Number of CPU Threads
- The number of CPU threads you want to use for Transcribing.
- Minutes to Pause After Transcriptions
- This will pause the Transcriber for X minutes before moving on to the next Model/File so your CPU can cool down a bit.
- Useful if you're using 100% of your CPU threads and your computer fans are having a hard time keeping up
- Transcribe Individual Files
- Select all the files you want to transcribe individually.
- Transcribe All Audio Files within Folder
- Transcribe all MP3/WAV files within a directory
## Compiling to .exe from Source
1. [Install Autohotkey v1](https://www.autohotkey.com/download/)
2. `git clone` the project and then either run the `Compile Transcriber to EXE.ahk` autohotkey script to automatically compile, or start up the AHK compiler that comes installed with Autohotkey and select the `Whisper-AHK.ahk` and `\Assets\Elegantthemes-Beautiful-Flat-Speaker.ico` icon.

761
Whisper-AHK.ahk Normal file
View File

@ -0,0 +1,761 @@
; ENVIRONMENT
;------------------------------------------------
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn ; Enable warnings to assist with detecting common errors.
;DetectHiddenWindows, On
if(InStr(A_ScriptFullPath, ".ahk")){
#SingleInstance, Force
}
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;SetKeyDelay, 500
CoordMode, ToolTip, Screen
CoordMode, Mouse, Screen
;#NoTrayIcon
; Notes/Extra Info/#Includes
;------------------------------------------------
#Include, %A_scriptdir%\Lib\RunCMD.ahk
; #Include C:\Users\%A_Username%\Syncthing\Scripts\AutoHotKey\RadialMenu\My codes\My Global Variables.ahk
Menu, Tray, Icon, %A_scriptDir%\Assets\Elegantthemes-Beautiful-Flat-Speaker.ico
ScriptName = Whisper-AHK
ScriptVersion = V1.0
; VARIABLES
;------------------------------------------------
WhitelistedMediaFilesExtensions = mp3,wav,mp4
; Models
largeM_FP = %A_scriptdir%\Whisper\ggml-large-v1.bin
mediumM_FP = %A_scriptdir%\Whisper\ggml-medium.bin
baseM_FP = %A_scriptdir%\Whisper\ggml-base.en.bin
smallM_FP = %A_scriptdir%\Whisper\ggml-small.en.bin
tinyM_FP = %A_scriptdir%\Whisper\ggml-tiny.en.bin
; Number of processors
EnvGet, ProcessorCount, NUMBER_OF_PROCESSORS
; EnvGet, ProcessorCount, NUMBER_OF_PROCESSORS
IniRead, CPUThreads, Settings.ini, %ScriptName%, CPUThreads, %A_space%
IniRead, ShowTooltip, Settings.ini, %ScriptName%, ShowTooltip, %A_space%
IniRead, MinutesToPauseBetweenTranscriptions, Settings.ini, %ScriptName%, MinutesToPauseBetweenTranscriptions, 0
IniRead, SelectedDirectoryPath, Settings.ini, %ScriptName%, SelectedDirectoryPath, %A_space%
IniRead, TranscriptionModelsSelected, Settings.ini, %ScriptName%, TranscriptionModelsSelected, %A_space%
IniRead, TranscriptionLengthsSelected, Settings.ini, %ScriptName%, TranscriptionLengthsSelected, %A_space%
IniRead, NTFYURL, Settings.ini, %ScriptName%, NTFYURL, %A_space%
(NTFYURL)?(NTFYURLCheckStatus := 1):(NTFYURLCheckStatus := 0)
(WinExist("Podcast-Transcription-In-Progress"))?(ContinueAfterCMDCloseCheckStatus := 1):(ContinueAfterCMDCloseCheckStatus := 0)
; Msgbox % "ContinueAfterCMDCloseCheckStatus: " ContinueAfterCMDCloseCheckStatus
/*
Gui, Add, Checkbox,y+15 vTinyM, Tiny (75 MB Disk, ~125 MB RAM)
Gui, Add, Checkbox, vBaseM, Base (142 MB Disk, ~210 MB RAM)
Gui, Add, Checkbox, vSmallM, Small (466 MB Disk, ~600 MB RAM)
Gui, Add, Checkbox, vMediumM, Medium (1.5 GB Disk, ~1.7 GB RAM)
Gui, Add, Checkbox, vLargeM checked,Large (2.9 GB Disk, ~3.3 GB RAM)
Gui, Add, Checkbox, vAllMQualities, ALL (One by One)
*/
(instr(TranscriptionModelsSelected,"Tiny"))?(TinyM := 1):(TinyM := 0)
(instr(TranscriptionModelsSelected,"Base"))?(BaseM := 1):(BaseM := 0)
(instr(TranscriptionModelsSelected,"Small"))?(SmallM := 1):(SmallM := 0)
(instr(TranscriptionModelsSelected,"Medium"))?(MediumM := 1):(MediumM := 0)
(instr(TranscriptionModelsSelected,"Large"))?(LargeM := 1):(LargeM := 0)
(instr(TranscriptionLengthsSelected,"Short"))?(ShortPodcastsCheckStatus := 1):(ShortPodcastsCheckStatus := 0)
(instr(TranscriptionLengthsSelected,"Medium"))?(MediumPodcastsCheckStatus := 1):(MediumPodcastsCheckStatus := 0)
(instr(TranscriptionLengthsSelected,"Long"))?(LongPodcastsCheckStatus := 1):(LongPodcastsCheckStatus := 0)
; Msgbox % "ShortPodcastsCheckStatus: " ShortPodcastsCheckStatus
global AudioFilesDIR
global ShowTooltip
global ErrorLogText
TranscriptionModels := [] ; Create an array
TranscriptionModelPaths := [] ; Create an array
TranscriptionModelGPUNames := [] ; Create an array
; -------------------------------GUI Variables-------------------------------
GUIMargin := 5
GUIRowTwoXPos := 300
GUIRowTwoVerticalLineXPos := GUIRowTwoXPos - 10
GUIRowThreeXPos := 550
GUIRowThreeVerticalLineXPos := GUIRowThreeXPos - 10
GUIButtonWidths := 50
GUIEditBoxWidth := GUIRowTwoXPos - (GUIMargin * 4)
GuiWidth := 800
GuiStartButtonXPos := GUIRowTwoXPos + %GUIMargin%
GUISelectButtonWidths := 70
TranscribeButtonWidth := GuiWidth - GUIRowThreeXPos - (GUIMargin * 2)
; Msgbox % "TranscribeButtonWidth: " TranscribeButtonWidth
; MAIN SCRIPT
;------------------------------------------------
Gui, font, Bold
; Gui, Add, Text,x%GUIMargin% y%GUIMargin% w%GUIRowTwoXPos% center, Transcription Settings
Gui, font, normal
; Gui, Add, Text, , Number of CPU Threads ; `nTotal Processors on PC: %ProcessorCount%
Gui, Add, Text, x%GUIMargin% y+%GUIMargin% w%GUIEditBoxWidth% center, Number of CPU Threads (PC MAX: %ProcessorCount%) ; `nTotal Processors on PC: %ProcessorCount%
Gui, Add, Edit, gUpdateGUI w%GUIEditBoxWidth%,
Gui, Add, UpDown, vCPUThreads Range1-20, %CPUThreads%
Gui, Add, Text, x%GUIMargin% y+15 w%GUIEditBoxWidth% center, Minutes to Pause After M/L Models ; `nTotal Processors on PC: %ProcessorCount%
Gui, Add, Edit, gUpdateGUI w%GUIEditBoxWidth%,
Gui, Add, UpDown, vMinutesToPauseBetweenTranscriptions Range0-20, %MinutesToPauseBetweenTranscriptions%
; Gui, Add, Text
; Gui, font, Bold
Gui, Add, Text,x%GUIMargin% y+15 w%GUIEditBoxWidth% center, Transcribe Individual File(s):
; Gui, font, normal
Gui, Add, Edit, vFilesFilepath gUpdateGUI w%GUIEditBoxWidth%
Gui, Add, Button, y+1 gSelectFile w%GUIEditBoxWidth%, Select
; Gui, font, Bold
; Gui, Add, Text, cRed center w200 x%GUIMargin%, OR
Gui, Add, Text,x%GUIMargin% y+15 w%GUIEditBoxWidth% center, Transcribe All Audio Files within Folder:
Gui, Add, Edit, vSelectedDirectoryPath gUpdateGUI w%GUIEditBoxWidth%, %SelectedDirectoryPath%
Gui, Add, Button, y+1 w%GUIEditBoxWidth% gSelectDirectory , Select
gui, add, text, y%GUIMargin% x%GUIRowTwoVerticalLineXPos% 0x11 h270 ; 0x11 is a "line" ; refer to here: https://autohotkey.com/board/topic/50910-draw-line-gui/
Gui, font, Bold
Gui, Add, Text,x%GUIRowTwoXPos% y%GUIMargin% w200 center,Transcription Model
Gui, font, normal ; , Param2, Param3, Param4]
; Gui, Add, Radio
Gui, Add, Checkbox,y+%GUImargin% vTinyM checked%TinyM% , Tiny (75 MB Disk, ~125 MB RAM)
Gui, Add, Checkbox, vBaseM checked%BaseM%, Base (142 MB Disk, ~210 MB RAM)
Gui, Add, Checkbox, vSmallM checked%SmallM%, Small (466 MB Disk, ~600 MB RAM)
Gui, Add, Checkbox, vMediumM checked%MediumM%, Medium (1.5 GB Disk, ~1.7 GB RAM)
Gui, Add, Checkbox, vLargeM checked%LargeM% ,Large (2.9 GB Disk, ~3.3 GB RAM)
; Gui, Add, Checkbox, vAllMQualities checked%AllMQualities%, ALL (One by One)
Gui, Font, Bold
Gui, Add, Text,x%GUIRowTwoXPos% y+15 w200 center,Length of Podcasts to Transcribe
Gui, font, normal
Gui, Add, Checkbox,y+%GUIMargin% gUpdateGUI vShortPodcasts checked%ShortPodcastsCheckStatus%, Short ( < 30 Mins)
Gui, Add, Checkbox, vMediumPodcasts gUpdateGUI checked%MediumPodcastsCheckStatus%, Medium (30-60 Mins)
Gui, Add, Checkbox, vLongPodcasts gUpdateGUI checked%LongPodcastsCheckStatus%, Long ( > 60 Mins)
; Gui, Add, Text
Gui, Font, Bold
Gui, Add, Text,x%GUIRowTwoXPos% y+15 w200 center,Other Settings
Gui, font, normal
Gui, Add, Checkbox, vKeepCMD, Keep CMD Open After Model Completion
Gui, Add, Checkbox, vShowTooltip checked%ShowTooltip%, Show Tooltip of Progress at Top of Screen
Gui, Add, Checkbox, vNTFY checked%NTFYURLCheckStatus%, NTFY After Each Transcription
Gui, Add, Checkbox, vContinueAfterCMDClose checked%ContinueAfterCMDCloseCheckStatus%, Start After Current Running Transcription Ends
gui, add, text, y%GUIMargin% x%GUIRowThreeVerticalLineXPos% 0x11 h270 ; 0x11 is a "line" ; refer to here: https://autohotkey.com/board/topic/50910-draw-line-gui/
Gui, font, Bold
gui, font, s12
Gui, Add, text,y%GUIMargin% w%TranscribeButtonWidth% x%GUIRowThreeXPos% h20 Center, Status Log
gui, font, normal
gui, font, s7
Gui, Add, Edit, y+%GUIMargin% w%TranscribeButtonWidth% x%GUIRowThreeXPos% h200 vStatusLog
Gui, font, Bold
Gui, Font, s12
Gui, Add, Button, y+20 x%GUIRowThreeXPos% w%TranscribeButtonWidth% h40 gSubmit Center, Transcribe
gui, font, normal
Gui, Font, s9
Gui, Add, Button, y+%GUIMargin% x%GUIRowThreeXPos% w%TranscribeButtonWidth% h15 gReloadScript Center, Restart
Gui, Font, s5
Gui, Add, StatusBar,Center,This Node: Minutes Transcribed by Node: Total Minutes Transcribed by All Nodes: Total Minutes of All Podcasts: || Everyone: Podcasts Transcribed
gui, show, w%GuiWidth%, %ScriptName% %ScriptVersion%
Return
UpdateGUI:
Gui, Submit, NoHide ; , Param2, Param3, Param4]
; msgbox % SelectedDirectoryPath
Return
SelectFile:
if(SelectedDirectoryPath){
Msgbox, Your already have a directory selected. `nThis script can only handle one or the other at the moment.
return
}
FileSelectFile, SelectedFiles, M3 ; M3 = Multiselect existing files.
if (SelectedFiles = "")
return
GUIFilesText := StrReplace(SelectedFiles, "`n", "|")
GuiControl, Text,FilesFilepath, %GUIFilesText%
return
SelectDirectory:
if(SelectedFiles){
Msgbox, Your already have individual files selected. `nThis script can only handle one or the other at the moment.
return
}
; have user select a file within the directory they want transcribed.
; Will later get the directory name from this file
FileSelectFile, SelectedDirectoryPath
if (SelectedDirectoryPath = "")
return
GuiControl,Text,SelectedDirectoryPath, %SelectedDirectoryPath%
return
GuiClose:
ExitApp
ReloadScript:
Reload
ExitApp
Submit:
gui, Submit, NoHide
if(NTFY){
IniRead, NTFYURL, Settings.ini, %ScriptName%, NTFYURL, %A_space%
; Msgbox % "NTFYURL: " NTFYURL
if(!NTFYURL){
InputBox, NTFYURL, Input NTFY URL, Please input NTFY url for notifications.`nGenerate a URL at: https://ntfy.sh/app
if(ErrorLevel){
NTFY := 0
}
else, { ; save url to settings.ini
IniWrite, %NTFYURL%, Settings.ini, %ScriptName%, NTFYURL
}
}
}
IniWrite, %CPUThreads%, Settings.ini, %ScriptName%, CPUThreads
IniWrite, %ShowTooltip%, Settings.ini, %ScriptName%, ShowTooltip
IniWrite, %MinutesToPauseBetweenTranscriptions%, Settings.ini, %ScriptName%, MinutesToPauseBetweenTranscriptions
; IniWrite, %ContinueAfterCMDClose%, Settings.ini, %A_ScriptName%, ContinueAfterCMDClose
if(SelectedDirectoryPath){
IniWrite, %SelectedDirectoryPath%, Settings.ini, %ScriptName%, SelectedDirectoryPath
}
else, {
IniWrite, %A_space%, Settings.ini, %ScriptName%, SelectedDirectoryPath
}
if(!SelectedFiles AND !SelectedDirectoryPath){
msgbox, Please select individual files or a directory that you want Transcribed.
return
}
Status := RunCMD("ffmpeg")
; Msgbox % "Status: " Status
if(!InStr(Status, "ffmpeg version")){
MsgBox, Error:, FFMPEG was not found in System PATH.`nPlease install it and add it to System PATH to automatically convert files to the Whisper.cpp required 16-bit WAV file
return
}
Message = Creating Required Variables
ShowTooltipText(Message)
; if files selected, add them all to array
if(SelectedFiles){
SelectedAudioFilesArray := [] ; Create array
; loop through all selected files and add them to the array
Loop, parse, SelectedFiles, `n
{
if (A_Index = 1){
AudioFilesDIR = %A_LoopField%
; MsgBox, The selected files are all contained in %A_LoopField%.
}
else
{
AudioFileFP = %AudioFilesDIR%\%A_LoopField%
SelectedAudioFilesArray.Push(AudioFileFP) ; Append an item to the array
; SelectedAudioFilesVAR .= AudioFileFP . ","
}
}
}
; if directory selected, loop through all files and add them to the array
if(SelectedDirectoryPath){
SplitPath, SelectedDirectoryPath, OutFileName, AudioFilesDIR, OutExtension, OutNameNoExt, OutDrive
; msgbox, adding files in directory to var
SelectedAudioFilesArray := [] ; Create array
Text = Creating Array of Whitelisted Files (%WhitelistedMediaFilesExtensions%) `nin Directory: %AudioFilesDIR%
ShowTooltipText(Text)
PrePendToErrorLogText(text)
Loop, files, %AudioFilesDIR%\*.*, F
{
SplitPath, A_LoopFileFullPath, FileNameWExt, FileDir, FileExt, FileNameNoExt,
if(InStr(WhitelistedMediaFilesExtensions, FileExt)){
SelectedAudioFilesArray.Push(A_LoopFileFullPath)
}
}
}
; If directory selected, add all files to array
; Msgbox % "AudioFilesDIR: " AudioFilesDIR
; KeepCMD := 0
OverwritePreviousTranscriptions := 0
if(KeepCMD){
KeepCMD := "K"
}
else, {
KeepCMD := "C"
}
; clear variable from GUI
TranscriptionModelsSelected :=
; push to array each quality selected
if(TinyM Or AllMQualities){
TranscriptionModels.Push("Tiny") ; Append an item to the array
TranscriptionModelPaths.Push(tinyM_FP) ; Append an item to the array
TranscriptionModelsSelected .= "Tiny|"
}
if(SmallM Or AllMQualities){
TranscriptionModels.Push("Small") ; Append an item to the array
TranscriptionModelPaths.Push(smallM_FP) ; Append an item to the array
TranscriptionModelsSelected .= "Small|"
}
if(BaseM Or AllMQualities){
TranscriptionModels.Push("Base") ; Append an item to the array
TranscriptionModelPaths.Push(baseM_FP) ; Append an item to the array
TranscriptionModelsSelected .= "Base|"
}
if(MediumM Or AllMQualities){
TranscriptionModels.Push("Medium") ; Append an item to the array
TranscriptionModelPaths.Push(mediumM_FP) ; Append an item to the array
TranscriptionModelsSelected .= "Medium|"
}
if(LargeM Or AllMQualities){
TranscriptionModels.Push("Large") ; Append an item to the array
TranscriptionModelPaths.Push(largeM_FP) ; Append an item to the array
TranscriptionModelsSelected .= "Large|"
}
if(TranscriptionModelsSelected = ""){
ToolTip
Text = Please Select at Least ONE Model to Transcribe With
msgbox, %Text%
return
}
; save selected models to ini files
IniWrite, %TranscriptionModelsSelected%, Settings.ini, %ScriptName%, TranscriptionModelsSelected
TranscriptionLengthsSelected :=
(ShortPodcasts)?(TranscriptionLengthsSelected .= "Short|"):("")
(MediumPodcasts)?(TranscriptionLengthsSelected .= "Medium|"):("")
(LongPodcasts)?(TranscriptionLengthsSelected .= "Long|"):("")
if(TranscriptionLengthsSelected = ""){
ToolTip
Text = Please Select the Audio Length you'd like to Transcribe
msgbox, %Text%
return
}
IniWrite, %TranscriptionLengthsSelected%, Settings.ini, %ScriptName%, TranscriptionLengthsSelected
; msgbox
text = Creating Required Directories
ShowTooltipText(Text)
FileCreateDir, %AudioFilesDIR%\Transcriptions
FileCreateDir, %AudioFilesDIR%\WAVFiles
text = Starting Transcription
ShowTooltipText(Text)
PrePendToErrorLogText(text)
; loop through the array and transcribe using options selected
; Msgbox % TranscriptionModels.Length() ; Display total number of items in the array
; ArrayLenght := TranscriptionModels.Length() ; Save total number of items in the array
if(ContinueAfterCMDClose and WinExist("Podcast-Transcription-In-Progress")){
; msgbox, cmd found.
Text = Waiting for Current Running Transcription to Finish in CMD
ShowTooltipText(Text)
PrePendToErrorLogText(text)
WinWaitClose, ahk_class ConsoleWindowClass ;, WinText, Seconds [, ExcludeTitle, ExcludeText]
; msgbox, cmd closed
}
; loop for each selected audio file
loop % SelectedAudioFilesArray.Length() {
Filepath := SelectedAudioFilesArray[A_Index]
OriginalFilepath := SelectedAudioFilesArray[A_Index]
SplitPath, Filepath, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive
; Convert the file to 16-bit WAV file as required by whisper.cpp
WavFilepath = %AudioFilesDIR%\WAVFiles\%OutNameNoExt%.wav
; loop through each selected transcription model
Loop % TranscriptionModels.Length() {
ModelName := TranscriptionModels[A_Index]
ModelPath := TranscriptionModelPaths[A_Index]
; create filepaths where outputs will be saved to
OutputPath = %AudioFilesDIR%\Transcriptions\%OutNameNoExt%_%ModelName%
OutputModelTxtFile = %AudioFilesDIR%\Transcriptions\%OutNameNoExt%_%ModelName%.txt
OutputTxtFP = %OutputPath%.txt
LogFileFP = %OutputPath%.log
Text = Checking for Previous Transcription
ShowTooltipText(Text)
; If .txt Transcription file exists, move on to next model
if(FileExist(OutputModelTxtFile)){
Message :="Skipping " . OutFileName . " - already transcribed with " . ModelName . " Model"
PrePendToErrorLogText(Message)
Continue
}
; otherwise check if log file exists from a previous run, or current run on different node (if using shared folder)
if(FileExist(LogFileFP)){
FileGetTime, LogFileFPModificationTime, %LogFileFP%, M ;
; EnvSub, Var, Value [, TimeUnits]
EnvSub, LogFileFPModificationTime, A_Now, S ; get hours SINCE last modified
; Check if log file was last added to more than 24 hours ago
; No podcast transcription should take more than that, and it means that a node started, but never finished it
LogFileFPModificationTime := (LogFileFPModificationTime * -1 )
; Msgbox % "LogFileFPModificationTime: " LogFileFPModificationTime
if((LogFileFPModificationTime < 86400)){
text = Skipping %OutFileName% with Model:%ModelName% - Currently being Transcribed by a different node.
PrePendToErrorLogText(text)
ShowTooltipText(Text)
; sleep, 1000
Continue
}
}
; get information about audio file
Obj := Filexpro(Filepath,,
, "Length"
, "Size" )
AudioLength := obj["Length"]
AudioLengthArray := StrSplit(AudioLength,":")
TotalTimeInSeconds := ((AudioLengthArray[1] * 60 ) * 60) + (AudioLengthArray[2] * 60) + AudioLengthArray[3]
if(ShortPodcasts){
if(TotalTimeInSeconds > 1860){ ; greater than 31 minutes
Text = Podcast is longer than 30 minutes. Skipping
ShowTooltipText(Text)
PrePendToErrorLogText(text)
; msgbox, skipping medium/Long podcast
Continue
}
}
if(MediumPodcasts){ ; if less than 31 minutes or greater than 61 minutes
if(TotalTimeInSeconds < 1860 OR TotalTimeInSeconds > 3660){
Text = Podcast is either shorter than 30 minutes or longer than 60 minutes. Skipping
ShowTooltipText(Text)
PrePendToErrorLogText(text)
Continue
}
}
if(LongPodcasts){
if(TotalTimeInSeconds < 3660){
Text = Podcast is shorter than 60 minutes Skipping
ShowTooltipText(Text)
PrePendToErrorLogText(text)
; msgbox, skipping short/medium podcast
Continue
}
}
if(FileExist(WavFilepath)){ ; re-use previously converted wav file if it exists
Filepath := WavFilepath
}else, {
text = Converting File: %OutFileName% To 16-bit WAV file
ShowTooltipText(Text)
PrePendToErrorLogText(text)
runwait, %ComSpec% /%KeepCMD% ffmpeg -i "%Filepath%" -ar 16000 -ac 1 -c:a pcm_s16le "%WavFilepath%"
}
; msgbox, checking filepath
if(!FileExist(WavFilepath)){
Message = WAV file not found at:`n%WavFilepath%`nConversion failed for some reason.`nPlease select the "Keep CMD Open" checkbox and run again to see the error.`nClick OK to exit.
PrePendToErrorLogText(text)
Continue
}
FormatTime, TodayDate , YYYYMMDDHH24MISS,hh:mm
text = Transcription in Progress`nModel: %ModelName% CPU Threads: %CPUThreads% Length: %AudioLength%`nFile: %OutNameNoExt%`nStart Time: %TodayDate%
LogToTextFile(text, LogFileFP)
PrePendToErrorLogText(text)
ShowTooltipText(Text)
; msgbox
UStartTime := A_TickCount ; start time
runwait, %ComSpec% /%KeepCMD% title Podcast-Transcription-In-Progress & %A_scriptdir%\Whisper\main.exe -m %ModelPath% -f "%WavFilepath%" -t %CPUThreads% -otxt -ovtt -osrt -owts -ocsv -of "%OutputPath%"
URunTime := round(((A_TickCount - UStartTime) / 1000), 2) ; end time
Message = Time to Transcribe: %URunTime% seconds
LogToTextFile(Message, LogFileFP)
; get time it took to transcribe in seconds
TranscriptionLength := round(((A_TickCount - UStartTime) / 1000), 2)
; if more than 1 hour, convert time to hours:minutes for NTFY message
(TranscriptionLength > 3600)?(NTFYTranscriptionTime := round((TranscriptionLength / 3600),2) . " Hours"):(NTFYTranscriptionTime := TranscriptionLength . " Seconds")
SecondsToTranscribe1Sec := round((TranscriptionLength / TotalTimeInSeconds), 2)
; TotalTimeInSeconds
text = Transcription of %WavFilepath% took a total of %TranscriptionLength% Seconds
LogToTextFile(text, LogFileFP)
PrePendToErrorLogText(text)
if(NTFY){
Message = Transcription Complete `nNode: %A_ComputerName% `nFile: %OutNameNoExt% `nAudio Length: %AudioLength%`nModel: %ModelName%`nCPU Threads: %CPUThreads% `nTTTS: %NTFYTranscriptionTime%`nTTS 1 (s): %SecondsToTranscribe1Sec% Seconds
SendMessagetoNTFY(Message, NTFYURL)
}
}
; / All transcriptions have been looped through
; take a short rest so CPU has time to cool down
; IF the last model tool longer than 10 seconds to complete (AKA not skipped over)
if(MinutesToPauseBetweenTranscriptions AND TranscriptionLength > 1000){
if(ModelName = "Medium" OR ModelName="Large"){
text = Waiting for %MinutesToPauseBetweenTranscriptions% Minutes before moving on to next item
ShowTooltipText(Text)
PrePendToErrorLogText(text)
MilisecondsToSleep := MinutesToPauseBetweenTranscriptions * 60000
sleep, %MilisecondsToSleep%
}
; reset timer for next loop
TranscriptionLength :=
}
}
ToolTip
if(NTFY){
Message = Node: %A_ComputerName% Has Completed Transcribing ALL Selected Files! ;`nFile: %OutNameNoExt% `nModel: %ModelName%`nCPU Threads: %CPUThreads% `nLength: %AudioLength%`nTime: %TranscriptionLength% Seconds
SendMessagetoNTFY(Message, NTFYURL)
}
msgbox, All Transcriptions have been completed.
return
; Functions
;------------------------------------------------
LogToTextFile(Text, Filepath){
; ErrorLoggingFile := Filepath
FileAppend, %Text%`n`n, %Filepath%
}
ShowTooltipText(Text){
if(ShowTooltip){
TooltipFirstLine := StrSplit(Text, "`n")
TooltipFirstLine := TooltipFirstLine[1]
ToolTipLen := StrLen(TooltipFirstLine)
TooltipXPos := A_ScreenWidth / 2 - ((ToolTipLen * 9) / 2)
; Msgbox % "TooltipXPos: " TooltipXPos
ToolTip, %Text%, %TooltipXPos%, 0
}
}
PrePendToErrorLogText(Text){
ErrorLogText := Text "`n`n" . ErrorLogText
GuiControl, Text,StatusLog, %ErrorLogText%
}
SendMessagetoNTFY(Message, URL){
command = powershell (Invoke-RestMethod -Method 'Post' -Uri %URL% -Body '%Message%' -UseBasicParsing)
Status := RunCMD(Command)
; Msgbox % "Status: " Status
}
; -------------------------------FileXPro Get File Attributes-------------------------------
;https://www.autohotkey.com/boards/viewtopic.php?t=59882
Filexpro( sFile := "", Kind := "", P* ) { ; v.90 By SKAN on D1CC @ goo.gl/jyXFo9
Local
Static xDetails
If ( sFile = "" )
{ ; Deinit static variable
xDetails := ""
Return
}
fex := {}, _FileExt := ""
Loop, Files, % RTrim(sfile,"\*/."), DF
{
If not FileExist( sFile:=A_LoopFileLongPath )
{
Return
}
SplitPath, sFile, _FileExt, _Dir, _Ext, _File, _Drv
If ( p[p.length()] = "xInfo" ) ; Last parameter is xInfo
{
p.Pop() ; Delete parameter
fex.SetCapacity(11) ; Make room for Extra info
fex["_Attrib"] := A_LoopFileAttrib
fex["_Dir"] := _Dir
fex["_Drv"] := _Drv
fex["_Ext"] := _Ext
fex["_File"] := _File
fex["_File.Ext"] := _FileExt
fex["_FilePath"] := sFile
fex["_FileSize"] := A_LoopFileSize
fex["_FileTimeA"] := A_LoopFileTimeAccessed
fex["_FileTimeC"] := A_LoopFileTimeCreated
fex["_FileTimeM"] := A_LoopFileTimeModified
}
Break
}
If Not ( _FileExt ) ; Filepath not resolved
{
Return
}
objShl := ComObjCreate("Shell.Application")
objDir := objShl.NameSpace(_Dir)
objItm := objDir.ParseName(_FileExt)
If ( VarSetCapacity(xDetails) = 0 ) ; Init static variable
{
i:=-1, xDetails:={}, xDetails.SetCapacity(309)
While ( i++ < 309 )
{
xDetails[ objDir.GetDetailsOf(0,i) ] := i
}
xDetails.Delete("")
}
If ( Kind and Kind <> objDir.GetDetailsOf(objItm,11) ) ; File isn't desired kind
{
Return
}
i:=0, nParams:=p.Count(), fex.SetCapacity(nParams + 11)
While ( i++ < nParams )
{
Prop := p[i]
If ( (Dot:=InStr(Prop,".")) and (Prop:=(Dot=1 ? "System":"") . Prop) )
{
fex[Prop] := objItm.ExtendedProperty(Prop)
Continue
}
If ( PropNum := xDetails[Prop] ) > -1
{
fex[Prop] := ObjDir.GetDetailsOf(objItm,PropNum)
Continue
}
}
fex.SetCapacity(-1)
Return fex
} ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Misc
;------------------------------------------------
; Escape::ExitApp