直接用QtMultimedia.QAudioOutput播放gtts缓冲区。

问题描述 投票:0回答:1

我想玩的声音与 QtMultimedia.

ಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞಞ QMediaPlayer我可以播放MP3文件,它是由gTTS。

我认为它是好的,但我不喜欢的文件仍然,除非我exute代码删除它)。

我用gTTS模块制作一个mp3文件,我想直接用缓冲区播放声音。

似乎我可以做一个有效的对象,但...。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()
python audio pyside2 qtmultimedia gtts
1个回答
1
投票

而不是使用QAudioOutput,你可以使用QMediaPlayer。

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()
© www.soinside.com 2019 - 2024. All rights reserved.