Exemple #1
0
class MainWindow(QMainWindow):
    
    def __init__(self):
        super().__init__()

        self.widget = QWidget(self)
        self.layout = QVBoxLayout()
        self.bottom_layout = QHBoxLayout()

        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer()

        self.search_button = QPushButton("Buscar",self)
        self.play_button = QPushButton("Iniciar Vídeo", self)
        self.stop_button = QPushButton("Volver al principio", self)
        self.title_label = QLabel("",self)
        self.title_label.setStyleSheet('QLabel {background-color: black; color: green;}')
        #self.title_label.setStyleSheet("background-color : gold")
        self.title_label.setFixedWidth(220)
        self.volume_label = QLabel("VOLUMEN:",self)
        self.play_button.setEnabled(False)
        self.stop_button.setEnabled(False)

        self.seek_slider = QSlider(Qt.Horizontal)
        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(self.media_player.volume())
        self.seek_slider.sliderMoved.connect(self.media_player.setPosition)
        self.volume_slider.sliderMoved.connect(self.media_player.setVolume)
        self.media_player.positionChanged.connect(self.seek_slider.setValue)
        self.media_player.durationChanged.connect(partial(self.seek_slider.setRange, 0))

        self.layout.addWidget(self.video_widget)
        self.layout.addLayout(self.bottom_layout)
        
        self.bottom_layout.addWidget(self.search_button)
        self.bottom_layout.addWidget(self.title_label)
        self.bottom_layout.addWidget(self.play_button)
        self.bottom_layout.addWidget(self.stop_button)
        self.bottom_layout.addWidget(self.volume_label)
        self.bottom_layout.addWidget(self.volume_slider)
        self.layout.addWidget(self.seek_slider)

        self.search_button.clicked.connect(self.openFile)
        self.play_button.clicked.connect(self.play_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.media_player.stateChanged.connect(self.state_changed)

        self.video_widget.installEventFilter(self)
        self.setWindowTitle("Reproductor de video")
        self.resize(800, 600)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.bottom_layout.setContentsMargins(0, 0, 0, 0)
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)
    
    def play_clicked(self):
        if (self.media_player.state() in
            (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)):
            print("Lets go")
            self.media_player.play()
        else:
            self.media_player.pause()
    
    def stop_clicked(self):
        self.media_player.stop()
    
    def state_changed(self, newstate):
        states = {
            QMediaPlayer.PausedState: "Continuar",
            QMediaPlayer.PlayingState: "Pausa",
            QMediaPlayer.StoppedState: "Reproducir"
        }
        self.play_button.setText(states[newstate])
        self.stop_button.setEnabled(newstate != QMediaPlayer.StoppedState)
    
    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseButtonDblClick:
            obj.setFullScreen(not obj.isFullScreen())
        return False

    def openFile(self):
        print("Done")
        fileName,_ = QFileDialog.getOpenFileName(self, "Archivo de video", '/home')
        if fileName != '':
            videoName = fileName.split("/")[-1]
            self.title_label.setText(' VIDEO: {}'.format(videoName))
            VIDEO_PATH = fileName
            self.media_player.setMedia(
            QMediaContent(QUrl.fromLocalFile(VIDEO_PATH)))
            self.media_player.setVideoOutput(self.video_widget)
            self.play_button.setEnabled(True)
            self.stop_button.setEnabled(True)
