无法在pyside6中使用setSource()更改媒体

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

我有一些名为 0.mp4、1.mp4、2.mp4... 的视频剪辑,我在 PySide6 中使用 QMediaPlayer。 我想写一个可以逐个播放视频的媒体播放器。在每个视频剪辑的末尾,我使用“setSource()”函数过渡到下一个剪辑。但是每次我在槽函数中执行 setSource() 时,主窗口都会卡住。 我猜这与线程有些相关,所以我尝试在新线程中更改源。但好像只完成了一次切换,1.mp4结束时没有任何反应。

**1。我尝试在普通函数中编写 setSource() : **

import sys
from PySide6.QtCore import Slot, QUrl
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtMultimedia import QAudioOutput, QMediaPlayer
from PySide6.QtMultimediaWidgets import QVideoWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self._audio_output = QAudioOutput()
        self._player = QMediaPlayer()
        self._player.setAudioOutput(self._audio_output)

        self._video_widget = QVideoWidget()
        self.setCentralWidget(self._video_widget)
        self._player.setVideoOutput(self._video_widget)
        self.video_now = 0

        self._player.setSource(QUrl.fromLocalFile("./{}.mp4".format(self.video_now)))
        self.video_now += 1
        self._player.play()

        self._player.mediaStatusChanged.connect(self.change_source)

    @Slot()
    def change_source(self):
        self._player.setSource(QUrl.fromLocalFile("./{}.mp4".format(self.video_now)))
        self.video_now += 1
        self._player.play()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_win = MainWindow()
    available_geometry = main_win.screen().availableGeometry()
    main_win.resize(available_geometry.width() / 3,
                    available_geometry.height() / 2)
    main_win.show()
    sys.exit(app.exec())

主窗口会卡在0.mp4的末尾。

2。我尝试将 setSource() 放入新线程中:

import sys
from PySide6.QtCore import Slot, QUrl, QThread
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtMultimedia import QAudioOutput, QMediaPlayer
from PySide6.QtMultimediaWidgets import QVideoWidget

class source_thread(QThread):
    def __init__(self, func):
        super().__init__()
        self.func = func

    def run(self):
        self.func()
        print("source_thread_finished")

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self._audio_output = QAudioOutput()
        self._player = QMediaPlayer()
        self._player.setAudioOutput(self._audio_output)

        self._video_widget = QVideoWidget()
        self.setCentralWidget(self._video_widget)
        self._player.setVideoOutput(self._video_widget)
        self.video_now = 0

        self._player.setSource(QUrl.fromLocalFile("./{}.mp4".format(self.video_now)))
        self.video_now += 1
        self._player.play()

        self._player.mediaStatusChanged.connect(self.source_thread_slot)
        self.thread_source = source_thread(self.change_source)


    @Slot()
    def source_thread_slot(self, play_status):
        if play_status != QMediaPlayer.MediaStatus.EndOfMedia:
            return
        self.thread_source.start()

    def change_source(self):
        self._player.setSource(QUrl.fromLocalFile("./{}.mp4".format(self.video_now)))
        self.video_now += 1
        self._player.play()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    main_win = MainWindow()
    available_geometry = main_win.screen().availableGeometry()
    main_win.resize(available_geometry.width() / 3,
                    available_geometry.height() / 2)
    main_win.show()
    sys.exit(app.exec())

第一次切换很完美,但是1.mp4结束时程序没有响应。

您可以在pexel下载短视频片段进行测试,如果您能给我一些建议,我将非常感激。

qthread pyside6 qmediaplayer
1个回答
0
投票

检查状态,加载媒体时播放,到达媒体末尾时设置源。

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self._audio_output = QAudioOutput()
        self._player = QMediaPlayer()
        self._player.setAudioOutput(self._audio_output)

        self._video_widget = QVideoWidget()
        self.setCentralWidget(self._video_widget)
        self._player.setVideoOutput(self._video_widget)
        self.video_now = 0

        self._player.mediaStatusChanged.connect(self.change_source)

        self._player.setSource(QUrl.fromLocalFile("./{}.mp4".format(self.video_now)))
        
    def change_source(self, status):
        if status == QMediaPlayer.LoadedMedia:
            self._player.play()
        elif status == QMediaPlayer.EndOfMedia:
            self.video_now += 1
            self._player.setSource(QUrl.fromLocalFile("./{}.mp4".format(self.video_now)))
© www.soinside.com 2019 - 2024. All rights reserved.