def calculateOpticalFlowButtonClicked(self):
        if not self.opticalFlowLoaded:
            # Error: "First load optical flow images" in MessageBox
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setWindowTitle("Optical flow images are missing.")
            msg.setText('First load optical flow images!')
            msg.setStandardButtons(QMessageBox.Ok)

            msg.exec()
            return

        height, width = self.sequenceImages[0].shape

        fName = 'optical_flow.mp4'
        fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
        video = cv2.VideoWriter(fName, fourcc, 10, (width*2, height*2))

        size = 35
        s = int(size/2)
        e = int(round(size/2))
        
        for f in range(len(self.sequenceImages)-1):
            V = self.findOpticalFlowVectors(self.sequenceImages[f], self.sequenceImages[f+1], size)
            image = cv2.cvtColor(self.sequenceImages[f].copy(), cv2.COLOR_GRAY2RGB)
            image = cv2.resize(image, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

            for h in range(s, height-e, INTERVAL):
                for w in range(s, width-e, INTERVAL):
                    point1 = (w*2,h*2)
                    point2 = ((w+int(round(V[h,w,1])))*2, (h+int(round(V[h,w,0])))*2)
                    cv2.arrowedLine(image, point1, point2, (0,255,0), 1, 8, 0, 0.25)

            video.write(image)

        video.release()

        videoWidget = QVideoWidget()
        videoWidget.setFixedSize(width*2, height*2)
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.error.connect(self.handleError)
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(os.path.dirname(os.path.abspath(__file__)) + '/' + fName)))
        self.mediaPlayer.play()

        self.deleteItemsFromWidget(self.opticalFlowGroupBox.layout())
        self.opticalFlowGroupBox.layout().addWidget(videoWidget, 0, Qt.AlignCenter)
