Audio module done!

prd
Ivan Maslov 2 years ago
parent 20988db521
commit 0d97ec4ff2

@ -7,9 +7,6 @@ import time
from pyOpenRPA.Utils import Text
import os
def DeviceMicrophoneIndex():
"""L-,W+: Выполнить поиск устройства, с помощью которого можно будет выполнить захват c микрофона.
"""
@ -115,8 +112,10 @@ class Recorder:
mThresholdInt = 500
mSilentLastCheckTimeFloat = None
mIsMicrophoneBool=None
mCallbackChunkDef = None
mCallbackStopDef = None
def __init__(self, inDeviceInt=None):
"""L-,W+: Инициализация экземпляра класса записи звука
@ -148,13 +147,17 @@ class Recorder:
"""
return self.mStatusStr
def CaptureStart(self, inFolderPathStr="",inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 300.0):
def CaptureStart(self, inFolderPathStr="",inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 300.0, inCallbackChunkDef = None, inCallbackStopDef = None):
"""L-,W+: Начать запись звука
.. code-block:: python
def CallbackChunk(lRec, lFilenameStr):
pass # КОД ОБРАБОТКИ ПОСЛЕ СОХРАНЕНИЯ ЧАСТИ
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inCallbackChunkDef=CallbackChunk)
lRec.CaptureStop()
:param inFolderPathStr: Путь к папке, в которую сохранять аудиофайлы захвата , по умолчанию ""
@ -167,6 +170,10 @@ class Recorder:
:type inDurationSecFloat: float, опционально
:param inChunkSecFloat: Максимальная длина части аудиофайла, по умолчанию 300.0
:type inChunkSecFloat: float, опционально
:param inCallbackChunkDef: Функция, которая будет инициирована в случае выполнения Chunk сохранения (сохранение части). Callback функция должна принимать 2 аргумента: экземпляр класса Recorder и наименование сохраненного файла. Внимание! Функция запускается асинхронно!
:type inCallbackChunkDef: def, опционально
:param inCallbackStopDef: Функция, которая будет инициирована в случае окончания записи. Callback функция должна принимать 2 аргумента: экземпляр класса Recorder и наименование сохраненного файла. Внимание! Функция запускается асинхронно!
:type inCallbackStopDef: def, опционально
"""
# CHECK AUX.mp3
self.mFileInfoDict = {}
@ -182,6 +189,8 @@ class Recorder:
self.mFileFormatStr = inFileFormatStr
self.mAudio = pyaudio.PyAudio()
self.mSampleSizeInt = self.mAudio.get_sample_size(pyaudio.paInt16)
self.mCallbackChunkDef = inCallbackChunkDef
self.mCallbackStopDef = inCallbackStopDef
lDeviceInfoDict = self.mAudio.get_device_info_by_index(self.mDeviceInt)
#Open stream
self.mSampleRateInt = int(lDeviceInfoDict["defaultSampleRate"])
@ -209,7 +218,7 @@ class Recorder:
.. code-block:: python
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = 10.0, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = 10.0, inChunkSecFloat = 5.0)
lRec.CaptureWait()
"""
self.mCaptureThread.join()
@ -220,7 +229,7 @@ class Recorder:
.. code-block:: python
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0)
lRec.CaptureStop()
:param inWaitStream: True - выполнить ожидание окончания потока захвата перед окончанием, по умолчанию True
@ -234,8 +243,12 @@ class Recorder:
self.mStream.close()
#Close module
self.mAudio.terminate()
self.CaptureChunk(inExtra=inExtra, inForceChunkBool=False)
lFileNameStr = self.CaptureChunk(inExtra=inExtra, inForceChunkBool=False)
self.mStatusStr = "0_READY"
if self.mCallbackStopDef != None:
lCallbackThread = threading.Thread(target=self.mCallbackStopDef,args=[self, lFileNameStr])
lCallbackThread.start()
def CaptureChunk(self, inExtra=None, inForceChunkBool=True):
"""L-,W+: Зафиксировать захват аудио в виде промежуточного файла вида: <имя файла>_00000.mp3
@ -243,20 +256,23 @@ class Recorder:
.. code-block:: python
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0)
lRec.CaptureChunk()
:param inExtra: Дополнительный контент, необходимый для идентификации файла. В дальнейшем получить структуру можно с помощью функции FileInfoGet()['Extra'], по умолчанию None
:type inExtra: any, опционально
:param inForceChunkBool: True - вне зависимости от текущего режима перейти на режим сохранения по частям, по умолчанию True
:type inForceChunkBool: bool, опционально
:return: Наименование сохраненного аудиофайла
:rtype: str
"""
if inForceChunkBool==True and self.mFileAvailableChunkInt==None: self.mFileAvailableChunkInt=0
lFileNameStr = self.mFileNameStr
if self.mFileAvailableChunkInt!=None:
lFileNameStr+=f"_{self.mFileAvailableChunkInt:05}"
self.mFileAvailableChunkInt = self.mFileAvailableChunkInt + 1
lFilePathStr = os.path.abspath(os.path.join(self.mFolderPathStr,f"{lFileNameStr}.{self.mFileFormatStr}"))
lFileNameWExtStr = f"{lFileNameStr}.{self.mFileFormatStr}"
lFilePathStr = os.path.abspath(os.path.join(self.mFolderPathStr,lFileNameWExtStr))
# Advanced usage, if you have raw audio data:
sound = AudioSegment(
# raw audio data (bytes)
@ -271,14 +287,18 @@ class Recorder:
self.mRecordedFramesList = []
lTimeSecFloat = time.time()
sound.export(lFilePathStr, format=f"{self.mFileFormatStr}")
self.mFileNameList.append(f"{lFileNameStr}.{self.mFileFormatStr}")
self.mFileInfoDict[f"{lFileNameStr}.{self.mFileFormatStr}"]= {
self.mFileNameList.append(lFileNameWExtStr)
self.mFileInfoDict[lFileNameWExtStr]= {
"StartSecFloat": self.mStartChunkSecFloat,
"EndSecFloat": lTimeSecFloat,
"Extra": inExtra,
"PathStr": lFilePathStr
}
if self.mCallbackChunkDef != None and self.mFileAvailableChunkInt!=None:
lCallbackThread = threading.Thread(target=self.mCallbackChunkDef,args=[self, lFileNameWExtStr])
lCallbackThread.start()
self.mStartChunkSecFloat = lTimeSecFloat
return lFileNameWExtStr
def FileInfoGet(self, inFileNameStr=None):
"""L-,W+: Вернуть информацию по аудиофайлу inFileNameStr. Если inFileNameStr == None -> Функция вернет информацию по последнему записанному файлу
@ -286,7 +306,7 @@ class Recorder:
.. code-block:: python
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0)
lRec.CaptureChunk()
lFileInfoDict = lRec.FileInfoGet()
@ -304,7 +324,7 @@ class Recorder:
.. code-block:: python
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0)
lRec.CaptureChunk()
lRec.CaptureChunk()
lRec.FileListGet()
@ -320,7 +340,7 @@ class Recorder:
.. code-block:: python
from pyOpenRPA.Robot import Audio
lRec = Audio.Recorder()
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)
lRec.CaptureStart(inFileNameStr = "out", inFileFormatStr = "mp3", inDurationSecFloat = None, inChunkSecFloat = 5.0)
lRec.CaptureChunk()
lRec.CaptureChunk()
lRec.FileListGet()
@ -329,13 +349,6 @@ class Recorder:
:rtype: list
"""
return self.mFileNameList[-1]
def __Callback__(self, inDefList):
pass
def __CallbackIsChunked__(self):
pass
def __CallbackIsStopped__(self):
pass
#def IsSilent(self, inLastSecFloat=None):
# "Returns 'True' if below the 'silent' threshold"

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@ -15,36 +15,9 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2 - NEC LCD1703M (AMD High Definition Audio Device): 0.2926829268292683 _ 0.0\n",
"Динамики (USB PnP Sound Device): 0.7419354838709677 _ 0.2926829268292683\n",
"Динамики (Realtek High Definition Audio): 0.22535211267605634 _ 0.7419354838709677\n",
"9\n"
]
},
{
"data": {
"text/plain": [
"{'IndexInt': 9,\n",
" 'NameStr': 'Динамики (USB PnP Sound Device)',\n",
" 'MaxInputChannelsInt': 0,\n",
" 'MaxOutputChannelsInt': 2,\n",
" 'HostApiInt': 1,\n",
" 'DefaultSampleRateFloat': 44100.0,\n",
" 'HostApiStr': 'Windows WASAPI'}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"from pyOpenRPA.Robot import Audio\n",
"print(Audio.DeviceSystemSoundIndex())\n",
@ -53,49 +26,38 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pyOpenRPA.Robot import Audio\n",
"lRec = Audio.Recorder(inDeviceInt = Audio.DeviceMicrophoneIndex())\n",
"lRec.CaptureStart(inFileNameStr = \"out2\", inFileFormatStr = \"mp3\", inDurationSecFloat = None, inChunkSecFloat = 15.0, inChunkSilentSecFloat = 3.0)"
"lRec.CaptureStart(inFileNameStr = \"out2\", inFileFormatStr = \"mp3\", inDurationSecFloat = None, inChunkSecFloat = 15.0)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pyOpenRPA.Robot import Audio\n",
"lRec = Audio.Recorder()\n",
"lRec.CaptureStart(inFileNameStr = \"out\", inFileFormatStr = \"mp3\", inDurationSecFloat = None, inChunkSecFloat = 5.0, inChunkSilentSecFloat = 10.0)"
"lRec.CaptureStart(inFileNameStr = \"out\", inFileFormatStr = \"mp3\", inDurationSecFloat = None, inChunkSecFloat = 5.0, inCallbackChunkDef=test)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"lRec.FileListGet()"
"lRec.hi"
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@ -104,150 +66,28 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"lRec.mT"
"def test(lRec, lFilenameStr):\n",
" lRec.hi=[lFilenameStr]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'1_RECORDING'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"lRec.StatusGet()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Available devices:\n",
"\n",
"0\n",
"0: \t Ïåðåíàçíà÷åíèå çâóêîâûõ óñòð. - Input \n",
" \t MME \n",
"\n",
"0\n",
"1: \t Ìèêðîôîí (Realtek High Definiti \n",
" \t MME \n",
"\n",
"0\n",
"2: \t Ìèêðîôîí (EpocCam Camera Audio) \n",
" \t MME \n",
"\n",
"0\n",
"3: \t Ìèêðîôîí (USB PnP Sound Device) \n",
" \t MME \n",
"\n",
"0\n",
"4: \t Ïåðåíàçíà÷åíèå çâóêîâûõ óñòð. - Output \n",
" \t MME \n",
"\n",
"0\n",
"5: \t Äèíàìèêè (USB PnP Sound Device) \n",
" \t MME \n",
"\n",
"0\n",
"6: \t 2 - NEC LCD1703M (AMD High Defi \n",
" \t MME \n",
"\n",
"0\n",
"7: \t Äèíàìèêè (Realtek High Definiti \n",
" \t MME \n",
"\n",
"1\n",
"8: \t 2 - NEC LCD1703M (AMD High Definition Audio Device) \n",
" \t Windows WASAPI \n",
"\n",
"1\n",
"9: \t Динамики (USB PnP Sound Device) \n",
" \t Windows WASAPI \n",
"\n",
"1\n",
"10: \t Динамики (Realtek High Definition Audio) \n",
" \t Windows WASAPI \n",
"\n",
"1\n",
"11: \t Микрофон (EpocCam Camera Audio) \n",
" \t Windows WASAPI \n",
"\n",
"1\n",
"12: \t Микрофон (Realtek High Definition Audio) \n",
" \t Windows WASAPI \n",
"\n",
"1\n",
"13: \t Микрофон (USB PnP Sound Device) \n",
" \t Windows WASAPI \n",
"\n",
"2\n",
"14: \t Стерео микшер (Realtek HD Audio Stereo input) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"15: \t Микрофон (Realtek HD Audio Mic input) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"16: \t Speakers (Realtek HD Audio output) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"17: \t Лин. вход (Realtek HD Audio Line input) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"18: \t Output (AMD HD Audio HDMI out #1) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"19: \t Динамики (USB PnP Sound Device) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"20: \t Микрофон (USB PnP Sound Device) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"21: \t MIDI (EpocCam Audio) \n",
" \t Windows WDM-KS \n",
"\n",
"2\n",
"22: \t Output (EpocCam Audio) \n",
" \t Windows WDM-KS \n",
"\n"
]
}
],
"outputs": [],
"source": [
"print (textcolors.blue + \"Available devices:\\n\" + textcolors.end)\n",
"for i in range(0, p.get_device_count()):\n",
@ -258,7 +98,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@ -279,32 +119,9 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Starting...\n",
"End.\n",
"2\n",
"2\n",
"48000\n",
"382976\n"
]
},
{
"data": {
"text/plain": [
"<_io.BufferedRandom name='out.mp3'>"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"import pyaudio\n",
"defaultframes = 512\n",
@ -364,7 +181,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@ -378,57 +195,25 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.647887323943662"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"similarity_no_case(\"Ìèêðîôîí (Realtek High Definiti\",\"Динамики (Realtek High Definition Audio)\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'index': 1,\n",
" 'structVersion': 2,\n",
" 'name': 'Ìèêðîôîí (Realtek High Definiti',\n",
" 'hostApi': 0,\n",
" 'maxInputChannels': 2,\n",
" 'maxOutputChannels': 0,\n",
" 'defaultLowInputLatency': 0.09,\n",
" 'defaultLowOutputLatency': 0.09,\n",
" 'defaultHighInputLatency': 0.18,\n",
" 'defaultHighOutputLatency': 0.18,\n",
" 'defaultSampleRate': 44100.0}"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"p.get_default_input_device_info()"
]
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@ -438,60 +223,27 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<pyaudio.PyAudio at 0x1a6b5ab2438>"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"p"
]
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"not (False ^ True)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"from pyOpenRPA.Robot import Audio\n",
"Audio.DeviceMicrophoneIndex()"
@ -499,21 +251,9 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "abspath() takes 1 positional argument but 2 were given",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-1-8d5d932ca99b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mos\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mos\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabspath\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"\"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m\"\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m: abspath() takes 1 positional argument but 2 were given"
]
}
],
"outputs": [],
"source": [
"import os\n",
"os.path.abspath(\"\",\"\")"

Loading…
Cancel
Save