Как воспроизвести несколько клипов видео один за другим - PullRequest
0 голосов
/ 29 января 2019

У меня есть видео, из которого я получаю несколько клипов по временному интервалу, и я хочу сделать следующее:

  • Заставить клипы воспроизводиться один за другим - поэтому сначала воспроизводится клип, затемпосле того, как это сделано, затем вторая игра и так далее ... Но в настоящее время это хорошо, но она просто играет роль между временными интервалами двух клипов, что я не хочу, чтобы это делалось.

Как мне поступить?

Я пытался использовать, например, pause, stop и т. Д. ... просто все, но ни один из них не работал.

Моя версия python: 3.6.0

И PyQt: 5.6

Файл проигрывателя видео (ссылка на repl, поскольку он слишком длинный):

https://repl.it/repls/SuperBrownSoftware

(просто скопируйте его в свою IDE)

Вот мой код, который вы должны выполнить:

from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
from PyQt5.QtWidgets import *
import sys
from pyqtvideo2_copy import *
app = QtWidgets.QApplication(sys.argv)

video = VideoWidget()
w = QtWidgets.QWidget()
w.fr = QtWidgets.QGridLayout(w)
w.bt = QtWidgets.QPushButton()
w.fr.addWidget(w.bt)
w.player_=Player(sys.argv[1:])
w.fr.addWidget(w.player_)
print(w)
video.activateWindow()

def clicked():
    l=[[2000,4000],[10000,15000]]
    for i in l:
        w.player_.setPosition(i[0])
        w.player_.player.pause()
        w.player_.player.play()
        w._end=i[1]
        w.player_.player.positionChanged.connect(on_positionChanged)

def on_positionChanged(position):
    if w.player_.player.state() == QtMultimedia.QMediaPlayer.PlayingState:
        if position > w._end:
            w.player_.player.stop()

def except_hook(cls, exception, traceback):
    sys.__excepthook__(cls, exception, traceback)

w.bt.clicked.connect(clicked)
w.show()
sys.excepthook=except_hook
sys.exit(app.exec_())

Обновление:

Теперь я получил ответЭхуморо, поэтому я использую эту настройку структуры:

class Ui_MainWindow(QMainWindow):
    def setupUi(self, MainWindow):
        ...
    def retranslateUi(self, MainWindow):
        ...
        self.player.positionChanged.connect(self.handlePositionChanged)
        self.player.mediaStatusChanged.connect(self.handleMediaStateChanged)

    ...
    def videoclips(self):
        self.w=QWidget()
        g=QGridLayout(self.w)
        g.setContentsMargins(0,0,0,0)
        d=TableWidget(self.df2,self.clicked)
        g.addWidget(d)
        self.w.show()
    def clicked(self,item):
        self.w.close()
        self.addMedia(ast.literal_eval(item.text()))
    def addMedia(self, clips):
        self._index = -1
        self._clips = clips
    def playNext(self):
        self.player.player.pause()
        self._index += 1
        if 0 <= self._index < len(self._clips):
            self.player.player.setPosition(self._clips[self._index][0])
            self.player.player.play()
    def handlePositionChanged(self, pos):
        if (0 <= self._index < len(self._clips) and
            pos > self._clips[self._index][1] and
            self.player.player.state() == QtMultimedia.QMediaPlayer.PlayingState):
            self.playNext()

    def handleMediaStateChanged(self, state):
        if state == QtMultimedia.QMediaPlayer.LoadedMedia:
            self.playNext()

Я скопировал функции ответа Эхуморо в свой код, затем добавил две строки: self.player.positionChanged.connect(self.handlePositionChanged) и self.player.mediaStatusChanged.connect(self.handleMediaStateChanged) в retranslateUi

Но, похоже, это не сработало, я чувствовал, что сделал какую-то ошибку.

Это дает мне ошибку:

AttributeError: 'Ui_MainWindow' object has no attribute '_index'

1 Ответ

0 голосов
/ 16 февраля 2019

Один из подходов заключается в создании простой очереди, а затем в ожидании завершения каждого клипа, прежде чем переходить к следующему элементу в очереди.Ниже приведена простая демонстрация, показывающая, как этого добиться.Надеюсь, будет легко увидеть, как адаптировать это к вашему собственному коду.

import sys
from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.video = QtMultimediaWidgets.QVideoWidget()
        self.player = QtMultimedia.QMediaPlayer()
        self.player.setVideoOutput(self.video)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.video)
        self.player.positionChanged.connect(self.handlePositionChanged)
        self.player.mediaStatusChanged.connect(self.handleMediaStateChanged)

    def addMedia(self, path, clips):
        self._index = -1
        self._clips = clips
        self.player.setMedia(
            QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(path)))

    def playNext(self):
        self.player.pause()
        self._index += 1
        if 0 <= self._index < len(self._clips):
            self.player.setPosition(self._clips[self._index][0])
            self.player.play()

    def handlePositionChanged(self, pos):
        if (0 <= self._index < len(self._clips) and
            pos > self._clips[self._index][1] and
            self.player.state() == QtMultimedia.QMediaPlayer.PlayingState):
            self.playNext()

    def handleMediaStateChanged(self, state):
        if state == QtMultimedia.QMediaPlayer.LoadedMedia:
            self.playNext()

app = QtWidgets.QApplication(sys.argv)
window = Window()
window.addMedia(sys.argv[1], [[2000, 4000], [10000, 15000]])
# window.addMedia(sys.argv[1], [[10000, 20000], [40000, 50000]])
window.show()
sys.exit(app.exec_())
...