class VideoDisplay(QWidget):
    def __init__(self):
        super().__init__()

        self.video_name = ''
        self.wholeStyleSheet = '''
        QFrame{
            padding-right:0.5px;
            padding-left:0.5px;
            margin-top:0.5px;
            margin-bottom:0.5px;
            height:450px;
            width:800px;
            border:4px solid rgb(0,0,205);
        }
        '''
        self.sliderSheet = '''
        QSlider::groove:horizontal { 
            height: 10px;
            background: #63B8FF;
            border: 1px solid #3A5FCD;
            border-radius: 1px;
            padding-left: -1px;
            padding-right: -1px;
        }
        
        QSlider::sub-page:horizontal { 
            height: 10px;
            background: 
            qlineargradient(
                x1:0, y1:0, 
                x2:0, y2:1, 
                stop:0 #B1B1B1, 
                stop:1 #c4c4c4
            );
            background: 
            qlineargradient(
            x1:0, y1:0.2, 
            x2:1, y2:1, 
            stop:0 #5DCCFF, 
            stop:1 #1874CD);
            border: 1px solid #4A708B;
            border-radius: 2px;
        }

        QSlider::add-page:horizontal { height: 10px;
            background: #575757;
            border: 0px solid #777;
            border-radius: 2px;
        }
        
        QSlider::handle:horizontal{
            height:14px;
            width:15px;
            background:
            qlineargradient(
                x1:0, y1:0, 
                x2:1, y2:1, 
                stop:0 #104E8B, 
                stop:1 #5CACEE); 
            border: 1px solid #777; 
            margin-top: -3px;
            margin-bottom: -3px;
            border-radius: 5px;
        }
            
        QSlider::handle:horizontal:hover{
            height:14px;
            width:15px;
            background:
            qlineargradient(
                x1:1, y1:0, 
                x2:1, y2:1, 
                stop:0 #B0E2FF, 
                stop:1 #FFE1FF); 
            border: 1px solid #444; 
            margin-top: -3px;
            margin-bottom: -3px;
            border-radius: 5px;
        }
        
        QSlider::sub-page:horizontal:disabled { 
            height: 10px;
            background: #E0EEEE;
            border-color: #838B8B;
        }

        QSlider::add-page:horizontal:disabled { 
            height: 10px;
            background: #C1CDCD;
            border-color: #838B8B;
        }
        
        QSlider::handle:horizontal:disabled { 
            background: #483D8B;
            border: 1px solid #696969;
            margin-top: -3px;
            margin-bottom: -3px;
            border-radius: 4px;
        }
        '''
        self.roundBtnSheet = '''
            QPushButton{
                border-top: 1px transparent;
                border-bottom: 1px transparent;
                border-right: 7px transparent;
                border-left: 7px transparent;
            }
        '''
        self.initUI()

    def get_video_name(self):
        return self.video_name

    def initUI(self):

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.videoWidget = QVideoWidget()
        self.videoWidget.setFixedSize(800, 450)

        self.playerFrame = QFrame()
        self.playerLayout = QHBoxLayout()
        self.playerLayout.addWidget(self.videoWidget)
        self.playerFrame.setLayout(self.playerLayout)
        self.playerFrame.setStyleSheet(self.wholeStyleSheet)

        self.playerWindow = QMainWindow()

        self.playerWindow.setCentralWidget(self.playerFrame)

        self.openFileBtn = QPushButton(self)
        self.openFileBtn.setStyleSheet(self.roundBtnSheet)
        self.openFileBtn.setIcon(QIcon('../icons/Folder-Open-icon.png'))
        self.openFileBtn.setIconSize(QSize(50, 50))
        self.openFileBtn.clicked.connect(self.openFile)

        self.playButton = QPushButton(self)
        self.playButton.setStyleSheet(self.roundBtnSheet)
        self.playButton.setEnabled(False)
        self.playButton.setIcon(QIcon('../icons/Play-icon.png'))
        self.playButton.setIconSize(QSize(50, 50))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.setStyleSheet(self.sliderSheet)
        self.positionSlider.sliderMoved.connect(self.setPosition)

        self.errorLabel = QLabel()
        self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Maximum)

        self.controlLayout = QHBoxLayout()
        self.controlLayout.addWidget(self.openFileBtn)
        self.controlLayout.addWidget(self.playButton)
        self.controlLayout.addWidget(self.positionSlider)

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

        self.wholeLayout = QVBoxLayout()
        self.wholeLayout.addWidget(self.playerWindow)
        self.wholeLayout.addLayout(self.controlLayout)
        #self.wholeLayout.addWidget(self.errorLabel)

        self.setLayout(self.wholeLayout)
        self.setStyleSheet(self.wholeStyleSheet)

    def openFile(self, pressed):
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie",
                                                  QDir.homePath())

        self.video_name = fileName.split('/')[-1]

        if fileName != '':
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(fileName)))
            self.playButton.setEnabled(True)

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
            self.playButton.setIcon(QIcon('../icons/Play-icon.png'))
        else:
            self.mediaPlayer.play()
            self.playButton.setIcon(QIcon('../icons/Pause-icon.png'))

    def mediaStateChanged(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))

    def positionChanged(self, position):
        self.positionSlider.setValue(position)

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)

    def handleError(self):
        self.playButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
예제 #3
0
    def __init__(self, parent=None, summaryImgPath=None):
        super(VideoWindow, self).__init__(parent)
        self.setWindowTitle("Video Summarizer")

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        videoWidget = QVideoWidget()
        videoWidget.setFixedSize(880, 720)

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        # Position slider
        self.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.sliderMoved.connect(self.setPosition)

        # Create the Image Widget
        self.sumImage = QImage(summaryImgPath)

        imgW = self.sumImage.width()
        imgH = self.sumImage.height()

        self.sumImage = self.sumImage.scaledToHeight(min(imgH, 175))
        self.imageWidget = QPixmap.fromImage(self.sumImage)

        print(self.imageWidget.height())

        self.imageLabel = QLabel()
        self.imageLabel.setPixmap(self.imageWidget)
        self.imageLabel.mousePressEvent = self.getPos

        self.errorLabel = QLabel()
        self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Maximum)

        # Create new action
        openAction = QAction(QIcon('open.png'), '&Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open movie')
        openAction.triggered.connect(self.openFile)

        # Create exit action
        exitAction = QAction(QIcon('exit.png'), '&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.exitCall)

        # Create menu bar and add action
        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addAction(exitAction)

        # Create a widget for window contents
        wid = QWidget(self)
        self.setCentralWidget(wid)

        # Create layouts to place inside widget
        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.positionSlider)

        layout = QVBoxLayout()
        layout.setAlignment(Qt.AlignCenter)

        hLayout = QHBoxLayout()
        hLayout.addWidget(self.imageLabel)
        hLayout.setAlignment(Qt.AlignCenter)

        self.stackWidget = QStackedWidget(self)

        self.imgLabel = QLabel()
        self.stackImageWidget = QPixmap('')
        self.imgLabel.setPixmap(self.stackImageWidget)

        self.stackWidget.addWidget(videoWidget)
        self.stackWidget.addWidget(self.imgLabel)

        layout.addWidget(self.stackWidget)
        layout.addLayout(controlLayout)
        layout.addLayout(hLayout)
        layout.addWidget(self.errorLabel)

        # Set widget to contain window contents
        wid.setLayout(layout)

        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

        self.setWindowTitle("CS576 Video Summarizer")
