You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Sources/pyOpenRPA/Robot/Audio.py

144 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import pyaudio
from pydub import AudioSegment
import threading
import wave
def DeviceSystemSoundSearchIndex():
"""L-,W+: Выполнить поиск устройства, с помощью которого можно будет выполнить захват аудио, которое поступает из приложений. Например: аудиоконференции Zoom, whatsapp, telegram и т.д.
"""
pass
def DeviceListGet():
"""L-,W+: Вернуть список аудио устройст (входящих и исходящих, микрофонов и динамиков).
from pyOpenRPA.Robot import Audio
Audio.DeviceListGet()
:return: [{"IndexInt":1, "NameStr": "",
"HostApiInt": 0, "HostApiStr": "MME"|"Windows WASAPI"|"Windows WDM-KS",
"MaxInputChannelsInt": 0, "MaxOutputChannelsInt": 0,
"DefaultSampleRateFloat": 44100.0
},...]
:rtype: list
"""
l_result = []
p = pyaudio.PyAudio()
for i in range(0, p.get_device_count()):
l_info = p.get_device_info_by_index(i)
l_info_dict = {
"IndexInt":l_info["index"],
"NameStr": l_info["name"],
"MaxInputChannelsInt": l_info["maxInputChannels"],
"MaxOutputChannelsInt": l_info["maxOutputChannels"],
"HostApiInt": l_info["hostApi"],
"DefaultSampleRateFloat": l_info["defaultSampleRate"],
"HostApiStr": p.get_host_api_info_by_index(l_info["hostApi"])["name"] #"MME"|"Windows WASAPI"|"Windows WDM-KS"
}
l_result.append(l_info_dict)
return l_result
class Recorder:
mStatusStr = "0_READY"
mAudio = pyaudio.PyAudio()
mCaptureThread = None
mStream = None
mDeviceInt = None
mChannelCountInt = None
mFramesInt = 512
mRecordedFramesList = []
mUseLoopbackBool = True
mSampleRateInt = None
mSampleSizeInt = mAudio.get_sample_size(pyaudio.paInt16)
mCaptureBool = True
mFileNameStr = "aux"
mFileFormatStr = "mp3"
def __init__(self, inDeviceInt=None):
self.mDeviceInt = inDeviceInt
def CaptureStart(self):
lDeviceInfoDict = self.mAudio.get_device_info_by_index(self.mDeviceInt)
#Open stream
self.mSampleRateInt = int(lDeviceInfoDict["defaultSampleRate"])
self.mChannelCountInt = lDeviceInfoDict["maxInputChannels"] if (lDeviceInfoDict["maxOutputChannels"] < lDeviceInfoDict["maxInputChannels"]) else lDeviceInfoDict["maxOutputChannels"]
self.mStream = self.mAudio.open(format = pyaudio.paInt16,
channels = self.mChannelCountInt,
rate = self.mSampleRateInt,
input = True,
frames_per_buffer = self.mFramesInt,
input_device_index = lDeviceInfoDict["index"],
as_loopback = self.mUseLoopbackBool)
self.mCaptureThread = threading.Thread(target=self.__Capture__)
self.mCaptureThread.start()
def __Capture__(self):
while self.mCaptureBool == True:
self.mRecordedFramesList.append(self.mStream.read(self.mFramesInt))
self.mStream.stop_stream()
self.mStream.close()
#Close module
self.mAudio.terminate()
print("done")
def CaptureStop(self):
self.mCaptureBool=False
self.mCaptureThread.join()
print("done2")
self.CaptureChunk()
print("done3")
def CaptureChunk(self):
print("CaptureChunk 1")
waveFile = wave.open(f"{self.mFileNameStr}.{self.mFileFormatStr}", 'wb')
waveFile.setnchannels(self.mChannelCountInt)
waveFile.setsampwidth(self.mSampleSizeInt)
waveFile.setframerate(self.mSampleRateInt)
waveFile.writeframes(b''.join(self.mRecordedFramesList))
waveFile.close()
lSound = AudioSegment(
# raw audio data (bytes)
data=b''.join(self.mRecordedFramesList),
# 2 byte (16 bit) samples
sample_width=self.mSampleSizeInt,
# 44.1 kHz frame rate
frame_rate=self.mSampleRateInt,
# stereo
channels=self.mChannelCountInt
)
print("CaptureChunk 2")
print(len(self.mRecordedFramesList))
lSound.export(f"{self.mFileNameStr}.{self.mFileFormatStr}", format=self.mFileFormatStr)
print("CaptureChunk 3")
self.mRecordedFramesList = []
def FileListGet(self):
pass
def FileLastGet(self):
pass
def __Callback__(self, inDefList):
pass
def __CallbackIsSilent__(self):
pass
def __CallbackIsChunked__(self):
pass
def __CallbackIsStopped__(self):
pass
def __TriggerCenter__(self):
"""L-,W+: Контроль записи / остановки аудио по следующим критериям:
- Общая длительность,
- Максимальная длительность части,
- Максимальная длит тишины (часть),
- Максимальная длительность тишины (остановка),
"""
pass