Exemple #2
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # Controles principales para organizar la ventana.

        self.setupConstants()

        self.widget = QWidget(self)

        # tha main layout
        self.layout = QVBoxLayout()

        # the top box with file selections
        self.input_layout = QHBoxLayout()
        self.output_layout = QHBoxLayout()
        self.bottom_layout = QHBoxLayout()
        self.volume_box = QHBoxLayout()

        # video playback section
        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer()
        self.media_player.setVideoOutput(self.video_widget)

        # initialize audio recording section
        self.recorder = QAudioRecorder()

        # labels
        self.volume_label = QLabel()
        self.volume_label.setText("Volume")

        # Buttons for the I/O files selection
        self.input_file_button = QPushButton("Video Input", self)
        self.output_file_button = QPushButton("Audio output", self)

        # path/file line edits
        self.input_file_edit = QLineEdit()
        self.output_file_edit = QLineEdit()
        self.play_button = QPushButton("", self)
        self.play_button.setIcon(self.play_normal_icon)
        self.play_button.resize(150, 150)
        self.stop_button = QPushButton("", self)
        self.stop_button.setIcon(self.stop_normal_icon)
        self.record_button = QPushButton("", self)
        self.record_button.setCheckable(True)
        self.record_button.setIcon(self.rec_icon)

        self.seek_slider = QSlider(Qt.Horizontal)

        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(self.media_player.volume())

        self.input_layout.addWidget(self.input_file_button)
        self.input_layout.addWidget(self.input_file_edit)

        self.output_layout.addWidget(self.output_file_button)
        self.output_layout.addWidget(self.output_file_edit)

        self.bottom_layout.addWidget(self.play_button)
        self.bottom_layout.addWidget(self.stop_button)
        self.bottom_layout.addWidget(self.record_button)
        self.bottom_layout.addLayout(self.volume_box)

        self.volume_box.addWidget(self.volume_label)
        self.volume_box.addWidget(self.volume_slider)

        self.layout.addWidget(self.video_widget)
        self.layout.addLayout(self.bottom_layout)
        self.layout.addWidget(self.seek_slider)
        self.layout.addLayout(self.input_layout)
        self.layout.addLayout(self.output_layout)

        # Personalizzazione della finestra
        self.setWindowTitle("Wish' Karaoke! :)")
        self.resize(800, 600)
        self.layout.setContentsMargins(10, 10, 10, 10)
        self.bottom_layout.setContentsMargins(0, 0, 0, 0)
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

        self.setupMenus()
        self.setupUiConnections()

    def setupMenus(self):
        # setup the menus
        self.mainMenu = self.menuBar()

        # File menu and subitems
        self.fileMenu = self.mainMenu.addMenu('File')

        self.exitButton = QAction(self.exit_icon, 'Exit', self)
        self.exitButton.setShortcut('Ctrl+Q')
        self.exitButton.setStatusTip('Exit application')
        self.fileMenu.addAction(self.exitButton)

        # View menu and related items
        self.viewMenu = self.mainMenu.addMenu('View')

        # Fullscreen item
        self.toggleFullscreenButton = QAction(QIcon(""), 'Fullscreen', self)
        self.toggleFullscreenButton.setCheckable(True)
        self.toggleFullscreenButton.setStatusTip('Toggle fullscreen more')
        self.toggleFullscreenButton.setShortcut("CTRL+SHIFT+F")
        self.viewMenu.addAction(self.toggleFullscreenButton)

        # Tools menu and related items
        self.toolsMenu = self.mainMenu.addMenu('Tools')

        # Play/Rec bind toggle
        self.bindPlayRecButton = QAction(QIcon(""), 'Bind Play/Rec', self)
        self.bindPlayRecButton.setCheckable(True)
        self.bindPlayRecButton.setStatusTip('Bind Play and Rec')

        self.toolsMenu.addAction(self.bindPlayRecButton)

    def setupUiConnections(self):
        """
        Put all the UI connections and event catchers here, just to keep the code clean
        :return:
        """
        self.record_button.clicked.connect(self.recButtonState)
        self.seek_slider.sliderMoved.connect(self.media_player.setPosition)
        self.volume_slider.sliderMoved.connect(self.media_player.setVolume)
        self.media_player.positionChanged.connect(self.seek_slider.setValue)
        self.media_player.durationChanged.connect(
            partial(self.seek_slider.setRange, 0))
        self.play_button.clicked.connect(self.play_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.media_player.stateChanged.connect(self.state_changed)
        #
        self.input_file_button.clicked.connect(self.selectInputFile)
        #
        self.input_file_edit.textChanged.connect(self.setInputMedia)
        #
        self.output_file_button.clicked.connect(self.selectOutputFile)
        self.output_file_edit.textChanged.connect(self.setOutputMedia)

        # menu connections
        # fullscreen
        self.toggleFullscreenButton.toggled.connect(self.toggleFullscreen)
        # quit
        self.exitButton.triggered.connect(self.close)
        # Play/Rec bind
        self.bindPlayRecButton.toggled.connect(self.bind_play_rec)

        # Installing event filter for the video widget
        self.video_widget.installEventFilter(self)

    def bind_play_rec(self):
        """
        toggle the binding between play and rec to start recording as soon as playback starts.


        :return: Nothing
        """
        if not self.bindPlayRecStatus:
            self.bindPlayRecStatus = True
        else:
            self.bindPlayRecStatus = False
        # If binding is active, the REC button is disabled.
        self.record_button.setDisabled(self.bindPlayRecStatus)

    def play_clicked(self):
        """
        Start or resume playback.
        If binding is active, start/pause the audio recording as well
        """
        if (self.media_player.state()
                in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)):
            self.media_player.play()
            logger.info("(Re)Starting playback")
            if self.bindPlayRecStatus:
                if (self.recorder.state() in (QAudioRecorder.PausedState,
                                              QAudioRecorder.StoppedState)):
                    logger.info(
                        "Rec/Play bind is on! (Re)Starting Recorder as well.")
                    self.recorder.record()
        else:
            self.media_player.pause()
            logger.info("Pausing playback")
            if self.bindPlayRecStatus:
                logger.info("Rec/Play bind is on! Pausing Recorder as well.")
                self.recorder.pause()

    def stop_clicked(self):
        """
        Stopping playback.
        if Play/Rec binding is on, stop also the recorder.
        """
        logger.info("Stopping playback")
        self.media_player.stop()
        if self.bindPlayRecStatus:
            logger.info("Rec/Play bind is on! Stopping Recorder as well.")
            self.recorder.stop()

    def state_changed(self, newstate):
        """
        Update buttons. Not really needed, probably.
        """
        states = {
            QMediaPlayer.PausedState: self.play_normal_icon,
            QMediaPlayer.PlayingState: self.pause_icon,
            QMediaPlayer.StoppedState: self.play_normal_icon
        }
        self.play_button.setIcon(states[newstate])
        # elegant way to enable/disable the stop button
        self.stop_button.setEnabled(newstate != QMediaPlayer.StoppedState)

    def eventFilter(self, obj, event):
        """
        Catch MouseButtonDblClick or CTRL+SHIFT+F to toggle fullscreen

        """
        if (event.type() == QEvent.KeyPress and event.modifiers() & Qt.ShiftModifier \
                    and event.modifiers() & Qt.ControlModifier and event.key() == 70) \
                    or event.type() == QEvent.MouseButtonDblClick:
            obj.setFullScreen(not obj.isFullScreen())
        return False

    def toggleFullscreen(self):
        self.video_widget.setFullScreen(not self.video_widget.isFullScreen())

    def selectInputFile(self):
        """
        Just a small function to open a file dialog
        """

        #self.input_file_edit.setText(QFileDialog.getOpenFileName())

        # encode the resulting filename as UNICODE text
        self.input_filename, _ = QFileDialog.getOpenFileName()
        self.input_file_edit.setText(self.input_filename)

    def setInputMedia(self, filename):
        self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(filename)))

    def selectOutputFile(self):
        """
        Just a small function to open a file dialog
        """
        self.output_filename, _ = QFileDialog.getSaveFileName()
        self.output_file_edit.setText(self.output_filename)

    def setOutputMedia(self, filename):
        self.recorder.setOutputLocation(QUrl.fromLocalFile(filename))

    def recButtonState(self):
        if self.record_button.isChecked():
            self.doRecord()
        else:
            self.stopRecord()

    def doRecord(self):
        """
        TODO: define this function better, toggled by the Rec button
        :return:
        """
        print("Recording")
        self.recorder.record()

    def stopRecord(self):
        print("Stopping recorder")
        self.recorder.stop()

    def setupConstants(self):
        self.rec_icon = QIcon.fromTheme("media-record", QIcon("icons/rec.png"))
        self.play_normal_icon = QIcon.fromTheme("media-playback-start",
                                                QIcon("icons/Play-Normal.png"))
        self.stop_normal_icon = QIcon.fromTheme("media-playback-stop",
                                                QIcon("icons/Stop-Normal.png"))
        self.exit_icon = QIcon.fromTheme("application-exit",
                                         QIcon("icons/application-exit.png"))
        self.pause_icon = QIcon.fromTheme(
            "media-playback-pause", QIcon("icons/Pause-Disabled-icon.png"))
        self.bindPlayRecStatus = False
