Qmediaplayer. How To Play Video With Multiple Audio?
Solution 1:
As @musicamante points out in the comments, the solution is to access the QMediaStreamsControl but PyQt5 does not expose it.
Instead PySide2 does expose it and the solution is to cast using shiboken2:
import os
from PySide2 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets
import shiboken2
classMainWindow(QtWidgets.QMainWindow):
def__init__(self, parent=None):
super(MainWindow, self).__init__(parent)
video_widget = QtMultimediaWidgets.QVideoWidget()
self.player = QtMultimedia.QMediaPlayer(
self, QtMultimedia.QMediaPlayer.VideoSurface
)
file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test5.mkv")
self.player.setMedia(
QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file))
)
self.player.setVideoOutput(video_widget)
self.player.play()
self.setCentralWidget(video_widget)
control = self.player.service().requestControl(
"org.qt-project.qt.mediastreamscontrol/5.0"
)
qptr = shiboken2.getCppPointer(control)[0]
self.qcontrol = shiboken2.wrapInstance(qptr, QtMultimedia.QMediaStreamsControl)
self.resize(640, 480)
defcontextMenuEvent(self, event):
menu = QtWidgets.QMenu()
group = QtWidgets.QActionGroup(menu)
group.setExclusive(True)
index = 0for i inrange(self.qcontrol.streamCount()):
t = self.qcontrol.streamType(i)
if t == QtMultimedia.QMediaStreamsControl.AudioStream:
action = menu.addAction("Audio-{}".format(index))
action.setCheckable(True)
if self.qcontrol.isActive(i):
action.setChecked(True)
action.setData(i)
menu.addAction(action)
index += 1
action = menu.exec_(self.mapToGlobal(event.pos()))
if action isnotNone:
i = action.data()
self.qcontrol.setActive(i, True)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
In the case of pyqt5 you should use sip with the following code:
import os
from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets
import sip
classMainWindow(QtWidgets.QMainWindow):
def__init__(self, parent=None):
super(MainWindow, self).__init__(parent)
video_widget = QtMultimediaWidgets.QVideoWidget()
self.player = QtMultimedia.QMediaPlayer(
self, QtMultimedia.QMediaPlayer.VideoSurface
)
file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test5.mkv")
self.player.setMedia(
QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file))
)
self.player.setVideoOutput(video_widget)
self.player.play()
self.setCentralWidget(video_widget)
control = self.player.service().requestControl(
"org.qt-project.qt.mediastreamscontrol/5.0"
)
self.qcontrol = sip.cast(control, QtMultimedia.QMediaStreamsControl)
self.resize(640, 480)
defcontextMenuEvent(self, event):
menu = QtWidgets.QMenu()
group = QtWidgets.QActionGroup(menu)
group.setExclusive(True)
index = 0for i inrange(self.qcontrol.streamCount()):
t = self.qcontrol.streamType(i)
if t == QtMultimedia.QMediaStreamsControl.AudioStream:
action = menu.addAction("Audio-{}".format(index))
action.setCheckable(True)
if self.qcontrol.isActive(i):
action.setChecked(True)
action.setData(i)
menu.addAction(action)
index += 1
action = menu.exec_(self.mapToGlobal(event.pos()))
if action isnotNone:
i = action.data()
self.qcontrol.setActive(i, True)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
But as pointed out by QMediaStreamsControl is not available in PyQt5, so a solution is to expose it and for this you must:
- Download PyQt5 source code: https://pypi.python.org/packages/source/P/PyQt5/PyQt5-5.14.2.tar.gz
Create the file qmediastreamscontrol.sip in "sip/QtMultimedia" folder of the PyQt5 source code.
qmediastreamscontrol.sip
classQMediaStreamsControl : QMediaControl { %TypeHeaderCode #include<qmediastreamscontrol.h> %End public: enumStreamType { UnknownStream, VideoStream, AudioStream, SubPictureStream, DataStream }; virtual ~QMediaStreamsControl(); virtualintstreamCount()= 0; virtual QMediaStreamsControl::StreamType streamType(int streamNumber)= 0; virtual QVariant metaData(int streamNumber, const QString &key)= 0; virtualboolisActive(int streamNumber)= 0; virtualvoidsetActive(int streamNumber, bool state)= 0; signals: voidstreamsChanged(); voidactiveStreamsChanged(); protected: %If (Qt_5_6_1 -) explicitQMediaStreamsControl(QObject *parent /TransferThis/ = 0); %End %If (- Qt_5_6_1) QMediaStreamsControl(QObject *parent /TransferThis/ = 0); %End };
Add
%Include qmediastreamscontrol.sip
to the end of file sip/QtMultimedia/QtMultimediamod.sipCompile and install PyQt5 using the modified source code.
In conclusion:
If you use pyside2 the solution is simple.
If you use pyqt5 you will have to modify its source code, compile it and install it. Hopefully with the @musicamante report class QMediaStreamsControl is exposed in future releases of pyqt5
Post a Comment for "Qmediaplayer. How To Play Video With Multiple Audio?"