录制某个PID的声音Ubuntu
Record voice coming of a certain PID Ubuntu
我正在研究文本到语音算法,我终于做到了,这个算法所做的是转换一个 html 文件
进入语音,像那样:python record.py file.html
这里一切都很好,但我想 运行 使用此命令对多个文件执行相同的命令:
python record.py file1.html & python record.py file2.html & python record.py file3.html
但我没有单独录制每个音频,而是在输出上重叠。
PS1:我正在使用 ubuntu 服务器,我想 运行 我对超过 6000 个文件的命令,每个文件大约需要 20 分钟,因为它们是一个大文件。
PS2: 我用的是pyaudio录音,下面是我代码中的录音部分:
from seleniumwire import webdriver
import sys
from webdriver_manager.chrome import ChromeDriverManager
import time
import pyaudio
import wave
from selenium.webdriver.chrome.options import Options
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
chrome_options = Options()
chrome_options.add_argument("--headless")
browser = webdriver.Chrome(ChromeDriverManager().install(), chrome_options=chrome_options)
#selenium part
browser.get('website')
search = browser.find_element_by_id("text-area")
search.clear()
data="this is a simple test"
search.send_keys(data)
time.sleep(2)
browser.find_element_by_id("btn").click()
print("waiting for audio")
size = len(data)/200
time.sleep(size*2)
print("audio detected")
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
#number = len(data)
RECORD_SECONDS = size*17
WAVE_OUTPUT_FILENAME = 'first.mp3'
open(WAVE_OUTPUT_FILENAME, "wb+")
frames = []
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE,input=True, frames_per_buffer=CHUNK)
print("started recording")
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
audio = stream.read(CHUNK)
frames.append(audio)
print("end of recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
有什么方法可以录制来自某个 PID 的音频。
我听说过 docker 容器,但我不知道在这种情况下它是否有帮助。
我无法让您的示例代码正常工作,但我有一个基本猜想:您是否更改了每次调用的输出文件名?查看您的脚本,情况似乎并非如此。在某些情况下,不更改文件名可能会导致文本出现乱码。
某些包(例如 pyttsx3)为了将音频写入非线程安全的文件而做了一些时髦的事情。这很可能是您的方法所发生的情况。
离线文字转语音
我发现完成此任务的一种非常可靠的方法是直接调用 espeak
之类的东西。
I've written a little package that provides a CLI for this. 它的核心在这个片段中:
import os
import tempfile
import re
# These packages are conveniences.
# Listing builtin packages that will require a few more lines to use
from bs4 import BeautifulSoup # Alt. html.parser
def text_to_mp3(text: str, outfile: str) -> None:
"""Given some text, generate an mp3 speaking the text.
Args:
text (str): Text to speak
outfile (str): *.mp3 file to write
"""
# For some reason espeak doesn't find NamedTemporaryFile files to be agreeable...
_, text_filename = tempfile.mkstemp(suffix=".txt")
with open(text_filename, "w") as file:
file.write(text)
try:
with tempfile.NamedTemporaryFile(suffix=".wav", delete=True) as wav_file:
os.system(f"espeak -f {text_filename} -w {wav_file.name}")
os.system(f"lame --preset insane {wav_file.name} {outfile} --silent")
finally:
if os.path.exists(text_filename):
os.remove(text_filename)
def html_to_mp3(html: str, outfile: str, select: str = "body") -> None:
"""Given a string containing html, generate an *.mp3 that speaks the text.
Args:
html (str): HTML string
outfile (str): *.mp3 to generate
select (str, optional): CSS selector from which to select text. Defaults to "body".
Raises:
ValueError: In case the CSS selector is not present in the text.
"""
soup = BeautifulSoup(html, features="html.parser")
elements = soup.select(select)
if not elements:
raise ValueError(f"No elements found for CSS selector `{select}`")
text = "\n".join([element.get_text() for element in elements])
text_to_mp3(text, outfile)
基本步骤是:
- 使用 beautifulsoup
从 html 文件中提取感兴趣的文本
- 对感兴趣的文本调用
espeak
并将结果输出到 *.wav
文件。
- 我们将文本写入文件,而不是尝试通过命令传递大字符串,以便回避解析
'
、"
和类似问题。
espeak
只输出到 wav
.
- 语音有很多选项可以修改
- 使用
lame
将上一步的 *.wav
转换为 mp3。
虽然您的计算机上可能已经安装了这些实用程序,但您始终可以(在 ubuntu 上)通过以下方式安装它们:
sudo apt-get update
sudo apt-get install lame espeak
在线文字转语音
如果您可以使用连接到 google 的在线文本到语音转换,那么 gTTS
包工作得很好。特别是,以下工作如您所愿:
gtts-cli 'hello' --output hello.mp3 & gtts-cli 'world' --output world.mp3
我解决问题的方法是从网站下载音频文件而不是
记录他们,这link帮助很大。
我正在研究文本到语音算法,我终于做到了,这个算法所做的是转换一个 html 文件
进入语音,像那样:python record.py file.html
这里一切都很好,但我想 运行 使用此命令对多个文件执行相同的命令:
python record.py file1.html & python record.py file2.html & python record.py file3.html
但我没有单独录制每个音频,而是在输出上重叠。
PS1:我正在使用 ubuntu 服务器,我想 运行 我对超过 6000 个文件的命令,每个文件大约需要 20 分钟,因为它们是一个大文件。
PS2: 我用的是pyaudio录音,下面是我代码中的录音部分:
from seleniumwire import webdriver
import sys
from webdriver_manager.chrome import ChromeDriverManager
import time
import pyaudio
import wave
from selenium.webdriver.chrome.options import Options
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
chrome_options = Options()
chrome_options.add_argument("--headless")
browser = webdriver.Chrome(ChromeDriverManager().install(), chrome_options=chrome_options)
#selenium part
browser.get('website')
search = browser.find_element_by_id("text-area")
search.clear()
data="this is a simple test"
search.send_keys(data)
time.sleep(2)
browser.find_element_by_id("btn").click()
print("waiting for audio")
size = len(data)/200
time.sleep(size*2)
print("audio detected")
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
#number = len(data)
RECORD_SECONDS = size*17
WAVE_OUTPUT_FILENAME = 'first.mp3'
open(WAVE_OUTPUT_FILENAME, "wb+")
frames = []
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=CHANNELS, rate=RATE,input=True, frames_per_buffer=CHUNK)
print("started recording")
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
audio = stream.read(CHUNK)
frames.append(audio)
print("end of recording")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
有什么方法可以录制来自某个 PID 的音频。
我听说过 docker 容器,但我不知道在这种情况下它是否有帮助。
我无法让您的示例代码正常工作,但我有一个基本猜想:您是否更改了每次调用的输出文件名?查看您的脚本,情况似乎并非如此。在某些情况下,不更改文件名可能会导致文本出现乱码。
某些包(例如 pyttsx3)为了将音频写入非线程安全的文件而做了一些时髦的事情。这很可能是您的方法所发生的情况。
离线文字转语音
我发现完成此任务的一种非常可靠的方法是直接调用 espeak
之类的东西。
I've written a little package that provides a CLI for this. 它的核心在这个片段中:
import os
import tempfile
import re
# These packages are conveniences.
# Listing builtin packages that will require a few more lines to use
from bs4 import BeautifulSoup # Alt. html.parser
def text_to_mp3(text: str, outfile: str) -> None:
"""Given some text, generate an mp3 speaking the text.
Args:
text (str): Text to speak
outfile (str): *.mp3 file to write
"""
# For some reason espeak doesn't find NamedTemporaryFile files to be agreeable...
_, text_filename = tempfile.mkstemp(suffix=".txt")
with open(text_filename, "w") as file:
file.write(text)
try:
with tempfile.NamedTemporaryFile(suffix=".wav", delete=True) as wav_file:
os.system(f"espeak -f {text_filename} -w {wav_file.name}")
os.system(f"lame --preset insane {wav_file.name} {outfile} --silent")
finally:
if os.path.exists(text_filename):
os.remove(text_filename)
def html_to_mp3(html: str, outfile: str, select: str = "body") -> None:
"""Given a string containing html, generate an *.mp3 that speaks the text.
Args:
html (str): HTML string
outfile (str): *.mp3 to generate
select (str, optional): CSS selector from which to select text. Defaults to "body".
Raises:
ValueError: In case the CSS selector is not present in the text.
"""
soup = BeautifulSoup(html, features="html.parser")
elements = soup.select(select)
if not elements:
raise ValueError(f"No elements found for CSS selector `{select}`")
text = "\n".join([element.get_text() for element in elements])
text_to_mp3(text, outfile)
基本步骤是:
- 使用 beautifulsoup 从 html 文件中提取感兴趣的文本
- 对感兴趣的文本调用
espeak
并将结果输出到*.wav
文件。- 我们将文本写入文件,而不是尝试通过命令传递大字符串,以便回避解析
'
、"
和类似问题。 espeak
只输出到wav
.- 语音有很多选项可以修改
- 我们将文本写入文件,而不是尝试通过命令传递大字符串,以便回避解析
- 使用
lame
将上一步的*.wav
转换为 mp3。
虽然您的计算机上可能已经安装了这些实用程序,但您始终可以(在 ubuntu 上)通过以下方式安装它们:
sudo apt-get update
sudo apt-get install lame espeak
在线文字转语音
如果您可以使用连接到 google 的在线文本到语音转换,那么 gTTS
包工作得很好。特别是,以下工作如您所愿:
gtts-cli 'hello' --output hello.mp3 & gtts-cli 'world' --output world.mp3
我解决问题的方法是从网站下载音频文件而不是
记录他们,这link帮助很大。