[英]play gtts buffer with QtMultimedia.QAudioOutput directly
我想用QtMultimedia
播放声音。
在QMediaPlayer
的情况下,我可以播放 mp3 文件,它是由 gTTS 制作的。
(我认为没关系,但我不喜欢文件保留,除非我执行删除它的代码。)
我用 gTTS 模块制作了一个 mp3 文件,我想直接用缓冲区播放声音。
看来我可以制作一个有效的 object 但QAudioOutput
没有做任何事情。
我将 mp3 文件序列化到数据库中,并在我喜欢的时候获取它。
我的代码有什么不足?
这是我原始代码的摘录。
在我的原始代码中,缓冲区数据位于 Qt.UserRole + x 中,我可以随时获取它们。
播放列表由QTableWidget
和 QTableWidgetItem 构成。
from PySide2 import QtCore
from PySide2 import QtWidgets
from PySide2 import QtMultimedia
import os
import PySide2
import sys
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
import gtts
def main():
if QtWidgets.QApplication.instance() is not None:
app = QtWidgets.QApplication.instance()
else:
app = QtWidgets.QApplication([])
widget = QtWidgets.QTableWidget()
widget.setColumnCount(2)
text = "hello"
lang = "en"
onsei = gtts.gTTS(text=text, lang=lang)
buf = QtCore.QBuffer()
buf.setOpenMode( QtCore.QIODevice.WriteOnly)
onsei.write_to_fp(buf)
buf.close()
if not widget.rowCount():
widget.setRowCount(1)
else:
widget.insertRow(1)
nitem = QtWidgets.QTableWidgetItem()
nitem.setText(str(widget.rowCount()))
item = QtWidgets.QTableWidgetItem()
item.setText("{0}_tts_lang_{1}.mp3".format(text, lang))
item.setData(QtCore.Qt.UserRole+1, buf.data())
variant = item.data(QtCore.Qt.UserRole+1)
format = QtMultimedia.QAudioFormat()
format.setSampleRate(8000)
format.setChannelCount(1)
format.setSampleSize(16)
format.setCodec("audio/pcm")
format.setByteOrder(QtMultimedia.QAudioFormat.LittleEndian)
format.setSampleType(QtMultimedia.QAudioFormat.UnSignedInt)
buf = QtCore.QBuffer()
buf.setData(variant)
buf.open(QtCore.QIODevice.ReadOnly)
buf.seek(0)
audio = QtMultimedia.QAudioOutput(format, app)
audio.setVolume(0.5)
audio.setBufferSize(buf.size())
audio.start(buf)
buf.close()
print(67)
# sys.exit(QtWidgets.QApplication.exec_())
sys.exit()
if __name__ == "__main__":
main()
您可以使用 QMediaPlayer,而不是使用 QAudioOutput:
import sys
import threading
import uuid
from PySide2 import QtCore, QtGui, QtWidgets, QtMultimedia
import gtts
IdentifierRole = QtCore.Qt.UserRole
DataRole = QtCore.Qt.UserRole + 1
DownLoadRole = QtCore.Qt.UserRole + 2
ActiveRole = QtCore.Qt.UserRole + 3
class BackgroundColorDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super().initStyleOption(option, index)
color = None
if index.data(DownLoadRole):
color = QtGui.QColor("green")
if index.data(ActiveRole):
color = QtGui.QColor("red")
if color:
option.backgroundBrush = color
class DownLoader(QtCore.QObject):
downloaded = QtCore.Signal(str, QtCore.QByteArray)
def start(self, identifier, text, lang):
threading.Thread(
target=self._execute, args=(identifier, text, lang), daemon=True
).start()
def _execute(self, identifier, text, lang):
tts = gtts.gTTS(text=text, lang=lang)
buf = QtCore.QBuffer()
buf.open(QtCore.QBuffer.ReadWrite)
tts.write_to_fp(buf)
self.downloaded.emit(identifier, buf.data())
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.player = QtMultimedia.QMediaPlayer()
self.current_buff = QtCore.QBuffer()
self.tablewidget = QtWidgets.QTableWidget(
0,
2,
selectionBehavior=QtWidgets.QAbstractItemView.SelectRows,
editTriggers=QtWidgets.QAbstractItemView.NoEditTriggers,
)
delegate = BackgroundColorDelegate(self.tablewidget)
self.tablewidget.setItemDelegateForColumn(0, delegate)
self.tablewidget.itemClicked.connect(self.on_item_clicked)
self.setCentralWidget(self.tablewidget)
self.add_row("hello", "en")
self.add_row("world", "en")
def add_row(self, text, lang):
it = QtWidgets.QTableWidgetItem("{0}_tts_lang_{1}.mp3".format(text, lang))
identifier = str(uuid.uuid4())
it.setData(IdentifierRole, identifier)
downloader = DownLoader(self)
downloader.start(identifier, text, lang)
downloader.downloaded.connect(self.on_downloaded)
downloader.downloaded.connect(downloader.deleteLater)
row = self.tablewidget.rowCount()
self.tablewidget.insertRow(row)
self.tablewidget.setItem(row, 0, it)
@QtCore.Slot(str, QtCore.QByteArray)
def on_downloaded(self, identifier, data):
model = self.tablewidget.model()
indexes = model.match(
model.index(0, 0), IdentifierRole, identifier, flags=QtCore.Qt.MatchExactly
)
if indexes:
item = self.tablewidget.itemFromIndex(indexes[0])
item.setData(DataRole, data)
item.setData(DownLoadRole, True)
@QtCore.Slot("QTableWidgetItem*")
def on_item_clicked(self, item):
self.player.stop()
self.current_buff.close()
data = item.data(DataRole)
if not data:
return
self.current_buff.setData(data)
self.current_buff.open(QtCore.QIODevice.ReadOnly)
self.player.setMedia(QtMultimedia.QMediaContent(), self.current_buff)
self.player.play()
for row in range(self.tablewidget.rowCount()):
it = self.tablewidget.item(row, 0)
it.setData(ActiveRole, it is item)
def main():
app = QtWidgets.QApplication.instance()
if app is None:
app = QtWidgets.QApplication([])
w = MainWindow()
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.