如何一个接一个地播放一个视频的多个片段 [英] How to play multiple clips of a video one after another

查看:71
本文介绍了如何一个接一个地播放一个视频的多个片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个视频,从中我按时间间隔获取了一些剪辑,我想执行以下操作:

I have a video, from which I am getting some clips by time interval, and I want to do the following:

  • 让剪辑一个接一个地播放 - 所以第一个剪辑播放,然后完成后,然后第二个播放,依此类推...但目前,这很好,但它只是在时间间隔之间播放部分两个剪辑,我不希望它这样做.

我该怎么做?

我尝试使用例如pausestop 等等……简单的一切,但它们都不起作用.

I tried using e.g. pause, stop, etc... simply everything, but none of them worked.

我的python版本:3.6.0

My version of python: 3.6.0

和 PyQt:5.6

视频播放器文件(repl 链接,因为它太长):

Video player file (a link to repl since it is too long):

https://repl.it/repls/SuperBrownSoftware

(只需将其复制到您的 IDE 中)

(just copy it into your IDE)

这是我应该运行的代码:

Here is my code that you should run:

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_())

更新:

我现在得到了 ekhumoro 的答案,所以我正在使用这种结构设置:

Update:

I now got the answer by ekhumoro, so i am using this setup of the structure:

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()

我将 ekhumoro 的答案的功能复制到我的代码中,然后添加了两行:self.player.positionChanged.connect(self.handlePositionChanged)self.player.mediaStatusChanged.connect(self.handleMediaStateChanged)retranslateUi

I copied ekhumoro's answer's functions to my code, then added two lines of: self.player.positionChanged.connect(self.handlePositionChanged) and self.player.mediaStatusChanged.connect(self.handleMediaStateChanged) in retranslateUi

但这似乎不起作用,我觉得我做错了什么.

But that didn't seem to work, i felt like i did some mistake.

它给了我一个错误:

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

推荐答案

一种方法是创建一个简单的队列,然后等待每个剪辑完成后再移动到队列中的下一项.下面是一个简单的演示,展示了如何实现这一点.希望很容易看出如何将其调整到您自己的代码中.

One approach is to create a simple queue and then wait for each clip to finish before moving to the next item in the queue. Below is a simple demo showing how to achieve that. Hopefully it should be easy to see how to adapt this to your own code.

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_())

这篇关于如何一个接一个地播放一个视频的多个片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