Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QMediaPlayer negative playbackRate doesn't rewind video

I am trying to use QMediaPlayer to create a.. media player. I want to have an ability to rewind videos on press of a button.

But setting a negative playbackRate via QMediaPlayer.setPlaybackRate doesn't seem to put video on rewind. It just keeps playing forward.

I don't want to change the position of the video, I want the video to play at negative speed. Through some logic of mine, setting playbackRate to a negative value would make the video play in reverse. But that just doesn't happen. If you can't understand me clearly, here is a video of what the playback should look like.

Here is some barebones code to reproduce the problem:

import sys

from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication

class VideoWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        videoWidget = QVideoWidget()
        self.setCentralWidget(videoWidget)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.setMedia(
            QMediaContent(QUrl.fromLocalFile(r"<some video file>.mp4"))
        )
        self.mediaPlayer.play()

        app.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QEvent.KeyPress:
            key = event.key()

            if key == Qt.Key_A:
                self.mediaPlayer.setPlaybackRate(1.0)
            elif key == Qt.Key_Y:
                self.mediaPlayer.setPlaybackRate(-1.0) # This doesn't work! :(

        return super().eventFilter(source, event)

    def closeEvent(self, event):
        self.mediaPlayer.setMedia(QMediaContent())

if __name__ == '__main__':
    app = QApplication(sys.argv)

    player = VideoWindow()
    player.resize(640, 480)
    player.show()

    exitCode = app.exec_()
    sys.exit(exitCode)

I tried searching for a solution, but I got nothing more than what documentation says (emphasis mine):

Values less than zero can be set and indicate the media will rewind at the multiplier of the standard pace.

However, I am not seeing this effect.

I did notice this:

Not all playback services support change of the playback rate.

Is it possible that I can't rewind an mp4? Perhaps I need to install / change something?

like image 206
Božo Stojković Avatar asked Sep 03 '18 20:09

Božo Stojković


1 Answers

QMediaPlayer.playbackRate property holds the playback rate of the current media. This value is a multiplier applied to the media's standard play rate.

Press the Key_A, Key_Z, Key_Y keys to see how it works.


If you want to rewind the video, you should use QMediaPlayer.position property, which holds the playback position of the current media. The value is the current playback position, expressed in milliseconds since the beginning of the media.

Press the Key_M, Key_P keys to see how it works.

import sys

from PyQt5.QtCore import Qt, QUrl, QEvent
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication

class VideoWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        videoWidget = QVideoWidget()
        self.setCentralWidget(videoWidget)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.setMedia(
            QMediaContent(QUrl.fromLocalFile(r"<some video file>.mp4"))
        )
        self.mediaPlayer.play()

        app.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QEvent.KeyPress:
            key = event.key()

            # It Playback Rate !
            if key == Qt.Key_A:
                #self.mediaPlayer.setPlaybackRate(1.0)
                self.mediaPlayer.setPlaybackRate(1.5)
            elif key == Qt.Key_Z:
                self.mediaPlayer.setPlaybackRate(0.8)
            elif key == Qt.Key_Y:
                self.mediaPlayer.setPlaybackRate(1.0)                        

            # setPosition(int), argument is in milliseconds.
            elif key == Qt.Key_M:
                self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000)
            elif key == Qt.Key_P:
                self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000)                

        return super().eventFilter(source, event)


    def closeEvent(self, event):
        self.mediaPlayer.setMedia(QMediaContent())

if __name__ == '__main__':
    app = QApplication(sys.argv)

    player = VideoWindow()
    player.resize(640, 480)
    player.show()

    exitCode = app.exec_()
    sys.exit(exitCode)
like image 178
S. Nick Avatar answered Nov 07 '22 07:11

S. Nick