예제 #4
0
class VideoPlayer(QWidget):

    def __init__(self, parent = None):

        super(VideoPlayer, self).__init__(parent)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setMuted(True)

#*******************************************************************************

        # The media player projects the media onto the videoWidget
        self.videoWidget = QVideoWidget()
        self.videoWidget.setFixedSize(450,300)

#*******************************************************************************

        # When play is pressed, 'play' is run, and the icon changes according to
        # its state
        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

#*******************************************************************************

        # This is a movable Qslider
        self.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.sliderMoved.connect(self.setPosition)

#*******************************************************************************

        # The widgets are thrown together in a layout
        self.controlLayout = QHBoxLayout()
        self.controlLayout.setContentsMargins(0,0,0,0)
        self.controlLayout.addWidget(self.playButton)
        self.controlLayout.addWidget(self.positionSlider)
        self.controlLayout.setAlignment(Qt.AlignBottom)

        self.superLayout = QVBoxLayout()
        self.superLayout.addWidget(self.videoWidget)
        self.superLayout.addLayout(self.controlLayout)
        self.superLayout.addStretch(1)

        self.setLayout(self.superLayout)

#*******************************************************************************

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)

        # This is where the selected video location is stored
        self.videoPath = None


        # Makes sure the videoWidget is centred
        frame = self.videoWidget.frameGeometry()
        centre = frame.center()
        frame.moveCenter(centre)
        self.move(frame.topLeft())

#*******************************************************************************

    def openFile(self):

        if self.videoPath != None:

            content = QMediaContent(QUrl.fromLocalFile(self.videoPath))

            self.playButton.setEnabled(True)

            self.mediaPlayer.setMedia(content)

#*******************************************************************************

    def play(self):

        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
            self.videoWidget.setFixedSize(451,301)
        else:
            self.mediaPlayer.play()
            self.videoWidget.setFixedSize(452,301)
#*******************************************************************************

    def mediaStateChanged(self, state):

        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))

