Blimmo
Blimmo

Reputation: 363

QMediaPlayer displays audio only for certain videos

I'm using QMediaPlayer according to the example in the docs.

Here's my code:

from PySide2 import QtWidgets
from PySide2 import QtCore
from PySide2.QtMultimedia import QMediaPlayer
from PySide2.QtMultimediaWidgets import QVideoWidget


class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.player = QMediaPlayer()
        self.video = QVideoWidget(self)
        self.player.setMedia(QtCore.QUrl.fromLocalFile("D:/path/to/file.webm"))
        self.player.setVideoOutput(self.video)
        self.video.show()
        self.player.play()

    def closeEvent(self, event):
        self.player.stop()
        event.accept()


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    window = App()
    window.show()
    app.exec_()

Overriding closeEvent was necessary to stop the program hanging on close.

My test videos:

I'm using qt5 on windows and have installed the appropriate codecs (the K-Lite Codec Pack) to play these files (they play in windows media player fine).

Edit:
I've connected to the mediaStatusChanged, videoAvailableChanged and error signals as suggested by @ekhumoro. I get video available as True and mediaStatus as BufferedMedia as soon as I run the program, regardless of whether it is actually displaying the video. The error signal handler is never being triggered.

During these further tests, videos in the "worked fine" section have been occassionaly failing to display video or, even more weirdly, displaying fine but at the minimum window size:

small window

Resizing the window doesn't increase the video's size. No videos in the "played audio only" section of my original tests have ever displayed video so far.

Edit 2:

After a restart (and updated graphics drivers), the first run with a video that didn't originally display video at all displayed in the weird small window. Subsequent runs (I've done 10 or so) have reverted to no video. Similarly a video that originally worked fine had no video on it's first run but is now consistantly small. A different video that originally worked is still playing normally.

Upvotes: 0

Views: 1243

Answers (1)

Blimmo
Blimmo

Reputation: 363

The problem was to do with sizing as @ekhumoro suggested.

When the QWidget I had inherited tried to work out its size it asked the QVideoWidget that was its only child for its size. Sometimes the QVideoWidget had loaded its video and so provided the correct size but other times it hadn't and so gave a sizeHint of (-1, -1). Because the QVideoWidget wasn't in a layout it wasn't able to resize itself and was stuck too small.

Additionally, the window itself isn't resized by layouts automatically once created (only by the user, or explicitly with adjustSize) so the window stays at its original size even with the QVideoWidget in a layout. The solution is to register a signal handler for the mediaStatusChanged and call updateGeometry and adjustSize.

Finally the other issue with the program hanging on exit was because I hadn't parented the QMediaPlayer on my window.

My modified class:

class App(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.player = QMediaPlayer(self)
        self.video = QVideoWidget(self)
        self.player.setMedia(QtCore.QUrl.fromLocalFile("D:/path/to/video.webm"))
        self.player.setVideoOutput(self.video)
        self.player.mediaStatusChanged.connect(self.video_available_changed)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.video)
        self.player.play()

    def video_available_changed(self, available):
        if available:
            self.video.updateGeometry()
            self.video.adjustSize()
            self.adjustSize()

Upvotes: 2

Related Questions