mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-29 00:24:13 +08:00
record
This commit is contained in:
parent
4d2ac7bf10
commit
38f5cd864f
@ -3066,7 +3066,8 @@ def getalistname(parent, callback, skipid=False, skipidid=None):
|
||||
},
|
||||
],
|
||||
)
|
||||
else:
|
||||
elif len(__uid):
|
||||
|
||||
callback(__uid[0])
|
||||
|
||||
|
||||
|
@ -347,28 +347,8 @@ class AnkiWindow(QWidget):
|
||||
|
||||
@threader
|
||||
def simulate_key(self, i):
|
||||
def __internal__keystring(i):
|
||||
try:
|
||||
for _ in (0,):
|
||||
|
||||
if not gobject.baseobject.textsource:
|
||||
break
|
||||
|
||||
gameuid = gobject.baseobject.textsource.gameuid
|
||||
if not gameuid:
|
||||
break
|
||||
if savehook_new_data[gameuid]["follow_default_ankisettings"]:
|
||||
break
|
||||
if not savehook_new_data[gameuid][f"anki_simulate_key_{i}_use"]:
|
||||
return None
|
||||
return savehook_new_data[gameuid][
|
||||
f"anki_simulate_key_{i}_keystring"
|
||||
]
|
||||
except:
|
||||
pass
|
||||
return globalconfig["ankiconnect"]["simulate_key"][i]["keystring"]
|
||||
try:
|
||||
keystring = __internal__keystring(i)
|
||||
keystring = globalconfig["ankiconnect"]["simulate_key"][i]["keystring"]
|
||||
except:
|
||||
return
|
||||
if not keystring:
|
||||
@ -387,10 +367,10 @@ class AnkiWindow(QWidget):
|
||||
for mode in modes:
|
||||
windows.keybd_event(mode, 0, windows.KEYEVENTF_KEYUP, 0)
|
||||
|
||||
def startorendrecord(self, target: QLineEdit, idx):
|
||||
def startorendrecord(self, ii, target: QLineEdit, idx):
|
||||
if idx == 1:
|
||||
self.recorder = loopbackrecorder()
|
||||
self.simulate_key(idx)
|
||||
self.simulate_key(ii)
|
||||
else:
|
||||
self.recorder.end(callback=target.setText)
|
||||
|
||||
@ -428,11 +408,11 @@ class AnkiWindow(QWidget):
|
||||
self.remarks = FQPlainTextEdit()
|
||||
recordbtn1 = statusbutton(icons=["fa.microphone", "fa.stop"], colors=["", ""])
|
||||
recordbtn1.statuschanged.connect(
|
||||
functools.partial(self.startorendrecord, self.audiopath)
|
||||
functools.partial(self.startorendrecord, 1, self.audiopath)
|
||||
)
|
||||
recordbtn2 = statusbutton(icons=["fa.microphone", "fa.stop"], colors=["", ""])
|
||||
recordbtn2.statuschanged.connect(
|
||||
functools.partial(self.startorendrecord, self.audiopath_sentence)
|
||||
functools.partial(self.startorendrecord, 2, self.audiopath_sentence)
|
||||
)
|
||||
self.recordbtn1 = recordbtn1
|
||||
self.recordbtn2 = recordbtn2
|
||||
|
@ -5,6 +5,8 @@ import socket, gobject, uuid, subprocess, functools
|
||||
import ctypes, importlib, json
|
||||
import ctypes.wintypes
|
||||
from qtsymbols import *
|
||||
from ctypes import CDLL, c_void_p, CFUNCTYPE, c_size_t, cast, c_char, POINTER
|
||||
from ctypes.wintypes import HANDLE
|
||||
from traceback import print_exc
|
||||
from myutils.config import (
|
||||
globalconfig,
|
||||
@ -759,36 +761,65 @@ def checkmd5reloadmodule(filename, module):
|
||||
return False, globalcachedmodule.get(key, {}).get("module", None)
|
||||
|
||||
|
||||
class audiocapture:
|
||||
def __datacollect(self, ptr, size):
|
||||
self.data = cast(ptr, POINTER(c_char))[:size]
|
||||
self.stoped.release()
|
||||
|
||||
def __mutexcb(self, mutex):
|
||||
self.mutex = mutex
|
||||
|
||||
def stop(self):
|
||||
_ = self.mutex
|
||||
if _:
|
||||
self.mutex = None
|
||||
self.StopCaptureAsync(_)
|
||||
self.stoped.acquire()
|
||||
return self.data
|
||||
|
||||
def __del__(self):
|
||||
self.stop()
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
loopbackaudio = CDLL(gobject.GetDllpath("loopbackaudio.dll"))
|
||||
StartCaptureAsync = loopbackaudio.StartCaptureAsync
|
||||
StartCaptureAsync.argtypes = c_void_p, c_void_p
|
||||
StartCaptureAsync.restype = HANDLE
|
||||
StopCaptureAsync = loopbackaudio.StopCaptureAsync
|
||||
StopCaptureAsync.argtypes = (HANDLE,)
|
||||
self.StopCaptureAsync = StopCaptureAsync
|
||||
self.mutex = None
|
||||
self.stoped = threading.Lock()
|
||||
self.stoped.acquire()
|
||||
self.data = None
|
||||
self.cb1 = CFUNCTYPE(None, c_void_p, c_size_t)(self.__datacollect)
|
||||
self.cb2 = CFUNCTYPE(None, c_void_p)(self.__mutexcb)
|
||||
threading.Thread(target=StartCaptureAsync, args=(self.cb1, self.cb2)).start()
|
||||
|
||||
|
||||
class loopbackrecorder:
|
||||
def __init__(self):
|
||||
self.file = gobject.gettempdir(str(time.time()) + ".wav")
|
||||
try:
|
||||
self.waitsignal = str(time.time())
|
||||
cmd = './files/plugins/loopbackaudio.exe "{}" "{}"'.format(
|
||||
self.file, self.waitsignal
|
||||
)
|
||||
self.engine = subproc_w(cmd, name=str(uuid.uuid4()))
|
||||
self.capture = audiocapture()
|
||||
except:
|
||||
print_exc()
|
||||
self.capture = None
|
||||
|
||||
@threader
|
||||
def end(self, callback):
|
||||
windows.SetEvent(
|
||||
windows.AutoHandle(windows.CreateEvent(False, False, self.waitsignal))
|
||||
)
|
||||
self.engine.wait()
|
||||
filewav = self.file
|
||||
if os.path.exists(filewav) == False:
|
||||
callback("")
|
||||
return
|
||||
with open(filewav, "rb") as ff:
|
||||
wav = ff.read()
|
||||
if not self.capture:
|
||||
return callback("")
|
||||
wav = self.capture.stop()
|
||||
if not wav:
|
||||
return callback("")
|
||||
mp3 = winsharedutils.encodemp3(wav)
|
||||
if mp3:
|
||||
filemp3 = filewav[:-3] + "mp3"
|
||||
with open(filemp3, "wb") as ff:
|
||||
ff.write(mp3)
|
||||
os.remove(filewav)
|
||||
callback(filemp3)
|
||||
if not mp3:
|
||||
file = gobject.gettempdir(str(time.time()) + ".wav")
|
||||
with open(file, "wb") as ff:
|
||||
ff.write(wav)
|
||||
callback(file)
|
||||
else:
|
||||
callback(filewav)
|
||||
file = gobject.gettempdir(str(time.time()) + ".mp3")
|
||||
with open(file, "wb") as ff:
|
||||
ff.write(mp3)
|
||||
callback(file)
|
||||
|
@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
|
||||
include(generate_product_version)
|
||||
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 25)
|
||||
set(VERSION_PATCH 1)
|
||||
set(VERSION_MINOR 26)
|
||||
set(VERSION_PATCH 0)
|
||||
|
||||
add_library(pch pch.cpp)
|
||||
target_precompile_headers(pch PUBLIC pch.h)
|
||||
|
@ -10,13 +10,8 @@ generate_product_version(
|
||||
VERSION_MINOR ${VERSION_MINOR}
|
||||
VERSION_PATCH ${VERSION_PATCH}
|
||||
)
|
||||
|
||||
|
||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||
|
||||
|
||||
else()
|
||||
|
||||
add_executable(loopbackaudio runer.cpp LoopbackCapture.cpp ${versioninfo})
|
||||
add_library(loopbackaudio MODULE runer.cpp LoopbackCapture.cpp ${versioninfo})
|
||||
target_precompile_headers(loopbackaudio REUSE_FROM pch)
|
||||
target_link_libraries(loopbackaudio Mfplat mfuuid )
|
||||
endif()
|
||||
target_link_libraries(loopbackaudio Mfplat mfuuid )
|
@ -47,17 +47,16 @@ CLoopbackCapture::~CLoopbackCapture()
|
||||
MFUnlockWorkQueue(m_dwQueueID);
|
||||
}
|
||||
}
|
||||
typedef HRESULT (STDAPICALLTYPE *ActivateAudioInterfaceAsync_t)(
|
||||
typedef HRESULT(STDAPICALLTYPE *ActivateAudioInterfaceAsync_t)(
|
||||
_In_ LPCWSTR deviceInterfacePath,
|
||||
_In_ REFIID riid,
|
||||
_In_opt_ PROPVARIANT *activationParams,
|
||||
_In_ IActivateAudioInterfaceCompletionHandler *completionHandler,
|
||||
_COM_Outptr_ IActivateAudioInterfaceAsyncOperation **activationOperation
|
||||
);
|
||||
_COM_Outptr_ IActivateAudioInterfaceAsyncOperation **activationOperation);
|
||||
HRESULT CLoopbackCapture::ActivateAudioInterface(DWORD processId, bool includeProcessTree)
|
||||
{
|
||||
return SetDeviceStateErrorIfFailed([&]() -> HRESULT
|
||||
{
|
||||
{
|
||||
AUDIOCLIENT_ACTIVATION_PARAMS audioclientActivationParams = {};
|
||||
audioclientActivationParams.ActivationType = AUDIOCLIENT_ACTIVATION_TYPE_PROCESS_LOOPBACK;
|
||||
audioclientActivationParams.ProcessLoopbackParams.ProcessLoopbackMode = includeProcessTree ?
|
||||
@ -77,8 +76,7 @@ HRESULT CLoopbackCapture::ActivateAudioInterface(DWORD processId, bool includePr
|
||||
// Wait for activation completion
|
||||
m_hActivateCompleted.wait();
|
||||
|
||||
return m_activateResult;
|
||||
}());
|
||||
return m_activateResult; }());
|
||||
}
|
||||
|
||||
//
|
||||
@ -87,10 +85,10 @@ HRESULT CLoopbackCapture::ActivateAudioInterface(DWORD processId, bool includePr
|
||||
// Callback implementation of ActivateAudioInterfaceAsync function. This will be called on MTA thread
|
||||
// when results of the activation are available.
|
||||
//
|
||||
HRESULT CLoopbackCapture::ActivateCompleted(IActivateAudioInterfaceAsyncOperation* operation)
|
||||
HRESULT CLoopbackCapture::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *operation)
|
||||
{
|
||||
m_activateResult = SetDeviceStateErrorIfFailed([&]()->HRESULT
|
||||
{
|
||||
m_activateResult = SetDeviceStateErrorIfFailed([&]() -> HRESULT
|
||||
{
|
||||
// Check for a successful activation result
|
||||
HRESULT hrActivateResult = E_UNEXPECTED;
|
||||
wil::com_ptr_nothrow<IUnknown> punkAudioInterface;
|
||||
@ -135,8 +133,7 @@ HRESULT CLoopbackCapture::ActivateCompleted(IActivateAudioInterfaceAsyncOperatio
|
||||
// Everything is ready.
|
||||
m_DeviceState = DeviceState::Initialized;
|
||||
|
||||
return S_OK;
|
||||
}());
|
||||
return S_OK; }());
|
||||
|
||||
// Let ActivateAudioInterface know that m_activateResult has the result of the activation attempt.
|
||||
m_hActivateCompleted.SetEvent();
|
||||
@ -150,10 +147,8 @@ HRESULT CLoopbackCapture::ActivateCompleted(IActivateAudioInterfaceAsyncOperatio
|
||||
//
|
||||
HRESULT CLoopbackCapture::CreateWAVFile()
|
||||
{
|
||||
return SetDeviceStateErrorIfFailed([&]()->HRESULT
|
||||
{
|
||||
m_hFile.reset(CreateFile(m_outputFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
|
||||
RETURN_LAST_ERROR_IF(!m_hFile);
|
||||
return SetDeviceStateErrorIfFailed([&]() -> HRESULT
|
||||
{
|
||||
|
||||
// Create and write the WAV header
|
||||
|
||||
@ -166,25 +161,23 @@ HRESULT CLoopbackCapture::CreateWAVFile()
|
||||
sizeof(m_CaptureFormat) // Size of fmt chunk
|
||||
};
|
||||
DWORD dwBytesWritten = 0;
|
||||
RETURN_IF_WIN32_BOOL_FALSE(WriteFile(m_hFile.get(), header, sizeof(header), &dwBytesWritten, NULL));
|
||||
|
||||
m_cbHeaderSize += dwBytesWritten;
|
||||
std::lock_guard _(bufferlock);
|
||||
buffer+=std::string((char*)header, sizeof(header));
|
||||
m_cbHeaderSize += sizeof(header);
|
||||
|
||||
// 2. The fmt sub-chunk
|
||||
WI_ASSERT(m_CaptureFormat.cbSize == 0);
|
||||
RETURN_IF_WIN32_BOOL_FALSE(WriteFile(m_hFile.get(), &m_CaptureFormat, sizeof(m_CaptureFormat), &dwBytesWritten, NULL));
|
||||
m_cbHeaderSize += dwBytesWritten;
|
||||
buffer+=std::string((char*) &m_CaptureFormat, sizeof(m_CaptureFormat));
|
||||
m_cbHeaderSize += sizeof(m_CaptureFormat);
|
||||
|
||||
// 3. The data sub-chunk
|
||||
DWORD data[] = { FCC('data'), 0 }; // Start of 'data' chunk
|
||||
RETURN_IF_WIN32_BOOL_FALSE(WriteFile(m_hFile.get(), data, sizeof(data), &dwBytesWritten, NULL));
|
||||
m_cbHeaderSize += dwBytesWritten;
|
||||
buffer+=std::string((char*) data, sizeof(data));
|
||||
m_cbHeaderSize += sizeof(data);
|
||||
|
||||
return S_OK;
|
||||
}());
|
||||
return S_OK; }());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FixWAVHeader()
|
||||
//
|
||||
@ -192,29 +185,24 @@ HRESULT CLoopbackCapture::CreateWAVFile()
|
||||
//
|
||||
HRESULT CLoopbackCapture::FixWAVHeader()
|
||||
{
|
||||
|
||||
std::lock_guard _(bufferlock);
|
||||
// Write the size of the 'data' chunk first
|
||||
DWORD dwPtr = SetFilePointer(m_hFile.get(), m_cbHeaderSize - sizeof(DWORD), NULL, FILE_BEGIN);
|
||||
RETURN_LAST_ERROR_IF(INVALID_SET_FILE_POINTER == dwPtr);
|
||||
|
||||
DWORD dwBytesWritten = 0;
|
||||
RETURN_IF_WIN32_BOOL_FALSE(WriteFile(m_hFile.get(), &m_cbDataSize, sizeof(DWORD), &dwBytesWritten, NULL));
|
||||
|
||||
auto offset = m_cbHeaderSize - sizeof(DWORD);
|
||||
memcpy(buffer.data() + offset, &m_cbDataSize, sizeof(DWORD));
|
||||
// Write the total file size, minus RIFF chunk and size
|
||||
// sizeof(DWORD) == sizeof(FOURCC)
|
||||
RETURN_LAST_ERROR_IF(INVALID_SET_FILE_POINTER == SetFilePointer(m_hFile.get(), sizeof(DWORD), NULL, FILE_BEGIN));
|
||||
|
||||
DWORD cbTotalSize = m_cbDataSize + m_cbHeaderSize - 8;
|
||||
RETURN_IF_WIN32_BOOL_FALSE(WriteFile(m_hFile.get(), &cbTotalSize, sizeof(DWORD), &dwBytesWritten, NULL));
|
||||
|
||||
RETURN_IF_WIN32_BOOL_FALSE(FlushFileBuffers(m_hFile.get()));
|
||||
offset = sizeof(DWORD);
|
||||
memcpy(buffer.data() + offset, &cbTotalSize, sizeof(DWORD));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CLoopbackCapture::StartCaptureAsync(DWORD processId, bool includeProcessTree, PCWSTR outputFileName)
|
||||
HRESULT CLoopbackCapture::StartCaptureAsync(DWORD processId, bool includeProcessTree)
|
||||
{
|
||||
m_outputFileName = outputFileName;
|
||||
auto resetOutputFileName = wil::scope_exit([&] { m_outputFileName = nullptr; });
|
||||
|
||||
RETURN_IF_FAILED(InitializeLoopbackCapture());
|
||||
RETURN_IF_FAILED(ActivateAudioInterface(processId, includeProcessTree));
|
||||
@ -234,21 +222,19 @@ HRESULT CLoopbackCapture::StartCaptureAsync(DWORD processId, bool includeProcess
|
||||
//
|
||||
// Callback method to start capture
|
||||
//
|
||||
HRESULT CLoopbackCapture::OnStartCapture(IMFAsyncResult* pResult)
|
||||
HRESULT CLoopbackCapture::OnStartCapture(IMFAsyncResult *pResult)
|
||||
{
|
||||
return SetDeviceStateErrorIfFailed([&]()->HRESULT
|
||||
{
|
||||
return SetDeviceStateErrorIfFailed([&]() -> HRESULT
|
||||
{
|
||||
// Start the capture
|
||||
RETURN_IF_FAILED(m_AudioClient->Start());
|
||||
|
||||
m_DeviceState = DeviceState::Capturing;
|
||||
MFPutWaitingWorkItem(m_SampleReadyEvent.get(), 0, m_SampleReadyAsyncResult.get(), &m_SampleReadyKey);
|
||||
|
||||
return S_OK;
|
||||
}());
|
||||
return S_OK; }());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// StopCaptureAsync()
|
||||
//
|
||||
@ -257,7 +243,7 @@ HRESULT CLoopbackCapture::OnStartCapture(IMFAsyncResult* pResult)
|
||||
HRESULT CLoopbackCapture::StopCaptureAsync()
|
||||
{
|
||||
RETURN_HR_IF(E_NOT_VALID_STATE, (m_DeviceState != DeviceState::Capturing) &&
|
||||
(m_DeviceState != DeviceState::Error));
|
||||
(m_DeviceState != DeviceState::Error));
|
||||
|
||||
m_DeviceState = DeviceState::Stopping;
|
||||
|
||||
@ -274,7 +260,7 @@ HRESULT CLoopbackCapture::StopCaptureAsync()
|
||||
//
|
||||
// Callback method to stop capture
|
||||
//
|
||||
HRESULT CLoopbackCapture::OnStopCapture(IMFAsyncResult* pResult)
|
||||
HRESULT CLoopbackCapture::OnStopCapture(IMFAsyncResult *pResult)
|
||||
{
|
||||
// Stop capture by cancelling Work Item
|
||||
// Cancel the queued work item (if any)
|
||||
@ -307,7 +293,7 @@ HRESULT CLoopbackCapture::FinishCaptureAsync()
|
||||
// Because of the asynchronous nature of the MF Work Queues and the DataWriter, there could still be
|
||||
// a sample processing. So this will get called to finalize the WAV header.
|
||||
//
|
||||
HRESULT CLoopbackCapture::OnFinishCapture(IMFAsyncResult* pResult)
|
||||
HRESULT CLoopbackCapture::OnFinishCapture(IMFAsyncResult *pResult)
|
||||
{
|
||||
// FixWAVHeader will set the DeviceStateStopped when all async tasks are complete
|
||||
HRESULT hr = FixWAVHeader();
|
||||
@ -324,7 +310,7 @@ HRESULT CLoopbackCapture::OnFinishCapture(IMFAsyncResult* pResult)
|
||||
//
|
||||
// Callback method when ready to fill sample buffer
|
||||
//
|
||||
HRESULT CLoopbackCapture::OnSampleReady(IMFAsyncResult* pResult)
|
||||
HRESULT CLoopbackCapture::OnSampleReady(IMFAsyncResult *pResult)
|
||||
{
|
||||
if (SUCCEEDED(OnAudioSampleRequested()))
|
||||
{
|
||||
@ -351,7 +337,7 @@ HRESULT CLoopbackCapture::OnSampleReady(IMFAsyncResult* pResult)
|
||||
HRESULT CLoopbackCapture::OnAudioSampleRequested()
|
||||
{
|
||||
UINT32 FramesAvailable = 0;
|
||||
BYTE* Data = nullptr;
|
||||
BYTE *Data = nullptr;
|
||||
DWORD dwCaptureFlags;
|
||||
UINT64 u64DevicePosition = 0;
|
||||
UINT64 u64QPCPosition = 0;
|
||||
@ -401,17 +387,11 @@ HRESULT CLoopbackCapture::OnAudioSampleRequested()
|
||||
// Get sample buffer
|
||||
RETURN_IF_FAILED(m_AudioCaptureClient->GetBuffer(&Data, &FramesAvailable, &dwCaptureFlags, &u64DevicePosition, &u64QPCPosition));
|
||||
|
||||
|
||||
// Write File
|
||||
if (m_DeviceState != DeviceState::Stopping)
|
||||
{
|
||||
DWORD dwBytesWritten = 0;
|
||||
RETURN_IF_WIN32_BOOL_FALSE(WriteFile(
|
||||
m_hFile.get(),
|
||||
Data,
|
||||
cbBytesToCapture,
|
||||
&dwBytesWritten,
|
||||
NULL));
|
||||
std::lock_guard _(bufferlock);
|
||||
buffer += std::string((char *)Data, cbBytesToCapture);
|
||||
}
|
||||
|
||||
// Release buffer back
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
//CLoopbackCapture() = default;
|
||||
~CLoopbackCapture();
|
||||
|
||||
HRESULT StartCaptureAsync(DWORD processId, bool includeProcessTree, PCWSTR outputFileName);
|
||||
HRESULT StartCaptureAsync(DWORD processId, bool includeProcessTree);
|
||||
HRESULT StopCaptureAsync();
|
||||
|
||||
METHODASYNCCALLBACK(CLoopbackCapture, StartCapture, OnStartCapture);
|
||||
@ -32,6 +32,7 @@ public:
|
||||
// IActivateAudioInterfaceCompletionHandler
|
||||
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation* operation);
|
||||
|
||||
std::string buffer;
|
||||
private:
|
||||
// NB: All states >= Initialized will allow some methods
|
||||
// to be called successfully on the Audio Client
|
||||
@ -69,15 +70,13 @@ private:
|
||||
|
||||
wil::unique_event_nothrow m_SampleReadyEvent;
|
||||
MFWORKITEM_KEY m_SampleReadyKey = 0;
|
||||
wil::unique_hfile m_hFile;
|
||||
wil::critical_section m_CritSec;
|
||||
DWORD m_dwQueueID = 0;
|
||||
DWORD m_cbHeaderSize = 0;
|
||||
DWORD m_cbDataSize = 0;
|
||||
|
||||
std::mutex bufferlock;
|
||||
// These two members are used to communicate between the main thread
|
||||
// and the ActivateCompleted callback.
|
||||
PCWSTR m_outputFileName = nullptr;
|
||||
HRESULT m_activateResult = E_UNEXPECTED;
|
||||
|
||||
DeviceState m_DeviceState{ DeviceState::Uninitialized };
|
||||
|
@ -1,12 +1,20 @@
|
||||
|
||||
#include "LoopbackCapture.h"
|
||||
int wmain(int argc, wchar_t *argv[])
|
||||
#define DECLARE extern "C" __declspec(dllexport)
|
||||
|
||||
DECLARE void StartCaptureAsync(void (*datacb)(void *ptr, size_t size), void (*handlecb)(HANDLE))
|
||||
{
|
||||
auto mutex = CreateSemaphoreW(NULL, 0, 1, NULL);
|
||||
handlecb(mutex);
|
||||
CLoopbackCapture loopbackCapture;
|
||||
loopbackCapture.StartCaptureAsync(GetCurrentProcessId(), false, argv[1]);
|
||||
WaitForSingleObject(
|
||||
CreateEventW(&allAccess, FALSE, FALSE, argv[2]),
|
||||
INFINITE);
|
||||
loopbackCapture.StartCaptureAsync(GetCurrentProcessId(), false);
|
||||
WaitForSingleObject(mutex, INFINITE);
|
||||
CloseHandle(mutex);
|
||||
loopbackCapture.StopCaptureAsync();
|
||||
return 0;
|
||||
datacb(loopbackCapture.buffer.data(), loopbackCapture.buffer.size());
|
||||
}
|
||||
|
||||
DECLARE void StopCaptureAsync(HANDLE m)
|
||||
{
|
||||
ReleaseSemaphore(m, 1, NULL);
|
||||
}
|
@ -2,12 +2,13 @@ import shutil,sys
|
||||
x86=int(sys.argv[1])
|
||||
if x86:
|
||||
shutil.copy('../builds/_x86/shareddllproxy32.exe','../../LunaTranslator/files/plugins')
|
||||
shutil.copy('../builds/_x86/loopbackaudio.exe','../../LunaTranslator/files/plugins')
|
||||
shutil.copy('../builds/_x86/loopbackaudio.dll','../../LunaTranslator/files/plugins/DLL32')
|
||||
shutil.copy('../builds/_x86/winrtutils32.dll','../../LunaTranslator/files/plugins/DLL32')
|
||||
shutil.copy('../builds/_x86/winsharedutils32.dll','../../LunaTranslator/files/plugins/DLL32')
|
||||
shutil.copy('../builds/_x86/wcocr.dll','../../LunaTranslator/files/plugins/DLL32')
|
||||
else:
|
||||
shutil.copy('../builds/_x64/shareddllproxy64.exe','../../LunaTranslator/files/plugins')
|
||||
shutil.copy('../builds/_x64/loopbackaudio.dll','../../LunaTranslator/files/plugins/DLL64')
|
||||
shutil.copy('../builds/_x64/hookmagpie.dll','../../LunaTranslator/files/plugins')
|
||||
shutil.copy('../builds/_x64/winrtutils64.dll','../../LunaTranslator/files/plugins/DLL64')
|
||||
shutil.copy('../builds/_x64/winsharedutils64.dll','../../LunaTranslator/files/plugins/DLL64')
|
||||
|
Loading…
x
Reference in New Issue
Block a user