Exemple #3
0
class VideoWindow(QMainWindow):

    def __init__(self, parent=None):
        super(VideoWindow, self).__init__(parent)

        # Variables ########################
        self.marker_begin = None
        self.marker_end = None
        self.saved_markers = []
        self.current_pos = 0
        self.mouse_button_down = False

        # Stop playing when reaching marker end?
        self.stop_at_marker_end = False

        # Settings
        self.include_subdirs = False


        # Which video are currently playing
        self.index = 0
        ###################################

        # PyQt
        self.setWindowTitle("Play Extractor")


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

        self.videoWidget = QVideoWidget()
        self.videoWidget.setMouseTracking(True)
        self.videoWidget.installEventFilter(self)

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

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

        # Create new action
        openDirAction = QAction(QIcon('icons/folder.png'), '&OpenDir', self)
        openDirAction.setShortcut('Ctrl+Shift+O')
        openDirAction.setStatusTip('Open Directory')
        openDirAction.triggered.connect(self.openDir)

        exportAction = QAction(QIcon('icons/play.png'), '&Export', self)
        exportAction.setShortcut('Ctrl+E')
        exportAction.setStatusTip('Export Files')
        exportAction.triggered.connect(self.convertToMp4)

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

        # Create settings actions
        settingsAction = QAction(QIcon('icons/settings.png'), '&Settings', self)
        settingsAction.setShortcut('Ctrl+P')
        settingsAction.setStatusTip("Settings")
        settingsAction.triggered.connect(self.settings)

        # Create menu bar and add action
        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addAction(openDirAction)
        fileMenu.addAction(exportAction)
        fileMenu.addAction(settingsAction)
        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)
        self.label = QLabel(self)
        controlLayout.addWidget(self.label)

        #List
        listlayout = QHBoxLayout()
        listlayout.setContentsMargins(0, 0, 0, 0)
        self.labellist = List()
        self.labellist.mousePressEvent = self.selectVidFromList
        listlayout.addWidget(self.labellist)


        
        #if os.path.isfile(".last_session.pickle"):
        if False:
            self.video_list = pickle.load( open( ".last_session.pickle", "rb" ) )
            # Load videos into the the side list view
            for vid in self.video_list:
                imgPath = vid.path
                item = QListWidgetItem(imgPath.split("/")[-1].split(".")[0])
                self.labellist.addItem(item)

        else:
            #Open the play_extractor folder
            #self.loadVideos("/home/jake/dev/play_extractor")
            pass

        #self.labellist.item(0).setSelected(True)
        #self.labellist.itemClicked.connect(self.itemActivated)

        layout = QVBoxLayout()
        layout.addWidget(self.videoWidget)
        layout.addLayout(controlLayout)
        layout.setStretchFactor(self.videoWidget, 20)
        layout.setStretchFactor(controlLayout, 1)
        layout.addWidget(self.errorLabel)

        top = QHBoxLayout()
        top.setContentsMargins(0, 0, 10, 0)
        top.addLayout(listlayout)
        top.addLayout(layout)
        top.setStretchFactor(listlayout, 1)
        top.setStretchFactor(layout, 5)
        # Set widget to contain window contents
        wid.setLayout(top)

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

        #self.loadVidIndex(self.index)

        self.qTimer = QTimer()
        # set interval to 1 s
        self.qTimer.setInterval(20)  # 1000 ms = 1 s
        # connect timeout signal to signal handler
        self.qTimer.timeout.connect(self.getSensorValue)
        # start timer
        self.qTimer.start()

    def selectVidFromList(self, event):
        itemat =  self.labellist.itemAt(event.pos())
        row = self.labellist.row(itemat)
        if row != -1: 
            self.loadVidIndex(row)
        

    def itemActivated(self, item):
        index = self.labellist.currentRow()
        self.loadVidIndex(index)

    def settings(self):
        raise NotImplementedError

    def loadVideos(self, path):
        self.mImgList = self.scanDir(path)
        self.video_list = []
        self.labellist.clear()
        for imgPath in self.mImgList:
            self.video_list.append(video_container(imgPath, "None", "None", []))
            item = QListWidgetItem(os.path.split(imgPath)[1])
            self.labellist.addItem(item)
        if(len(self.video_list) > 0):
            self.loadVidIndex(0)

    def scanAllDirs(self, folderPath):
        images = []
        extensions = [".mp4"]

        for root, dirs, files in os.walk(folderPath):
            for file in files:
                if file.lower().endswith(tuple(extensions)):
                    relativePath = os.path.join(root, file)
                    path = str(os.path.abspath(relativePath))
                    images.append(path)
        return images

    def scanDir(self, folderPath):
        files = os.path.join(folderPath, '*.mp4')
        files = glob.glob(files)
        print(files)
        return files

    def time_to_x(self, timepoint):
        return int(timepoint / self.mediaPlayer.duration() * self.videoWidget.width())

    def clipArea(self, marker_begin, position):
        # Clip the box so it doesn't overlap with previous clips
        if self.saved_markers:
            if position > marker_begin:
                beginning_markers = [x[0] for x in self.saved_markers]
                beginning_markers.append(position)
                beginning_markers = np.array(beginning_markers)
                beginning_markers = beginning_markers[beginning_markers > marker_begin]
                return(np.min(beginning_markers))
            else:
                ending_markers = np.array([x[1] for x in self.saved_markers].append(position))
                ending_markers = ending_markers[ending_markers < marker_begin]
                return(np.max(ending_markers))
        else:
            return position

    def updateImage(self, position=0):
        width = self.label.width()
        pixmap = QPixmap(width, 50)
        pixmap.fill(Qt.gray)

        painter = QPainter()
        painter.begin(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(QPen(Qt.black, 1))

        # Draw markers and bars
        markerwidth = 10    
        try:
            for saved_marker in self.saved_markers:
                sm_begin, sm_end = saved_marker
                bar_width = self.time_to_x(sm_end - sm_begin)
                painter.setBrush(QBrush(Qt.yellow, Qt.SolidPattern))
                painter.drawRect(self.time_to_x(sm_begin), 0, bar_width, 50)
            
            if self.marker_begin:
                markerpos = self.time_to_x(self.marker_begin)
                if self.marker_end:
                    bar_width = self.time_to_x(self.marker_end) - markerpos
                elif markerpos < self.time_to_x(self.mediaPlayer.position()):
                    bar_width = self.time_to_x(self.clipArea(self.marker_begin, self.mediaPlayer.position())) - markerpos
                else:
                    bar_width = 0
                painter.setBrush(QBrush(Qt.blue, Qt.SolidPattern))
                painter.drawRect(markerpos, 0, bar_width, 50)

                if self.marker_end:
                    if self.mediaPlayer.position() > self.marker_end:
                        painter.setBrush(QBrush(QColor(171, 255, 158), Qt.SolidPattern))
                        bar_width = self.time_to_x(self.clipArea(self.marker_begin, self.mediaPlayer.position()) - self.marker_end)
                        painter.drawRect(self.time_to_x(self.marker_end), 0, bar_width, 50)

                    elif self.mediaPlayer.position() < self.marker_begin:
                        painter.setBrush(QBrush(QColor(171, 255, 158), Qt.SolidPattern))
                        bar_width = markerpos - self.time_to_x(self.mediaPlayer.position())
                        painter.drawRect(self.time_to_x(self.mediaPlayer.position()), 0, bar_width, 50)

                    elif abs(self.mediaPlayer.position() - self.marker_begin) < abs(self.mediaPlayer.position() - self.marker_end):
                        painter.setBrush(QBrush(QColor(255, 101, 84), Qt.SolidPattern))
                        bar_width = self.time_to_x(self.mediaPlayer.position()) - self.time_to_x(self.marker_begin)
                        painter.drawRect(self.time_to_x(self.marker_begin), 0, bar_width, 50)

                    else:
                        painter.setBrush(QBrush(QColor(255, 101, 84), Qt.SolidPattern))
                        bar_width = self.time_to_x(self.marker_end) - self.time_to_x(self.mediaPlayer.position())
                        painter.drawRect(self.time_to_x(self.mediaPlayer.position()), 0, bar_width, 50)

            for marker in [self.marker_begin, self.marker_end]:
                if marker != None:
                    painter.setBrush(QBrush(Qt.green, Qt.SolidPattern))
                    markerpos = int(marker / self.mediaPlayer.duration() * width)
                    painter.drawRect(min(markerpos, width - markerwidth), 0, markerwidth, 50)
        
        except Exception as e:
            print(e)

        # Draw video playback marker
        painter.setBrush(QBrush(Qt.white, Qt.SolidPattern))
        painter.drawRect(min(position, width - markerwidth), 0, markerwidth, 50)
        painter.end()
        pixmap.scaled(width, 50)
        self.label.setMinimumSize(1, 50)
        self.label.setPixmap(pixmap)
        self.label.setScaledContents(True)


    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            if event.button() == QtCore.Qt.LeftButton:
                self.mouse_button_down = True
                self.current_pos = int(event.x() / self.videoWidget.geometry().width() * self.mediaPlayer.duration())
                self.mediaPlayer.setPosition(self.current_pos)
                self.updateImage(event.x())
            elif event.button() == QtCore.Qt.RightButton:
                self.addMarker()
        elif event.type() == QtCore.QEvent.MouseButtonRelease:
            self.mouse_button_down = False
        elif event.type() == QtCore.QEvent.MouseMove and self.mouse_button_down:
            self.current_pos = int(event.x() / self.videoWidget.geometry().width() * self.mediaPlayer.duration())
            self.mediaPlayer.setPosition(self.current_pos)
            self.updateImage(event.x())


        # if event.type() == QtCore.QEvent.MouseMove:
        # elif event.type() == QtCore.QEvent.MouseButtonPress or event.type() == QtCore.QEvent.MouseButtonRelease:
        #     self.addMarker()
        return True


    def resizeEvent(self, event):
        QMainWindow.resizeEvent(self, event)
        # self.updateImage()


    def getSensorValue(self):
        position = self.mediaPlayer.position()
        duration = self.mediaPlayer.duration()
        if duration > 0:
            self.updateImage(int(position / self.mediaPlayer.duration() * self.videoWidget.geometry().width()))

        # Stop at marker end if flag is set
        if self.stop_at_marker_end and self.marker_end:
            if position >= self.marker_end:
                if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
                    self.play()


    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie",
                                                  QDir.homePath())
        print(fileName)
        if fileName != '':
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(fileName)))


    def openDefault(self):
        fileName = self.video_list[self.index].path
        self.mediaPlayer.setMedia(
            QMediaContent(QUrl.fromLocalFile(fileName)))
        self.play()
        self.play()
        self.mediaPlayer.setPosition(self.current_pos)
        self.updateImage()


    def openDir(self):
        targetDirPath = (str(QFileDialog.getExistingDirectory(self, "Select Directory", ".")))
        self.loadVideos(targetDirPath)


    def exitCall(self):
        sys.exit(app.exec_())


    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()


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


    def handleError(self):
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())


    def index_next(self):
        self.index = (self.index + 1) % len(self.video_list)


    def index_prev(self):
        self.index = (self.index - 1) % len(self.video_list)


    def reset(self):
        self.marker_end = None
        self.marker_begin = None
        self.current_pos = 0


    def save(self):
        if self.marker_begin and self.marker_end:
            self.video_list[self.index] = video_container(self.video_list[self.index].path, self.marker_begin,
                                                          self.marker_end, self.saved_markers)

        #Save the video list to a file
        pickle.dump(self.video_list, open( ".last_session.pickle", "wb" ))

    def delete_marker(self):
        self.video_list[self.index] = self.video_list[self.index]._replace(marker_begin = "None", marker_end = "None")
        self.marker_end = None
        self.marker_begin = None


    def load(self):
        if self.video_list[self.index].marker_begin != "None" and self.video_list[self.index].marker_end != "None":
            print("loading")
            self.marker_begin = self.video_list[self.index].marker_begin
            self.marker_end = self.video_list[self.index].marker_end
            self.current_pos = self.marker_begin
            self.saved_markers = self.video_list[self.index].saved_markers
        else:
            self.reset()

    def nextVid(self):
        self.save()
        self.labellist.item(self.index).setSelected(False)
        if self.marker_begin and self.marker_end:
            self.labellist.item(self.index).setForeground(Qt.green)
        self.index_next()
        self.reset()
        self.load()
        self.openDefault()
        self.labellist.item(self.index).setSelected(True)


    def previousVid(self):
        self.save()
        self.labellist.item(self.index).setSelected(False)
        if self.marker_begin and self.marker_end:
            self.labellist.item(self.index).setForeground(Qt.green)
        self.index_prev()
        self.reset()
        self.load()
        self.openDefault()
        self.labellist.item(self.index).setSelected(True)


    def loadVidIndex(self, index):
        self.save()
        self.labellist.item(self.index).setSelected(False)
        if self.marker_begin and self.marker_end:
            self.labellist.item(self.index).setForeground(Qt.green)
        self.index = index
        self.reset()
        self.load()
        self.openDefault()
        self.labellist.item(self.index).setSelected(True)


    def toggleFileList(self):
        if self.labellist.isHidden():
            self.labellist.show()
        else:
            self.labellist.hide()

    def overlapsWithSavedClips(self, position):
        for saved_marker in self.saved_markers:
            if position > saved_marker[0] and position <= saved_marker[1]:
                return True
            if self.marker_begin != None:
                if self.marker_begin < saved_marker[0] and (position > saved_marker[0]):
                    return True 
                
        return False


    def convertToMp4(self):
        #TODO: MAKE THIS PARALLEL
        for video in self.video_list:
            if video.marker_begin != "None" and video.marker_end != "None":
                input_kwargs = {}
                start_time = video.marker_begin / 1000
                end_time = video.marker_end / 1000

                if start_time is not None:
                    input_kwargs['ss'] = start_time
                else:
                    start_time = 0.
                if end_time is not None:
                    input_kwargs['t'] = end_time - start_time

                output_path = os.path.split(video.path)[0] + "/output"
                Path(output_path).mkdir(parents=True, exist_ok=True)
                print(video.path)
                stream = ffmpeg.input(video.path, **input_kwargs)
                stream = ffmpeg.output(stream, output_path + '/{}.mp4'.format(os.path.split(video.path)[1]))
                ffmpeg.run(stream)
        

    def showShortcuts(self):
        MsgBox = QMessageBox()
        MsgBox.setText("<b>Shortcuts</b><br><br>"
                       "<b>mouse hover</b>: scrub <br>"
                       "<b>space</b>: play/pause <br>"
                       "<b>d</b>: next video <br>"
                       "<b>a</b>: previous video <br> "
                       "<b>w</b>: place marker <br>"
                       "<b>s</b>: delete selection <br>"
                       "<b>p</b>: play from first marker <br>")
        MsgBox.exec()
        #MsgBox.about(self, "Title", "Message")

    def addMarker(self):
        if not self.overlapsWithSavedClips(self.mediaPlayer.position()):
            if self.marker_begin == None:
                self.marker_begin = self.mediaPlayer.position()
            elif self.marker_end == None:
                if self.mediaPlayer.position() > self.marker_begin:
                    self.marker_end = self.mediaPlayer.position()
                else:
                    self.marker_begin = self.mediaPlayer.position()
            elif self.mediaPlayer.position() < self.marker_begin:
                self.marker_begin = self.mediaPlayer.position()
            elif self.mediaPlayer.position() > self.marker_end:
                self.marker_end = self.mediaPlayer.position()
            else:
                if abs(self.mediaPlayer.position() - self.marker_begin) > abs(self.mediaPlayer.position() - self.marker_end):
                    self.marker_end = self.mediaPlayer.position()
                else:
                    self.marker_begin = self.mediaPlayer.position()

            if self.marker_begin and self.marker_end:
                self.save()

        print(self.current_pos)
        print(self.mediaPlayer.position())


    def keyPressEvent(self, e):
        key = e.key()
        self.stop_at_marker_end = False

        # play/pause
        if key == Qt.Key_Space:
            self.play()


        # Play from marker begin
        elif key == Qt.Key_E and self.marker_begin != None:
            self.mediaPlayer.setPosition(self.marker_begin)
            if self.marker_end:
                self.stop_at_marker_end = True
            if self.mediaPlayer.state() != QMediaPlayer.PlayingState:
                self.play()

        # Add marker
        elif key == Qt.Key_W:
            self.addMarker()


        # Remove all markers
        elif key == Qt.Key_S:
            self.delete_marker()

        # elif key == Qt.Key_Q:
        #     if self.marker_begin != None and self.marker_end != None:
        #         self.saved_markers.append([self.marker_begin, self.marker_end])
        #     self.delete_marker()

        # Time skipping
        elif key == Qt.Key_Left:
            # Scrub right N miliseconds
            self.current_pos -= 30
            self.mediaPlayer.setPosition(self.current_pos)

        elif key == Qt.Key_Right:
            self.current_pos += 30
            self.mediaPlayer.setPosition(self.current_pos)

        elif key == Qt.Key_D:
            self.nextVid()

        elif key == Qt.Key_A:
            self.previousVid()

        elif key == Qt.Key_R:
            self.toggleFileList()

        elif key == Qt.Key_J:
            self.convertToMp4()

        elif key == Qt.Key_T:
            self.showShortcuts()
