我知道您可以像这样使用 SoundPlay 播放声音文件:
q:: SoundPlay, C:\Users\User\Desktop\testing\Ding Sound Effect.mp3
但是你能做一个记录系统音频的功能吗?
我正在尝试制作一个持续记录系统音频的功能,当我像 num9 一样按 smth 时,它会保存最后 10 或 5 秒并使用 "SoundPlay" 播放。我只是想知道这是否可能是因为我搜索并找到了与我正在寻找的东西无关的东西!
- 我尝试过的:当你用谷歌搜索解决方案时,你会发现这篇 2006-2010 年的旧帖子
https://autohotkey.com/board/topic/49559-recording-audio-seven-ways-in-ahk-6-ways-even-work/
我尝试了作者说它有效的每一个......对我没有任何效果。
大胆的代码一直给我错误:“Audacity.exe!
n
n请确保 Audacity.exe 位于”即使我安装并打开了 Audacity!在SndRec32.exe方法中...因为您需要从网站将SndRec32.exe安装到wind10...很难找到没有病毒的文件...即使我找到一个并复制并粘贴它到 system32 (正如作者建议的那样),保存时我看不到文件,并且当 ahk 脚本午餐时,您也需要处理出现的弹出窗口!
SoundRecorder.exe 方法需要你有wind 7或vista ...我正在使用win10
SoX 方法:我安装了 sox 并运行了脚本,但它给了我错误“找不到 sox!请确保 sox.exe 位于:。”是的,它说位于(。)
MCI方法:它不起作用,但它是迄今为止最好的......它显示了gui并显示了录制动画,但是当谈到保存文件时,它给了你命名文件的选项和选择位置,但它没有保存文件!正如作者提到的那样,这和录音机方法的最佳之处在于(它们允许 AHK 控制录音机,即使它是“隐藏的”,即运行但在屏幕上不可见)
- 正如作者所说,FMOD.DLL 和 BASS.DLL 方法仍在进行中……所以它们不起作用!
如果我做错了什么,请告诉我,我可能做错了什么。如果你也测试了这些方法,我真的会很高兴,我仍然会尝试重新阅读代码,我会尝试让大胆或 MCI 方法发挥作用,因为它们已经取得了最好的结果!
我试图理解 MCI 代码,但显然保存部分是什么把一切都搞砸了,我只是不知道它到底是什么......
顺便说一句,这是我从网站上使用的代码:
Gui 文件 MCI Gui.ahk (我不得不将它削减到未注释的部分.. 请参考上面的网站链接以获取原始代码)
#Persistent
#SingleInstance FORCE
#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance, ignore
DetectHiddenWindows, On
SetTitleMatchMode, 2
#Include MCI.AHK
hMedia:=MCI_Open("new","","type waveaudio")
SetTimer showRecording,350
SetTimer showRecording,Off
Recording = 0
Step = 0
gui Margin,0,0
gui -MinimizeBox
gui Add,Button, w220 gRecord, Record/Pause
gui Add,Button, wp hp gExit, Exit (Save as .WAV)
Gui, Add, StatusBar,, Ready
gui, Show,,MCI
Return
Record:
if (Recording = 0) {
Recording = 1
status := MCI_Record(hMedia)
SetTimer showRecording,On
gosub, showRecording
} else {
Recording = 0
status := MCI_Pause(hMedia)
SetTimer showRecording,Off
SB_SetText(" Paused")
}
return
showRecording:
Step ++
if (Step = 1)
SB_SetText("Recording")
else if (Step = 2)
SB_SetText(" Recording")
else {
SB_SetText(" Recording")
Step = 0
}
return
ESC::
Exit:
GUIClose:
MCI_Stop(hMedia)
SetTimer showRecording,Off
SB_SetText(" Saving")
FileSelectFile, SavePath, S8, .wav,,*.wav
MCI_Save(hMedia,SavePath)
SB_SetText(" Saved")
SB_SetText(" Closing")
MCI_Stop(hMedia)
MCI_Close(hMedia)
ExitApp
return
和主文件 MCI.AHK (我不得不将它削减到未注释的部分.. 请参考上面的网站链接以获取原始代码)
MCI_Open(p_MediaFile,p_Alias="",p_Flags="")
{
Static s_Seq=0
;[==============]
;[ Parameters ]
;[==============]
;-- p_MediaFile
if p_MediaFile<>new
{
;-- Media file exist?
IfNotExist %p_MediaFile%
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: The media file can't be
found. Return=0
)
return false
}
;-- "Type" flag not defined?
if InStr(A_Space . p_Flags . A_Space," type ")=0
{
;-- Registered file extension?
SplitPath p_MediaFile,,,l_Extension
;-- Which OS type?
if A_OSType=WIN32_NT ;-- Windows NT4/2000/XP/2003/Vista
RegRead
,l_Dummy
,HKEY_LOCAL_MACHINE
,SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions
,%l_Extension%
else
{
;-- Windows 95/98/ME
iniRead
,l_Value
,%A_WinDir%\win.ini
,MCI Extensions
,%l_Extension%
if l_Value=ERROR
ErrorLevel=1
}
;-- Not found?
if ErrorLevel
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: The file extension for this media
file is not registered as a valid MCI extension. Return=0
)
return false
}
}
;-- Enclose in DQ
p_MediaFile="%p_MediaFile%"
}
;-- Alias
if p_Alias is Space
{
s_Seq++
p_Alias=MCIFile%s_Seq%
}
;[===============]
;[ Open device ]
;[===============]
l_CmdString=open %p_MediaFile% alias %p_Alias% %p_Flags% wait
l_Return:=MCI_SendString(l_CmdString,Dummy)
if l_Return
l_Return:=0
else
l_Return:=p_Alias
;-- Set time format to milliseconds
if l_Return
{
l_CmdString=set %p_Alias% time format milliseconds wait
MCI_SendString(l_CmdString,Dummy)
}
;-- Return to sender
return l_Return
}
MCI_OpenCDAudio(p_Drive="",p_Alias="",p_CheckForMedia=true)
{
Static s_Seq=0
;-- Parameters
p_Drive=%p_Drive% ;-- Autotrim
p_Drive:=SubStr(p_Drive,1,1)
if p_Drive is not Alpha
p_Drive:=""
;-- Drive not specified
if p_Drive is Space
{
;-- Collect list of CDROM drives
DriveGet l_ListOfCDROMDrives,List,CDROM
if l_ListOfCDROMDrives is Space
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: This PC does not have functioning CDROM
drive. Return=0
)
return false
}
;-- Assign the first CDROM drive
p_Drive:=SubStr(l_ListOfCDROMDrives,1,1)
}
;-- Is this a CDROM drive?
DriveGet l_DriveType,Type,%p_Drive%:
if l_DriveType<>CDROM
{
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: The specified drive (%p_Drive%:) is not
a CDROM drive. Return=0
)
return false
}
;-- Alias
if p_Alias is Space
{
s_Seq++
p_Alias=MCICDAudio%s_Seq%
}
;-- Open device
l_CmdString=open %p_Drive%: alias %p_Alias% type cdaudio shareable wait
l_Return:=MCI_SendString(l_CmdString,Dummy)
if l_Return
l_Return:=0
else
l_Return:=p_Alias
;-- Device is open
if l_Return
{
;-- Set time format to milliseconds
l_CmdString=set %p_Alias% time format milliseconds wait
MCI_SendString(l_CmdString,Dummy)
;-- Check for media?
if p_CheckForMedia
{
if not MCI_MediaIsPresent(p_Alias)
{
MCI_Close(p_Alias)
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: Media is not present in the
specified drive (%p_Drive%:). Return=0
)
return false
}
;-- 1st track an audio track?
if not MCI_TrackIsAudio(p_Alias,1)
{
MCI_Close(p_Alias)
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: Media in drive %p_Drive%: does not
contain CD Audio tracks. Return=0
)
return false
}
}
}
return l_Return
}
MCI_Close(p_lpszDeviceID)
{
Static MM_MCINOTIFY:=0x03B9
;-- Close device
l_Return:=MCI_SendString("close " . p_lpszDeviceID . " wait",Dummy)
;-- Turn off monitoring of MM_MCINOTIFY message?
if OnMessage(MM_MCINOTIFY)="MCI_Notify"
{
;-- Don't proceed unless all MCI devices are closed
MCI_SendString("sysinfo all quantity open",l_OpenMCIDevices)
if l_OpenMCIDevices=0
{
;-- Disable monitoring
OnMessage(MM_MCINOTIFY,"")
}
}
return l_Return
}
MCI_Play(p_lpszDeviceID,p_Flags="",p_Callback="",p_hwndCallback=0)
{
Static MM_MCINOTIFY:=0x03B9
;-- Build command string
l_CmdString:="play " . p_lpszDeviceID
if p_Flags
l_CmdString:=l_CmdString . A_Space . p_Flags
;-- Notify
p_Callback=%p_Callback% ;-- AutoTrim
if StrLen(p_Callback)
{
l_CmdString:=l_CmdString . " notify"
;-- Attach p_Callback to MCI_Notify function
MCI_Notify(p_Callback,"","","")
;-- Monitor for MM_MCINOTIFY message
OnMessage(MM_MCINOTIFY,"MCI_Notify")
;-- Note: If the MM_MCINOTIFY message was monitored elsewhere,
; this statement will override it.
}
;-- Callback handle
if not p_hwndCallback
{
if InStr(A_Space . l_CmdString . A_Space," notify ")
or StrLen(p_Callback)
{
l_DetectHiddenWindows:=A_DetectHiddenWindows
DetectHiddenWindows On
Process Exist
p_hwndCallback:=WinExist("ahk_pid " . ErrorLevel . " ahk_class AutoHotkey")
DetectHiddenWindows %l_DetectHiddenWindows%
}
}
;-- Send it!
l_return:=MCI_SendString(l_CmdString,Dummy,p_hwndCallback)
return l_Return
}
MCI_Notify(wParam,lParam,msg,hWnd)
{
;;;;; Critical
;-- This will cause MM_MCINOTIFY messages to be buffered rather than
; discared if this function is still running when another MM_MCINOTIFY
; message is sent.
Static s_Callback
;-- Internal call?
if lParam is Space
{
s_Callback:=wParam
return
}
;-- Call developer function
if s_Callback is not Space
%s_Callback%(wParam)
return 0
}
MCI_Stop(p_lpszDeviceID)
{
l_Return:=MCI_SendString("stop " . p_lpszDeviceID . " wait",Dummy)
return l_Return
}
MCI_Pause(p_lpszDeviceID)
{
l_Return:=MCI_SendString("pause " . p_lpszDeviceID . " wait",Dummy)
return l_Return
}
MCI_Resume(p_lpszDeviceID)
{
l_Return:=MCI_SendString("resume " . p_lpszDeviceID . " wait",Dummy)
return l_Return
}
MCI_Record(p_lpszDeviceID,p_Flags="")
{
l_CmdString=record %p_lpszDeviceID% %p_Flags%
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_Return
}
MCI_Save(p_lpszDeviceID,p_FileName)
{
l_CmdString=save %p_lpszDeviceID% "%p_FileName%"
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_Return
}
MCI_Seek(p_lpszDeviceID,p_Position)
{
;-- Get current status
l_Status:=MCI_Status(p_lpszDeviceID)
;-- Adjust p_Position if necessary
if p_Position not in start,end
{
if p_Position is not Number
p_Position=0
p_Position:=Round(p_Position) ;-- Integer values only
if (p_Position>MCI_Length(p_lpszDeviceID))
p_Position:="end"
else
if p_Position<1
p_Position:="start"
;-- This is necessary because some devices don't like a "0"
; position.
}
;-- Seek
l_CmdString=seek %p_lpszDeviceID% to %p_Position% wait
l_Return:=MCI_SendString(l_CmdString,Dummy)
;-- Return to mode before seek
if l_Status in paused,playing
{
MCI_Play(p_lpszDeviceID)
;-- Re-pause
if l_Status=paused
MCI_Pause(p_lpszDeviceID)
}
l_CurrentPos:=MCI_Position(p_lpszDeviceID)
;-- Return to sender
return l_Return
}
MCI_Length(p_lpszDeviceID,p_Track=0)
{
;-- Build command string
l_CmdString:="status " . p_lpszDeviceID . " length"
if p_Track
l_CmdString:=l_CmdString . " track " . p_Track
;-- Send it!
MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
MCI_Status(p_lpszDeviceID)
{
MCI_SendString("status " . p_lpszDeviceID . " mode",l_lpszReturnString)
return l_lpszReturnString
}
MCI_Position(p_lpszDeviceID,p_Track=0)
{
;-- Build command string
l_CmdString:="status " . p_lpszDeviceID . " position"
if p_Track
l_CmdString:=l_CmdString . " track " . p_Track
;-- Send it!
MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
MCI_DeviceType(p_lpszDeviceID)
{
l_CmdString=capability %p_lpszDeviceID% device type
MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
MCI_MediaIsPresent(p_lpszDeviceID)
{
l_CmdString=status %p_lpszDeviceID% media present
l_RC:=MCI_SendString(l_CmdString,l_lpszReturnString)
if l_RC ;-- Probably invalid command for the device
l_Return:=false
else
if (l_lpszReturnString="true")
l_Return:=true
else
l_Return:=false
return l_Return
}
MCI_TrackIsAudio(p_lpszDeviceID,p_Track=1)
{
if p_Track is not Integer
p_Track=1
l_CmdString=status %p_lpszDeviceID% type track %p_Track%
l_RC:=MCI_SendString(l_CmdString,l_lpszReturnString)
if l_RC ;-- Probably invalid command for the device
l_Return:=false
else
if l_lpszReturnString=audio
l_Return:=true
else
l_Return:=false
return l_Return
}
MCI_CurrentTrack(p_lpszDeviceID)
{
l_CmdString:="status " . p_lpszDeviceID . " current track"
l_Return:=MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
MCI_NumberOfTracks(p_lpszDeviceID)
{
l_CmdString:="status " . p_lpszDeviceID . " number of tracks"
l_Return:=MCI_SendString(l_CmdString,l_lpszReturnString)
return l_lpszReturnString
}
MCI_SetVolume(p_lpszDeviceID,p_Factor)
{
l_CmdString:="setaudio " . p_lpszDeviceID . " volume to " . p_Factor
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_Return
}
MCI_SetBass(p_lpszDeviceID,p_Factor)
{
l_CmdString:="setaudio " . p_lpszDeviceID . " bass to " . p_Factor
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_lpszReturnString
}
MCI_SetTreble(p_lpszDeviceID,p_Factor)
{
l_CmdString:="setaudio " . p_lpszDeviceID . " treble to " . p_Factor
l_Return:=MCI_SendString(l_CmdString,Dummy)
return l_lpszReturnString
}
MCI_ToMilliseconds(Hour,Min,Sec)
{
milli:=Sec*1000
milli += (Min*60)*1000
milli += (Hour*3600)*1000
return milli
}
MCI_ToHHMMSS(p_ms,p_MinimumSize=4)
{
;-- Convert p_ms to whole seconds
if p_ms is not Number
l_Seconds=0
else
if p_ms<0
l_Seconds=0
else
l_Seconds:=floor(p_ms/1000)
;-- Initialize and format
l_Time=20121212 ;-- Midnight of an arbitrary date
EnvAdd l_Time,l_Seconds,Seconds
FormatTime l_mmss,%l_Time%,mm:ss
l_FormattedTime:="0" . l_Seconds//3600 . ":" . l_mmss
;-- Allows support for more than 24 hours.
;-- Trim insignificant leading characters
loop
if StrLen(l_FormattedTime)<=p_MinimumSize
break
else
if SubStr(l_FormattedTime,1,1)="0"
StringTrimLeft l_FormattedTime,l_FormattedTime,1
else
if SubStr(l_FormattedTime,1,1)=":"
StringTrimLeft l_FormattedTime,l_FormattedTime,1
else
break
;-- Return to sender
return l_FormattedTime
}
MCI_SendString(p_lpszCommand,ByRef p_lpszReturnString,p_hwndCallback=0)
{
VarSetCapacity(p_lpszReturnString,100,0)
l_Return:=DllCall("winmm.dll\mciSendStringA"
,"str",p_lpszCommand ;-- lpszCommand
,"str",p_lpszReturnString ;-- lpszReturnString
,"uint",100 ;-- cchReturn
,"uint",p_hwndCallback ;-- hwndCallback
,"Cdecl int") ;-- Return type
if ErrorLevel
MsgBox
,262160 ;-- 262160=0 (OK button) + 16 (Error icon) + 262144 (AOT)
,%A_ThisFunc% Function Error,
(ltrim join`s
Unexpected ErrorLevel from DllCall to the
"winmm.dll\mciSendStringA"
function. ErrorLevel=%ErrorLevel% %A_Space%
`nSee the AutoHotkey documentation (Keyword: DLLCall) for more
information. %A_Space%
)
;-- Return code?
if l_Return
{
VarSetCapacity(l_MCIErrorString,1024)
DllCall("winmm\mciGetErrorStringA"
,"uint",l_Return ;-- MCI error number
,"str",l_MCIErrorString ;-- MCI error text
,"uint",1024)
;-- This is provided to help debug MCI calls
outputdebug,
(ltrim join`s
End Func: %A_ThisFunc%: Unexpected return code from command string:
"%p_lpszCommand%"
`n--------- Return code=%l_Return% - %l_MCIErrorString%
)
}
return l_Return
}