#*******************************************************************************

    def positionChanged(self, position):
        self.positionSlider.setValue(position)

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)
class EcranConnexion(QMainWindow):
    """
    Fenêtre de connexion au serveur de jeu. Permet à l'utilisateur
    de choisir un pseudo pour sa partie, de sélectionner un serveur
    disponible ou d'en ajouter un.

    Args:
        parent (QWidget): (OPTIONNEL) le parent auquel rattacher
            la fenêtre.

    Attributes:
        game (QMainWindow): la fenêtre de jeu qui s'ouvrira
            une fois connecté.
        logo (QLabel): référence au logo affiché sur l'écran
        btn_connect (QPushButton): bouton de connexion au serveur
            sélectionné dans la liste
        btn_local (QPushButton): bouton pour entrer manuellement
            les informations de connexion au serveur
        server_list (QListWidget): liste des serveurs enregistrés
        input_username (QLineEdit): pseudo du joueur, devient 'Anonyme'
            si la case est laissée vide
    """
    def __init__(self, parent: QObject = None):
        super().__init__(parent)
        self.game = None
        uic.loadUi(os.path.join(os.getcwd(), "assets", "ecran_connexion.ui"),
                   self)

        # On cherche les éléments
        self.logo = self.findChild(QLabel, 'logo')
        self.btn_connect = self.findChild(QPushButton, 'btn_connect')
        self.btn_add_server = self.findChild(QPushButton, 'btn_add_server')
        self.server_list = self.findChild(QListWidget, 'server_list')
        self.input_username = self.findChild(QLineEdit, 'input_username')

        # On connecte les boutons aux méthodes
        self.btn_connect.clicked.connect(self.connect_from_list)
        self.btn_add_server.clicked.connect(self.add_server)
        self.server_list.itemDoubleClicked.connect(self.connect_from_list)

        self.setWindowTitle(
            "La Bataille Brestoise - Alexandre F. & Guillaume L.")

        # On créer un widget vidéo et on place notre vidéo en lecture
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.videoWidget = QVideoWidget(self.logo)
        self.logo.setFixedSize(800, int(9 / 16 * 800))
        self.videoWidget.setFixedSize(800, int(9 / 16 * 800))
        app_root = os.path.abspath(os.path.dirname(sys.argv[0]))
        movie_path = os.path.join(app_root, "assets", "background_video.mp4")
        self.mediaPlayer.setMedia(QMediaContent(
            QUrl.fromLocalFile(movie_path)))
        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.play()

        # On paramètre la liste des serveurs
        liste_serveurs = JsonLoader("known_servers.json")["server_list"]
        if len(liste_serveurs) == 0:
            self.add_server()
        else:
            self.refresh_server_list()

    def refresh_server_list(self) -> None:
        """
        Recupère la liste des serveurs enregistrés et l'enregistre dans la liste
        """
        self.server_list.clear()
        # On paramètre la liste des serveurs
        liste_serveurs = JsonLoader("known_servers.json")["server_list"]
        for server in liste_serveurs:
            self.server_list.addItem(
                QListWidgetItem(
                    f"{server['name']} | {server['ip']} | {server['port']}"))
        self.server_list.setCurrentRow(0)

    def connect_from_list(self) -> None:
        """
        Appelée lorsque l'utilisateur clique sur le bouton 'Connecter'
        Se connecter à partir d'un serveur enregistré
        """
        nom, ip, port = self.server_list.currentItem().text().split(" | ")
        # On se connecte
        self.connect(nom, ip, port)

    def add_server(self) -> None:
        """
        Appelée lorsque l'utilisateur clique sur le bouton 'Connexion locale'
        Ouvre la boite de dialogue correspondante
        """
        reponse = LocalServerDialog.get_local_server_addr()
        # On a cliqué sur cancel
        if reponse is None:
            return
        else:
            nom, ip, port = reponse
            liste_serveurs = JsonLoader("known_servers.json")
            liste_serveurs["server_list"].append({
                "name": nom,
                "ip": ip,
                "port": int(port)
            })
            liste_serveurs.write()
            self.refresh_server_list()

    def keyPressEvent(self, event: QKeyEvent) -> None:
        """
        Fonction héritée de Qt qui permet de prendre en charge les évènements du type
        touche clavier.

        Args:
            event (QKeyEvent): évènement de type touche de clavier
        """
        if event.key() == Qt.Key_Escape:
            self.close()

    def connect(self, nom: str, ip: str, port: int) -> None:
        """
        Appelée finalement pour se connecter au serveur et ouvrir
        la fenêtre de jeu.

        Args:
            nom (str): le nom affiché du serveur
            ip (str): l'adresse IP (IPv4) de l'hôte
            port (int): le port de l'hôte
        """
        # On arrête d'abord la lecture de la video
        self.mediaPlayer.stop()
        # On récupère la boucle des évènements
        loop = asyncio.get_event_loop()
        # On en fait la boucle principale
        GCR.setEventLoop(loop)
        try:
            # On ouvre la connexion au serveur
            username = self.input_username.text()
            if username == "":
                username = GCR.getRandomName()
            loop.run_until_complete(
                TCPClientProtocol.create(nom, ip, port, username))
            self.open_game()
            # L'astuce réside ici
            # On contient les évènements réseau dans un autre Thread
            # Comme ça le thread PyQt peut continuer de tourner
            GCR.tcp_thread = Thread(target=loop.run_forever)
            GCR.tcp_thread.start()
        except KeyboardInterrupt:
            GCR.log.log(Logger.INFORMATION, "Fin du programme client")

    def open_game(self) -> None:
        """
        Ouvre la fenêtre de jeu et cache la fenêtre de
        connexion jusqu'à ce que la fenêtre de jeu soit
        fermée.
        """
        GCR.log.log(Logger.INFORMATION, "Ouverture du jeu en cours ...")
        self.game = EcranJeu(self)

        # On connecte la fermeture de la fenêtre de jeu
        # A l'ouverture de la fenêtre de connexion
        self.game.closed.connect(self.show)
        self.game.show()
        self.hide()