Exemple #4
0
class MainWindow(QMainWindow):
    def __init__(self):

        # inicializar UI
        super(MainWindow, self).__init__()
        loadUi("SI_main.ui", self)

        # variables
        self.ruta = ""
        self.dir = ""
        self.txt_org.setText(
            "Texto no procesado. Por favor, inicie un video para procesar")
        self.txt_mod.setText(
            "Texto no procesado. Por favor, inicie un video para procesar")
        self.txt_tag.setText(
            "No hay texto modificado, por lo que no se pueden añadir tags. Por favor, inicie un video para procesar"
        )

        # definir elementos de la UI y acciones/funciones asociadas
        self.setWindowTitle("Speech to text from .mp4")

        # Video y Media Player
        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer()

        # Botones video
        self.search_button.clicked.connect(self.openFile)
        self.play_button.clicked.connect(self.play_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)

        self.play_button.setEnabled(False)
        self.stop_button.setEnabled(False)

        # Controles video
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(self.media_player.volume())
        self.seek_slider.sliderMoved.connect(self.media_player.setPosition)
        self.volume_slider.sliderMoved.connect(self.media_player.setVolume)
        self.media_player.positionChanged.connect(self.seek_slider.setValue)
        self.media_player.durationChanged.connect(
            partial(self.seek_slider.setRange, 0))
        self.media_player.stateChanged.connect(self.state_changed)
        self.video_widget.installEventFilter(self)

        #Textos: Botones y campos de texto
        self.save_button_org.clicked.connect(self.save_txt_org)
        self.save_button_mod.clicked.connect(self.save_txt_mod)
        self.save_button_tag.clicked.connect(self.save_txt_tag)
        self.procesar_txt_button.clicked.connect(self.procesar_txt)

    # pulsar boton play
    def play_clicked(self):
        if (self.media_player.state()
                in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)):
            print("Lets go")
            self.media_player.play()

            #generar pista audio a partir del video
            videoclip = VideoFileClip(self.dir + "/" + self.ruta)
            videoclip.audio.write_audiofile("resultados/audio/" +
                                            str(self.ruta.split(".")[0]) +
                                            "_audio.wav",
                                            codec='pcm_s16le')
            print(videoclip)

            #limpieza de audio
            r = sr.Recognizer()
            with sr.AudioFile("resultados/audio/" +
                              str(self.ruta.split(".")[0]) +
                              "_audio.wav") as source:

                r.adjust_for_ambient_noise(source, 0.75)
                audio_clr = r.record(source)

                #clean_audio = AudioClip(audio_data)
                #videoclip.audio.write_audiofile(self.dir+"/"+"audio.wav",codec='pcm_s16le')

                # conversion speech to text
                text = r.recognize_google(audio_clr, language="es-ES")
                print(text)
                #source.write(audio_clr)
                # comprobar audio limpiado
                self.txt_org.setText(text)
                self.txt_mod.setText(text)
                self.save_button_org.setEnabled(True)
                self.save_button_mod.setEnabled(True)
                self.procesar_txt_button.setEnabled(True)
            #txt_org = r.recognize_google(audio_clr)
            #print(txt_org)

        else:
            self.media_player.pause()

    # pulsar boton stop
    def stop_clicked(self):
        self.media_player.stop()

    # pulsar botones Guardar
    def save_txt_org(self):
        txt_to_save = open(
            "resultados/texto/" + str(self.ruta.split(".")[0]) +
            "_Texto_Original.txt", 'w')
        txt_to_save.write(self.txt_org.toPlainText())
        txt_to_save.close()

    def save_txt_mod(self):
        txt_to_save = open(
            "resultados/texto/" + str(self.ruta.split(".")[0]) +
            "_Texto_Modificado.txt", 'w')
        txt_to_save.write(self.txt_mod.toPlainText())
        txt_to_save.close()

    def save_txt_tag(self):
        txt_to_save = open(
            "resultados/texto/" + str(self.ruta.split(".")[0]) +
            "_Texto_Con_Tags.txt", 'w')
        txt_to_save.write(self.txt_tag.toPlainText())
        txt_to_save.close()

    # pulsar boton procesar texto
    def procesar_txt(self):
        self.txt_tag.setText(
            pruebaBusqueda.procesarTxt(self.txt_mod.toPlainText()))
        self.save_button_tag.setEnabled(True)

    # manejo pause/play del video
    def state_changed(self, newstate):
        states = {
            QMediaPlayer.PausedState: "Continuar",
            QMediaPlayer.PlayingState: "Pausa",
            QMediaPlayer.StoppedState: "Reproducir"
        }
        self.play_button.setText(states[newstate])
        self.stop_button.setEnabled(newstate != QMediaPlayer.StoppedState)

    # Video pantalla completa doble click
    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseButtonDblClick:
            obj.setFullScreen(not obj.isFullScreen())
        return False

    # Abrir archivo de video
    def openFile(self):
        print("Done")
        fileName, _ = QFileDialog.getOpenFileName(self, "Archivo de video",
                                                  '/home')
        if fileName != '':
            ruta = fileName.split("/")
            #print(ruta)
            videoName = fileName.split("/")[-1]

            for i in ruta[:-1]:
                if (i == ruta[0]):
                    self.dir = i
                else:
                    self.dir = self.dir + "/" + i

            self.vidLayout.addWidget(self.video_widget)
            self.title_label.setText(' VIDEO: {}'.format(videoName))
            self.ruta = videoName
            VIDEO_PATH = fileName
            self.media_player.setMedia(
                QMediaContent(QUrl.fromLocalFile(VIDEO_PATH)))

            self.media_player.setVideoOutput(self.video_widget)
            self.video_widget.setGeometry(30, 30, 700, 300)

            self.play_button.setEnabled(True)
            self.stop_button.setEnabled(True)