PyQt5 shows black window without widgets while moviepy is concatenating videos

886 views Asked by At

When concatenating two video files, the PyQt window is completely black with no widgets. The background color changes to grey and the widget shows up only after the videos have been concatenated.

I would like to see a grey window and my widget while the videos are being concatenated.

Here is the script:

import os
import sys
from PyQt5.QtWidgets import *
from moviepy.editor import VideoFileClip, concatenate_videoclips


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Using Labels")
        self.setGeometry(50,50,350,350)
        self.UI()


    def UI(self):
        text1=QLabel("Hello Python",self)
        text1.move(50,50)
        self.show()

def make_movie():
    sep = os.sep
    directory_stub = '.' + sep + 'src' + sep + "assets" + sep  
    clip1 = VideoFileClip(directory_stub + 'introoutro' + sep + "intro.mp4")
    clip2 = VideoFileClip(directory_stub + 'introoutro' + sep + "outro.mp4")
    final_clip = concatenate_videoclips([clip1,clip2])
    final_clip.write_videofile("my_concatenation.mp4")

def main():
    App = QApplication(sys.argv)
    window=Window()
    make_movie()
    sys.exit(App.exec_())

if __name__ == '__main__':
    main()

While the videos are being put together I see this:

enter image description here

I want to see this during the video processing but I only see it 1. after the processing is done or 2. if I edit the code to never call make_movie():

enter image description here

Thanks for any help.

1

There are 1 answers

1
eyllanesc On BEST ANSWER

Concatenation is a very time consuming task so it should not be run on the main thread as it can freeze the GUI:

import os
import sys
import threading

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from moviepy.editor import VideoFileClip, concatenate_videoclips


class QMovie(QObject):
    started = pyqtSignal()
    finished = pyqtSignal()

    def concatenate(self, inputs, output):
        threading.Thread(
            target=self._concatenate, args=(inputs, output), daemon=True
        ).start()

    def _concatenate(self, inputs, output):
        self.started.emit()
        clips = []
        for input_ in inputs:
            clip = VideoFileClip(input_)
            clips.append(clip)
        output_clip = concatenate_videoclips(clips)
        output_clip.write_videofile(output)
        self.finished.emit()


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Using Labels")
        self.setGeometry(50, 50, 350, 350)
        self.UI()

    def UI(self):
        text1 = QLabel("Hello Python", self)
        text1.move(50, 50)
        self.show()


def main():
    App = QApplication(sys.argv)
    window = Window()

    directory_stub = os.path.join(".", "src", "assets")
    in1 = os.path.join(directory_stub, "introoutro", "intro.mp4")
    in2 = os.path.join(directory_stub, "introoutro", "outro.mp4")
    qmovie = QMovie()
    qmovie.concatenate([in1, in2], "my_concatenation.mp4")
    sys.exit(App.exec_())


if __name__ == "__main__":
    main()