Beispiel #1
0
class Player(QGraphicsVideoItem):
    def __init__(self, parent=None):
        super().__init__()
        self.parent = parent

        self.player = QMediaPlayer()
        self.player.setVideoOutput(self)

    def playerPlayOrOpen(self, arg=None):
        if type(arg) == list and len(arg) > 1:
            content = QMediaContent(QUrl.fromLocalFile(arg[1]))
            self.player.setMedia(content)
            self.play()

    def addVideo(self, video):
        content = QMediaContent(QUrl.fromLocalFile(video))
        self.player.setMedia(content)
        self.play()

    def sliderChanged(self, pos):
        self.player.setPosition(pos)

    def mouseDoubleClickEvent(self, event):
        if not self.parent.isFullScreen():
            self.parent.showFullScreen()
        else:
            self.parent.showNormal()

    def play(self):
        self.player.play()

    def stop(self):
        self.player.stop()

    def pause(self):
        self.player.pause()

    def setMuted(self, mute):
        self.player.setMuted(mute)

    def mutedState(self):
        if self.player.isMuted():
            self.setMuted(False)
        else:
            self.setMuted(True)

    def isMuted(self):
        return  self.player.isMuted()

    def setVolume(self, value):
        self.player.setVolume(value)

    def volume(self):
        return self.player.volume()
Beispiel #2
0
class Player(QGraphicsVideoItem):
    def __init__(self, parent=None):
        super().__init__()
        self.parent = parent

        self.player = QMediaPlayer()
        self.player.setVideoOutput(self)

    def playerPlayOrOpen(self, arg=None):
        if type(arg) == list and len(arg) > 1:
            content = QMediaContent(QUrl.fromLocalFile(arg[1]))
            self.player.setMedia(content)
            self.play()

    def addVideo(self, video):
        content = QMediaContent(QUrl.fromLocalFile(video))
        self.player.setMedia(content)
        self.play()

    def sliderChanged(self, pos):
        self.player.setPosition(pos)

    def mouseDoubleClickEvent(self, event):
        if not self.parent.isFullScreen():
            self.parent.showFullScreen()
        else:
            self.parent.showNormal()

    def play(self):
        self.player.play()

    def stop(self):
        self.player.stop()

    def pause(self):
        self.player.pause()

    def setMuted(self, mute):
        self.player.setMuted(mute)

    def mutedState(self):
        if self.player.isMuted():
            self.setMuted(False)
        else:
            self.setMuted(True)

    def isMuted(self):
        return self.player.isMuted()

    def setVolume(self, value):
        self.player.setVolume(value)

    def volume(self):
        return self.player.volume()
Beispiel #3
0
class Player(QWidget):

    fullScreenChanged = pyqtSignal(bool)

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

        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)

        self.videoWidget = VideoWidget()
        self.player.setVideoOutput(self.videoWidget)

        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)

        self.playlistView = QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(
            self.playlistModel.index(self.playlist.currentIndex(), 0))

        self.playlistView.activated.connect(self.jump)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)

        #        self.labelHistogram = QLabel()
        #        self.labelHistogram.setText("Histogram:")
        #        self.histogram = HistogramWidget()
        #        histogramLayout = QHBoxLayout()
        #        histogramLayout.addWidget(self.labelHistogram)
        #        histogramLayout.addWidget(self.histogram, 1)

        self.probe = QVideoProbe()
        #        self.probe.videoFrameProbed.connect(self.histogram.processFrame)
        self.probe.setSource(self.player)

        openButton = QPushButton("打开", clicked=self.open)

        controls = PlayerControls()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())
        controls.setMuted(controls.isMuted())

        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeMuting.connect(self.player.setMuted)
        controls.changeRate.connect(self.player.setPlaybackRate)
        controls.stop.connect(self.videoWidget.update)

        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)
        self.player.mutedChanged.connect(controls.setMuted)

        self.fullScreenButton = QPushButton("全屏")
        self.fullScreenButton.setCheckable(True)

        self.colorButton = QPushButton("颜色选项")
        self.colorButton.setEnabled(False)
        self.colorButton.clicked.connect(self.showColorDialog)

        displayLayout = QHBoxLayout()
        displayLayout.addWidget(self.videoWidget, 2)
        displayLayout.addWidget(self.playlistView)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addStretch(1)
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        controlLayout.addWidget(self.fullScreenButton)
        controlLayout.addWidget(self.colorButton)

        layout = QVBoxLayout()
        layout.addLayout(displayLayout)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)
        #        layout.addLayout(histogramLayout)

        self.setLayout(layout)

        if not self.player.isAvailable():
            QMessageBox.warning(
                self, "Service not available",
                "The QMediaPlayer object does not have a valid service.\n"
                "Please check the media service plugins are installed.")

            controls.setEnabled(False)
            self.playlistView.setEnabled(False)
            openButton.setEnabled(False)
            self.colorButton.setEnabled(False)
            self.fullScreenButton.setEnabled(False)

        self.metaDataChanged()

        self.addToPlaylist(playlist)

    def open(self):
        fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files")
        self.addToPlaylist(fileNames)

    def addToPlaylist(self, fileNames):
        for name in fileNames:
            fileInfo = QFileInfo(name)
            if fileInfo.exists():
                url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
                if fileInfo.suffix().lower() == 'm3u':
                    self.playlist.load(url)
                else:
                    self.playlist.addMedia(QMediaContent(url))
            else:
                url = QUrl(name)
                if url.isValid():
                    self.playlist.addMedia(QMediaContent(url))

    def durationChanged(self, duration):
        duration /= 1000

        self.duration = duration
        self.slider.setMaximum(duration)

    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)

        self.updateDurationInfo(progress)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo(
                "%s - %s" % (self.player.metaData(QMediaMetaData.AlbumArtist),
                             self.player.metaData(QMediaMetaData.Title)))

    def previousClicked(self):
        # Go to the previous track if we are within the first 5 seconds of
        # playback.  Otherwise, seek to the beginning.
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)

    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()

    def playlistPositionChanged(self, position):
        self.playlistView.setCurrentIndex(self.playlistModel.index(
            position, 0))

    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)

    def statusChanged(self, status):
        self.handleCursor(status)

        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo("Loading...")
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo("Media Stalled")
        elif status == QMediaPlayer.EndOfMedia:
            QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo("")

    def handleCursor(self, status):
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia,
                      QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def bufferingProgress(self, progress):
        self.setStatusInfo("Buffering %d%" % progress)

    def videoAvailableChanged(self, available):
        if available:
            self.fullScreenButton.clicked.connect(
                self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.connect(
                self.fullScreenButton.setChecked)

            if self.fullScreenButton.isChecked():
                self.videoWidget.setFullScreen(True)
        else:
            self.fullScreenButton.clicked.disconnect(
                self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.disconnect(
                self.fullScreenButton.setChecked)

            self.videoWidget.setFullScreen(False)

        self.colorButton.setEnabled(available)

    def setTrackInfo(self, info):
        self.trackInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def setStatusInfo(self, info):
        self.statusInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def displayErrorMessage(self):
        self.setStatusInfo(self.player.errorString())

    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QTime((currentInfo / 3600) % 60,
                                (currentInfo / 60) % 60, currentInfo % 60,
                                (currentInfo * 1000) % 1000)
            totalTime = QTime((duration / 3600) % 60, (duration / 60) % 60,
                              duration % 60, (duration * 1000) % 1000)

            format = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            tStr = currentTime.toString(format) + " / " + totalTime.toString(
                format)
        else:
            tStr = ""

        self.labelDuration.setText(tStr)

    def showColorDialog(self):
        if self.colorDialog is None:
            brightnessSlider = QSlider(Qt.Horizontal)
            brightnessSlider.setRange(-100, 100)
            brightnessSlider.setValue(self.videoWidget.brightness())
            brightnessSlider.sliderMoved.connect(
                self.videoWidget.setBrightness)
            self.videoWidget.brightnessChanged.connect(
                brightnessSlider.setValue)

            contrastSlider = QSlider(Qt.Horizontal)
            contrastSlider.setRange(-100, 100)
            contrastSlider.setValue(self.videoWidget.contrast())
            contrastSlider.sliderMoved.connect(self.videoWidget.setContrast)
            self.videoWidget.contrastChanged.connect(contrastSlider.setValue)

            hueSlider = QSlider(Qt.Horizontal)
            hueSlider.setRange(-100, 100)
            hueSlider.setValue(self.videoWidget.hue())
            hueSlider.sliderMoved.connect(self.videoWidget.setHue)
            self.videoWidget.hueChanged.connect(hueSlider.setValue)

            saturationSlider = QSlider(Qt.Horizontal)
            saturationSlider.setRange(-100, 100)
            saturationSlider.setValue(self.videoWidget.saturation())
            saturationSlider.sliderMoved.connect(
                self.videoWidget.setSaturation)
            self.videoWidget.saturationChanged.connect(
                saturationSlider.setValue)

            layout = QFormLayout()
            layout.addRow("亮度", brightnessSlider)
            layout.addRow("对比度", contrastSlider)
            layout.addRow("色调", hueSlider)
            layout.addRow("饱和度", saturationSlider)

            button = QPushButton("关闭")
            layout.addRow(button)

            self.colorDialog = QDialog(self)
            self.colorDialog.setWindowTitle("颜色选项")
            self.colorDialog.setLayout(layout)

            button.clicked.connect(self.colorDialog.close)

        self.colorDialog.show()
Beispiel #4
0
class VideoPlayer(QWidget):

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

        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAcceptDrops(True)
        
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
        self.mediaPlayer.setVolume(80)
        
        self.videoWidget = QVideoWidget(self)
        self.videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.videoWidget.setMinimumSize(QSize(640, 360))
        
        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setFixedWidth(70)
        self.lbl.setUpdatesEnabled(True)
        self.lbl.setStyleSheet(stylesheet(self))

        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setFixedWidth(70)
        self.elbl.setUpdatesEnabled(True)
        self.elbl.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet(stylesheet(self))
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handleLabel)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)

        self.clip = QApplication.clipboard()
        self.process = QProcess(self)
        self.process.readyRead.connect(self.dataReady)
        self.process.finished.connect(self.playFromURL)

        self.myurl = ""

        # channel list
        self.channelList = QListView(self)
        self.channelList.setMinimumSize(QSize(150, 0))
        self.channelList.setMaximumSize(QSize(150, 4000))
        self.channelList.setFrameShape(QFrame.Box)
        self.channelList.setObjectName("channelList")
        self.channelList.setStyleSheet("background-color: black; color: #585858;")
        self.channelList.setFocus()
        # for adding items to list must create a model
        self.model = QStandardItemModel()
        self.channelList.setModel(self.model)

        self.controlLayout = QHBoxLayout()
        self.controlLayout.setContentsMargins(5, 0, 5, 0)
        self.controlLayout.addWidget(self.playButton)
        self.controlLayout.addWidget(self.lbl)
        self.controlLayout.addWidget(self.positionSlider)
        self.controlLayout.addWidget(self.elbl)

        self.mainLayout = QHBoxLayout()

        # contains video and cotrol widgets to the left side
        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.videoWidget)
        self.layout.addLayout(self.controlLayout)
        
        # adds channels list to the right
        self.mainLayout.addLayout(self.layout)
        self.mainLayout.addWidget(self.channelList)

        self.setLayout(self.mainLayout)

        self.myinfo = "©2020\nTIVOpy v1.0"

        self.widescreen = True

        #### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence("u"), self)
        self.shortcut.activated.connect(self.playFromURL)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Space), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_F), self)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self)
        self.shortcut.activated.connect(self.exitFullscreen)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handleInfo)
        self.shortcut = QShortcut(QKeySequence("s"), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)

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

        self.populateChannelList()
        self.selectChannel()
        self.initialPlay()

    def playFromURL(self):
        self.mediaPlayer.pause()
        self.myurl = self.clip.text()
        self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()
        self.hideSlider()
        print(self.myurl)

    def dataReady(self):
        self.myurl = str(self.process.readAll(), encoding='utf8').rstrip()  ###
        self.myurl = self.myurl.partition("\n")[0]
        print(self.myurl)
        self.clip.setText(self.myurl)
        self.playFromURL()

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

    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)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

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

    def handleError(self):
        self.playButton.setEnabled(False)
        print("Error: ", self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        print("Goodbye ...")
        app.quit()

    def contextMenuRequested(self, point):
        menu = QMenu()
        actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)")
        menu.addSeparator()
        actionToggle = menu.addAction(QIcon.fromTheme("next"), "Show / Hide Channels (s)")
        actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)")
        menu.addSeparator()
        actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "About (i)")
        menu.addSeparator()
        actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)")

        actionQuit.triggered.connect(self.handleQuit)
        actionFull.triggered.connect(self.handleFullscreen)
        actionInfo.triggered.connect(self.handleInfo)
        actionToggle.triggered.connect(self.toggleSlider)
        actionURL.triggered.connect(self.playFromURL)
        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self, event):
        mscale = event.angleDelta().y() / 13
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + mscale)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def mouseDoubleClickEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.handleFullscreen()

    def handleFullscreen(self):
        if self.windowState() and Qt.WindowFullScreen:
            self.showNormal()
        else:
            self.showFullScreen()

    def exitFullscreen(self):
        self.showNormal()

    def handleInfo(self):
        QMessageBox.about(self, "About", self.myinfo)

    def toggleSlider(self):
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()

    def hideSlider(self):
        self.channelList.hide()
        self.playButton.hide()
        self.lbl.hide()
        self.positionSlider.hide()
        self.elbl.hide()

    def showSlider(self):
        self.channelList.show()
        self.playButton.show()
        self.lbl.show()
        self.positionSlider.show()
        self.elbl.show()
        self.channelList.setFocus()

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasText():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        print("drop")
        if event.mimeData().hasUrls():
            url = event.mimeData().urls()[0].toString()
            print("url = ", url)
            self.mediaPlayer.stop()
            self.mediaPlayer.setMedia(QMediaContent(QUrl(url)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
        elif event.mimeData().hasText():
            mydrop = event.mimeData().text()
            print("generic url = ", mydrop)
            self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
            self.hideSlider()

    def loadFilm(self, f):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()

    def populateChannelList(self):
        # file must be in same directory as the script
        FILEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "canaletv.txt")
        # lines from file with "channel name" -- "link"
        channelArray = []
        # split file by line and adding it to the array
        with open(FILEPATH) as f:
            for line in f:
                channelArray.append(line.rstrip())
        # dictionary with key = channel name and value = link
        self.channelDict = dict(ch.split(" -- ") for ch in channelArray)
        for channel in self.channelDict.keys():
            item = QStandardItem(channel)
            self.model.appendRow(item)

    def selectedItemBehavior(self, index):
    # gets the link for the selected channel and plays it
        itms = self.channelList.selectedIndexes()
        for it in itms:
            channel = it.data()
            link = self.channelDict[channel]
            self.mediaPlayer.setMedia(QMediaContent(QUrl(link)))
            self.play()

    def selectChannel(self):
    # selecting channel from sidebar calls selectedItemBehavior
        self.selModel = self.channelList.selectionModel()
        self.selModel.selectionChanged.connect(self.selectedItemBehavior)

    def initialPlay(self):
    # play somenting when app opens
        self.mediaPlayer.setMedia(QMediaContent(QUrl("https://vid.hls.protv.ro/proxhdn/proxhd_3_34/index.m3u8?1")))
        self.play()

    def handleLabel(self):
        self.lbl.clear()
        mtime = QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(self.time.toString())
Beispiel #5
0
class VideoPlayer(QWidget):
    def __init__(self, aPath, parent=None):
        super(VideoPlayer, self).__init__(parent)

        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAcceptDrops(True)
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
        self.mediaPlayer.mediaStatusChanged.connect(self.printMediaData)
        self.mediaPlayer.setVolume(80)
        self.videoWidget = QVideoWidget(self)

        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setFixedWidth(70)
        self.lbl.setUpdatesEnabled(True)
        self.lbl.setStyleSheet(stylesheet(self))

        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setFixedWidth(70)
        self.elbl.setUpdatesEnabled(True)
        self.elbl.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet(stylesheet(self))
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handleLabel)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)

        self.clip = QApplication.clipboard()
        self.process = QProcess(self)
        self.process.readyRead.connect(self.dataReady)
        #        self.process.started.connect(lambda: print("grabbing YouTube URL"))
        self.process.finished.connect(self.playFromURL)

        self.myurl = ""

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(5, 0, 5, 0)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.lbl)
        controlLayout.addWidget(self.positionSlider)
        controlLayout.addWidget(self.elbl)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.videoWidget)
        layout.addLayout(controlLayout)

        self.setLayout(layout)

        self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \
            "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \
                "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes"

        self.widescreen = True

        #### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence("u"), self)
        self.shortcut.activated.connect(self.playFromURL)

        self.shortcut = QShortcut(QKeySequence("y"), self)
        self.shortcut.activated.connect(self.getYTUrl)

        self.shortcut = QShortcut(QKeySequence("o"), self)
        self.shortcut.activated.connect(self.openFile)
        self.shortcut = QShortcut(QKeySequence(" "), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence("f"), self)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handleInfo)
        self.shortcut = QShortcut(QKeySequence("s"), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volumeUp)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volumeDown)
        self.shortcut = QShortcut(
            QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider10)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left),
                                  self)
        self.shortcut.activated.connect(self.backSlider10)

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

        print("QT5 Player started")
        self.suspend_screensaver()
        #        msg = QMessageBox.information(self, "Qt5Player", "press o to open file")
        self.loadFilm("/home/brian/Dokumente/Qt5PlayerIntro.m4v")

    def playFromURL(self):
        self.mediaPlayer.pause()
        self.myurl = self.clip.text()
        self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()
        self.hideSlider()
        print(self.myurl)

    def getYTUrl(self):
        cmd = "youtube-dl -g -f best " + self.clip.text()
        print("grabbing YouTube URL")
        self.process.start(cmd)

    def dataReady(self):
        self.myurl = str(self.process.readAll(), encoding='utf8').rstrip()  ###
        self.myurl = self.myurl.partition("\n")[0]
        print(self.myurl)
        self.clip.setText(self.myurl)
        self.playFromURL()

    def suspend_screensaver(self):
        'suspend linux screensaver'
        proc = subprocess.Popen(
            'gsettings set org.gnome.desktop.screensaver idle-activation-enabled false',
            shell=True)
        proc.wait()

    def resume_screensaver(self):
        'resume linux screensaver'
        proc = subprocess.Popen(
            'gsettings set org.gnome.desktop.screensaver idle-activation-enabled true',
            shell=True)
        proc.wait()

    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Open Movie",
            QDir.homePath() + "/Videos",
            "Media (*.webm *.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v *.3gp *.mp3 *.m4a *.wav *.ogg *.flac *.m3u *.m3u8)"
        )

        if fileName != '':
            self.loadFilm(fileName)
            print("File loaded")

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

    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)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

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

    def handleError(self):
        self.playButton.setEnabled(False)
        print("Error: ", self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        self.resume_screensaver()
        print("Goodbye ...")
        app.quit()

    def contextMenuRequested(self, point):
        menu = QMenu()
        actionFile = menu.addAction(QIcon.fromTheme("video-x-generic"),
                                    "open File (o)")
        actionclipboard = menu.addSeparator()
        actionURL = menu.addAction(QIcon.fromTheme("browser"),
                                   "URL from Clipboard (u)")
        actionclipboard = menu.addSeparator()
        actionYTurl = menu.addAction(QIcon.fromTheme("youtube"),
                                     "URL from YouTube (y)")
        actionclipboard = menu.addSeparator()
        actionToggle = menu.addAction(QIcon.fromTheme("next"),
                                      "show / hide Slider (s)")
        actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"),
                                    "Fullscreen (f)")
        action169 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "16 : 9")
        action43 = menu.addAction(QIcon.fromTheme("tv-symbolic"), "4 : 3")
        actionSep = menu.addSeparator()
        actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "Info (i)")
        action5 = menu.addSeparator()
        actionQuit = menu.addAction(QIcon.fromTheme("application-exit"),
                                    "Exit (q)")

        actionFile.triggered.connect(self.openFile)
        actionQuit.triggered.connect(self.handleQuit)
        actionFull.triggered.connect(self.handleFullscreen)
        actionInfo.triggered.connect(self.handleInfo)
        actionToggle.triggered.connect(self.toggleSlider)
        actionURL.triggered.connect(self.playFromURL)
        actionYTurl.triggered.connect(self.getYTUrl)
        action169.triggered.connect(self.screen169)
        action43.triggered.connect(self.screen43)
        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self, event):
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mscale = event.angleDelta().y() / 5
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth + mscale,
                             (mwidth + mscale) / 1.778)
        else:
            self.setGeometry(mleft, mtop, mwidth + mscale,
                             (mwidth + mscale) / 1.33)

    def screen169(self):
        self.widescreen = True
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.778
        self.setGeometry(mleft, mtop, mwidth, mwidth / mratio)

    def screen43(self):
        self.widescreen = False
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.33
        self.setGeometry(mleft, mtop, mwidth, mwidth / mratio)

    def handleFullscreen(self):
        if self.windowState() & Qt.WindowFullScreen:
            QApplication.setOverrideCursor(Qt.ArrowCursor)
            self.showNormal()
            print("no Fullscreen")
        else:
            self.showFullScreen()
            QApplication.setOverrideCursor(Qt.BlankCursor)
            print("Fullscreen entered")

    def handleInfo(self):
        msg = QMessageBox.about(self, "QT5 Player", self.myinfo)

    def toggleSlider(self):
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()

    def hideSlider(self):
        self.playButton.hide()
        self.lbl.hide()
        self.positionSlider.hide()
        self.elbl.hide()
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778)
        else:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33)

    def showSlider(self):
        self.playButton.show()
        self.lbl.show()
        self.positionSlider.show()
        self.elbl.show()
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55)
        else:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33)

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60)

    def forwardSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000 * 60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60)

    def backSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000 * 60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() \
                      - QPoint(self.frameGeometry().width() / 2, \
                                 self.frameGeometry().height() / 2))
            event.accept()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasText():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            url = event.mimeData().urls()[0].toString()
            print("url = ", url)
            self.mediaPlayer.stop()
            self.mediaPlayer.setMedia(QMediaContent(QUrl(url)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
        elif event.mimeData().hasText():
            mydrop = event.mimeData().text()
            ### YouTube url
            if "youtube" in mydrop:
                print("is YouTube", mydrop)
                self.clip.setText(mydrop)
                self.getYTUrl()
            else:
                ### normal url
                print("generic url = ", mydrop)
                self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop)))
                self.playButton.setEnabled(True)
                self.mediaPlayer.play()
                self.hideSlider()

    def loadFilm(self, f):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()

    def printMediaData(self):
        if self.mediaPlayer.mediaStatus() == 6:
            if self.mediaPlayer.isMetaDataAvailable():
                res = str(self.mediaPlayer.metaData("Resolution")).partition(
                    "PyQt5.QtCore.QSize(")[2].replace(", ",
                                                      " x ").replace(")", "")
                print("%s%s" % ("Video Resolution = ", res))
            else:
                print("no metaData available")

    def openFileAtStart(self, filelist):
        matching = [s for s in filelist if ".myformat" in s]
        if len(matching) > 0:
            self.loadFilm(matching)

##################### update Label ##################################

    def handleLabel(self):
        self.lbl.clear()
        mtime = QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(self.time.toString())
Beispiel #6
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)
Beispiel #7
0
class Player(QGraphicsVideoItem):

    isSubtitle = pyqtSignal(bool)
    subtitlePos = pyqtSignal(int)

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

        self.player = QMediaPlayer()
        self.player.setVolume(int(settings().value("Player/volume") or 100))
        self.player.setVideoOutput(self)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.timerPos)

        self.player.currentMediaChanged.connect(self.signalStart)
        self.player.currentMediaChanged.connect(
            self.parent.subtitleitem.subtitleControl)
        self.player.currentMediaChanged.connect(self.videoConfigure)
        """self.player.mediaStatusChanged.connect(self.metadata)

    def metadata(self, data):
        if data and self.player.isMetaDataAvailable():
            print(self.player.metaData("VideoCodec"))"""

    def videoConfigure(self, media):
        video_name = os.path.basename(media.canonicalUrl().toLocalFile())
        videos = settings().value("Player/video_names") or []
        videos_time = settings().value("Player/videos_time") or []
        try:
            self.player.setPosition(int(videos_time[videos.index(video_name)]))
        except ValueError:
            pass

    def timerStart(self):
        self.timer.start(200)

    def signalStart(self, content):
        srt = content.canonicalUrl().toLocalFile().split(".")
        srt.pop(-1)
        srt.append("srt")
        srt = ".".join(srt)
        if QFile.exists(srt):
            self.isSubtitle.emit(True)
            self.timer.start(100)
        else:
            self.isSubtitle.emit(False)
            self.timer.stop()

    def timerPos(self):
        self.subtitlePos.emit(self.player.position())

    def playerPlayOrOpen(self, arg=None):
        if type(arg) == list and len(arg) > 1:
            content = QMediaContent(QUrl.fromLocalFile(arg[1]))
            self.player.setMedia(content)
            self.play()

    def addVideo(self, video):
        content = QMediaContent(QUrl.fromLocalFile(video))
        self.player.setMedia(content)
        self.play()

    def addYoutubeVideo(self, video):
        dm = DownloadManager(self)

        content = QMediaContent(dm.addUrl(video))
        self.player.setMedia(content)
        self.play()

    def sliderChanged(self, pos):
        self.player.setPosition(pos)

    def play(self):
        self.player.play()

    def stop(self):
        self.player.stop()

    def pause(self):
        self.player.pause()

    def setMuted(self, mute):
        self.player.setMuted(mute)

    def mutedState(self):
        if self.player.isMuted():
            self.setMuted(False)
        else:
            self.setMuted(True)

    def isMuted(self):
        return self.player.isMuted()

    def setVolume(self, value):
        self.player.setVolume(value)

    def volume(self):
        return self.player.volume()
Beispiel #8
0
class Player(QWidget):
 
    fullScreenChanged = pyqtSignal(bool)
 
    def __init__(self, playlist, parent=None):
        super(Player, self).__init__(parent)
 
        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0
 
        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)
 
        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)
 
        self.videoWidget = VideoWidget()
        self.player.setVideoOutput(self.videoWidget)
 
        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)
 
        self.playlistView = QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(self.playlist.currentIndex(), 0))
 
        self.playlistView.activated.connect(self.jump)

        self.script_box = QPlainTextEdit()
        self.segmentList = QTreeWidget()
        self.segmentList.setSortingEnabled(True)
        #self.segmentList.setColumnCount(5)
        self.segmentList.setColumnCount(4)
        #self.segmentList.setHeaderLabels(['Product','Start','Label','Tool','Behavior'])
        self.segmentList.setHeaderLabels(['Start segment', 'End segment', 'Label', 'Event'])

        '''
        self.productTextInput = QLineEdit()
        self.startTextInput = QLineEdit()
        self.labelTextInput = QLineEdit()
        self.toolTextInput = QLineEdit()
        self.behaviorTextInput = QLineEdit()
        '''
        self.startTextInput = QLineEdit()
        self.endTextInput = QLineEdit()
        self.labelTextInput = QLineEdit()
        self.contentTextInput = QLineEdit()

        self.addBtn = QPushButton("Add")
        self.addBtn.clicked.connect(self.addSegment)

        self.saveBtn = QPushButton("Save")
        self.saveBtn.clicked.connect(self.saveSegments)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)
 
        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)
 
        self.labelHistogram = QLabel()
        self.labelHistogram.setText("Histogram:")
        self.histogram = HistogramWidget()
        histogramLayout = QHBoxLayout()
        histogramLayout.addWidget(self.labelHistogram)
        histogramLayout.addWidget(self.histogram, 1)
 
        self.probe = QVideoProbe()
        self.probe.videoFrameProbed.connect(self.histogram.processFrame)
        self.probe.setSource(self.player)
 
        openButton = QPushButton("Open", clicked=self.open)
        if os.path.isdir(VIDEO_DIR):
            self.open_folder(VIDEO_DIR)

        controls = PlayerControls()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())
        controls.setMuted(controls.isMuted())
 
        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeMuting.connect(self.player.setMuted)
        controls.changeRate.connect(self.player.setPlaybackRate)
        controls.stop.connect(self.videoWidget.update)
 
        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)
        self.player.mutedChanged.connect(controls.setMuted)

        #self.segmentButton = QPushButton("Segment")
        #self.segmentButton.clicked.connect(self.createNewSegment)
        self.startSegmentButton = QPushButton("Start Segment")
        self.startSegmentButton.clicked.connect(self.createNewStartSegment)
        # self.segmentButton.setCheckable(True)

        self.endSegmentButton = QPushButton("End Segment")
        self.endSegmentButton.clicked.connect(self.createNewEndSegment)

        #self.fullScreenButton = QPushButton("FullScreen")
        #self.fullScreenButton.setCheckable(True)
 
        self.colorButton = QPushButton("Color Options...")
        self.colorButton.setEnabled(False)
        self.colorButton.clicked.connect(self.showColorDialog)
 
        displayLayout = QHBoxLayout()
        # videoLayout = QVBoxLayout()
        # videoLayout.addWidget(self.videoWidget)
        # videoLayout.addWidget(self.script_box)
        
        displayLayout.addWidget(self.videoWidget, 3)

        editLayout = QVBoxLayout()
        editLayout.addWidget(self.playlistView, 2)
        #editLayout.addWidget(self.script_box, 4)
        editLayout.addWidget(self.segmentList, 3)
        segmentInputLayout = QHBoxLayout()
        '''
        segmentInputLayout.addWidget(self.productTextInput)
        segmentInputLayout.addWidget(self.startTextInput)
        segmentInputLayout.addWidget(self.labelTextInput)
        segmentInputLayout.addWidget(self.toolTextInput)
        segmentInputLayout.addWidget(self.behaviorTextInput)
        '''
        segmentInputLayout.addWidget(self.startTextInput)
        segmentInputLayout.addWidget(self.endTextInput)
        segmentInputLayout.addWidget(self.labelTextInput)
        segmentInputLayout.addWidget(self.contentTextInput)

        editLayout.addLayout(segmentInputLayout,1)

        displayLayout.addLayout(editLayout, 2)
 
        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addStretch(1)
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        #controlLayout.addWidget(self.segmentButton)
        controlLayout.addWidget(self.startSegmentButton)
        controlLayout.addWidget(self.endSegmentButton)
        controlLayout.addWidget(self.addBtn)
        controlLayout.addWidget(self.saveBtn)
        #controlLayout.addWidget(self.fullScreenButton)
        # controlLayout.addWidget(self.colorButton)
 
        layout = QVBoxLayout()
        layout.addLayout(displayLayout, 2)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)
        # layout.addLayout(histogramLayout)
 
        self.setLayout(layout)
 
        if not self.player.isAvailable():
            QMessageBox.warning(self, "Service not available",
                    "The QMediaPlayer object does not have a valid service.\n"
                    "Please check the media service plugins are installed.")
 
            controls.setEnabled(False)
            self.playlistView.setEnabled(False)
            openButton.setEnabled(False)
            self.colorButton.setEnabled(False)
            #self.fullScreenButton.setEnabled(False)
 
        self.metaDataChanged()
 
        self.addToPlaylist(playlist)
    
    def open(self):
        fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files")
        self.addToPlaylist(fileNames)

    def open_folder(self, folder_path):
        fileNames = [folder_path+x for x in os.listdir(folder_path) if x.endswith('.mp4')]
        self.addToPlaylist(fileNames)
 
    def addToPlaylist(self, fileNames):
        for name in fileNames:
            fileInfo = QFileInfo(name)
            if fileInfo.exists():
                url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
                if fileInfo.suffix().lower() == 'm3u':
                    self.playlist.load(url)
                else:
                    self.playlist.addMedia(QMediaContent(url))
            else:
                url = QUrl(name)
                if url.isValid():
                    self.playlist.addMedia(QMediaContent(url))

    def addSegment(self):
        item = TreeWidgetItem(self.segmentList)
        '''
        item.setText(0, self.productTextInput.text())
        item.setText(1, self.startTextInput.text())
        item.setText(2, self.labelTextInput.text())
        item.setText(3, self.toolTextInput.text())
        item.setText(4, self.behaviorTextInput.text())
        '''

        item.setText(0, self.startTextInput.text())
        item.setText(1, self.endTextInput.text())
        item.setText(2, self.labelTextInput.text())
        item.setText(3, self.contentTextInput.text())

        item.setFlags(item.flags() | Qt.ItemIsEditable)
        self.segmentList.addTopLevelItem(item)
        self.segmentList.sortByColumn(0, Qt.AscendingOrder)

        self.clear_input_boxes()
        self.player.play()
    
    def saveSegments(self):
        itemCnt = self.segmentList.topLevelItemCount()
        colCnt = self.segmentList.columnCount()
        save_dict = {'segments':[]}

        for i in range(itemCnt):
            item = self.segmentList.topLevelItem(i)
            temp_data = []
            for j in range(colCnt):
                temp_data.append(item.text(j))
            #temp_dict = {'product': temp_data[0], 'start': temp_data[1], 'label': temp_data[2], 'tool': temp_data[3], 'behavior': temp_data[4]}

            if len(temp_data[0]) > 0 and len(temp_data[1]) > 0 and (':' in temp_data[0]) and (':' in temp_data[1]):

                start_interval_seconds = 0
                j = 0
                while j < len(temp_data[0].split(':')):
                    start_interval_seconds += (int(temp_data[0].split(':')[- 1 - j]) * (60 ** j))
                    j += 1

                end_interval_seconds = 0
                j = 0
                while j < len(temp_data[1].split(':')):
                    end_interval_seconds += (int(temp_data[1].split(':')[- 1 - j]) * (60 ** j))
                    j += 1

            else:
                start_interval_seconds = ''
                end_interval_seconds = ''

            temp_dict = {'start_segment': start_interval_seconds, 'end_segment': end_interval_seconds, 'label': temp_data[2], 'event': temp_data[3]}
            save_dict['segments'].append(temp_dict)
        
        import json
        file_name = self.playlist.currentMedia().canonicalUrl().fileName()
        with open(SEGMENT_DIR+file_name.replace('.mp4','.json'),'w') as file:
            json.dump(save_dict, file)

    def durationChanged(self, duration):
        duration /= 1000
 
        self.duration = duration
        self.slider.setMaximum(duration)
 
    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)
 
        self.updateDurationInfo(progress)
 
    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo("%s - %s" % (
                    self.player.metaData(QMediaMetaData.AlbumArtist),
                    self.player.metaData(QMediaMetaData.Title)))
 
    def previousClicked(self):
        # Go to the previous track if we are within the first 5 seconds of
        # playback.  Otherwise, seek to the beginning.
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)
    
    def clear_input_boxes(self):
        '''
        self.productTextInput.clear()
        self.startTextInput.clear()
        self.labelTextInput.clear()
        self.toolTextInput.clear()
        self.behaviorTextInput.clear()
        '''
        self.startTextInput.clear()
        self.endTextInput.clear()
        self.labelTextInput.clear()
        self.contentTextInput.clear()


    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()
            file_name = self.playlist.currentMedia().canonicalUrl().fileName()
            '''
            script_file_name = file_name.replace('.mp4','.txt')
            if os.path.isfile(SCRIPT_DIR+script_file_name):
                text=open(SCRIPT_DIR+script_file_name).read()
                self.script_box.setPlainText(text)
            '''

            segment_file_path = SEGMENT_DIR + file_name.replace('.mp4','.json')
            json_dict = self.open_json(segment_file_path)
            self.clear_input_boxes()
            self.segmentList.clear()
            for segment in json_dict["segments"]:
                item = TreeWidgetItem(self.segmentList)
                '''
                item.setText(0, segment['product'])
                item.setText(1, str(segment['start']))
                item.setText(2, segment['label'])
                item.setText(3, segment['tool'])
                item.setText(4, segment['behavior'])
                '''
                item.setText(0, segment['start_segment'])
                item.setText(1, segment['end_segment'])
                item.setText(2, segment['label'])
                item.setText(3, segment['content'])

                item.setFlags(item.flags() | Qt.ItemIsEditable)
                self.segmentList.addTopLevelItem(item)
                
            
            
            # print([str(x.text()) for x in self.segmentList.currentItem()])

    def open_json(self, file_path):
        import json
        try:
            with open(file_path, 'r') as file:
                json_dict = json.loads(file.read())
        except:
            json_dict = {"segments":[]}
            # json_dict = {"segments":[{"product":"Sorry","start":"File not found.","label":"","tool":"","behavior":""}]}
        return json_dict
    
    def playlistPositionChanged(self, position):
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(position, 0))
 
    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)
 
    def statusChanged(self, status):
        self.handleCursor(status)
 
        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo("Loading...")
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo("Media Stalled")
        elif status == QMediaPlayer.EndOfMedia:
            QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo("")
 
    def handleCursor(self, status):
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()
 
    def bufferingProgress(self, progress):
        self.setStatusInfo("Buffering %d%" % progress)
 
    def videoAvailableChanged(self, available):
        '''
        if available:
            self.fullScreenButton.clicked.connect(
                    self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.connect(
                    self.fullScreenButton.setChecked)
 
            if self.fullScreenButton.isChecked():
                self.videoWidget.setFullScreen(True)
        else:
            self.fullScreenButton.clicked.disconnect(
                    self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.disconnect(
                    self.fullScreenButton.setChecked)
 
            self.videoWidget.setFullScreen(False)

        '''
        self.colorButton.setEnabled(available)
 
    def setTrackInfo(self, info):
        self.trackInfo = info
 
        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)
 
    def setStatusInfo(self, info):
        self.statusInfo = info
 
        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)
 
    def displayErrorMessage(self):
        self.setStatusInfo(self.player.errorString())
 
    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QTime((currentInfo/3600)%60, (currentInfo/60)%60,
                    currentInfo%60, (currentInfo*1000)%1000)
            totalTime = QTime((duration/3600)%60, (duration/60)%60,
                    duration%60, (duration*1000)%1000);
 
            format = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            tStr = currentTime.toString(format) + " / " + totalTime.toString(format)
        else:
            tStr = ""
 
        self.labelDuration.setText(tStr)
    '''
    def createNewSegment(self):
        self.startTextInput.setText(str(int(self.player.position()/1000)))
    '''

    def createNewStartSegment(self):
        seconds = int(self.player.position()/1000)
        self.startTextInput.setText("{:02d}".format(math.floor(seconds / 3600)) + ':' + "{:02d}".format(
            math.floor((seconds / 60)) - math.floor(seconds / 3600) * 60) + ':' + "{:02d}".format(seconds % 60))

    def createNewEndSegment(self):
        seconds = int(self.player.position() / 1000)
        self.endTextInput.setText("{:02d}".format(math.floor(seconds / 3600)) + ':' + "{:02d}".format(
            math.floor((seconds / 60)) - math.floor(seconds / 3600) * 60) + ':' + "{:02d}".format(seconds % 60))
        self.player.pause()

    def showColorDialog(self):
        if self.colorDialog is None:
            brightnessSlider = QSlider(Qt.Horizontal)
            brightnessSlider.setRange(-100, 100)
            brightnessSlider.setValue(self.videoWidget.brightness())
            brightnessSlider.sliderMoved.connect(
                    self.videoWidget.setBrightness)
            self.videoWidget.brightnessChanged.connect(
                    brightnessSlider.setValue)
 
            contrastSlider = QSlider(Qt.Horizontal)
            contrastSlider.setRange(-100, 100)
            contrastSlider.setValue(self.videoWidget.contrast())
            contrastSlider.sliderMoved.connect(self.videoWidget.setContrast)
            self.videoWidget.contrastChanged.connect(contrastSlider.setValue)
 
            hueSlider = QSlider(Qt.Horizontal)
            hueSlider.setRange(-100, 100)
            hueSlider.setValue(self.videoWidget.hue())
            hueSlider.sliderMoved.connect(self.videoWidget.setHue)
            self.videoWidget.hueChanged.connect(hueSlider.setValue)
 
            saturationSlider = QSlider(Qt.Horizontal)
            saturationSlider.setRange(-100, 100)
            saturationSlider.setValue(self.videoWidget.saturation())
            saturationSlider.sliderMoved.connect(
                    self.videoWidget.setSaturation)
            self.videoWidget.saturationChanged.connect(
                    saturationSlider.setValue)
 
            layout = QFormLayout()
            layout.addRow("Brightness", brightnessSlider)
            layout.addRow("Contrast", contrastSlider)
            layout.addRow("Hue", hueSlider)
            layout.addRow("Saturation", saturationSlider)
 
            button = QPushButton("Close")
            layout.addRow(button)
 
            self.colorDialog = QDialog(self)
            self.colorDialog.setWindowTitle("Color Options")
            self.colorDialog.setLayout(layout)
 
            button.clicked.connect(self.colorDialog.close)
 
        self.colorDialog.show()
Beispiel #9
0
class VideoWindow(QMainWindow):
    """ Class:
    Video player window.
    """

    # Main window size.
    WIN_SIZE = [800, 600]

    def __init__(self, parent=None):
        """ Function:
        Setup user interface of Video player window.
        """

        super(VideoWindow, self).__init__(parent)
        self.setWindowTitle("Video player")
        self.resize(VideoWindow.WIN_SIZE[0], VideoWindow.WIN_SIZE[1])
        self.setWindowIcon(self.style().standardIcon(QStyle.SP_DriveDVDIcon))

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

        self.record_start_time = None
        self.record_end_time = None
        self.video_name = ""

        self.widget_video = QVideoWidget()

        self.statusbar = QtWidgets.QStatusBar(self)
        self.setStatusBar(self.statusbar)

        self.button_play = QPushButton()
        self.button_play.setEnabled(False)
        self.button_play.setIcon(self.style().standardIcon(
            QStyle.SP_MediaPlay))
        self.button_play.clicked.connect(self.play_video)

        self.video_slider = QSlider(Qt.Horizontal)
        self.video_slider.setRange(0, 0)
        self.video_slider.sliderMoved.connect(self.set_position)
        self.video_duration = 0

        # Action 'Open'.
        self.action_open = QAction(QIcon('open.png'), '&Open', self)
        self.action_open.setShortcut('Ctrl+O')
        self.action_open.setStatusTip('Open a video')
        self.action_open.triggered.connect(self.open_video)

        # Menu bar.
        self.menu_bar = self.menuBar()
        self.menu_menu = self.menu_bar.addMenu('&Menu')
        self.menu_menu.addAction(self.action_open)

        # Widget.
        self.widget_window = QWidget(self)
        self.setCentralWidget(self.widget_window)

        self.layout_operation = QHBoxLayout()
        self.layout_operation.setContentsMargins(0, 0, 0, 0)
        self.label_rotate = QLabel('Degree of rotation')
        self.combobox_degree = QComboBox()
        degrees = ['0', '90', '180', '270']
        self.combobox_degree.addItems(degrees)
        self.button_subclip_video = QPushButton('Subclip (Video)')
        self.button_subclip_audio = QPushButton('Subclip (Audio)')
        self.layout_operation.addWidget(self.label_rotate)
        self.layout_operation.addWidget(self.combobox_degree)
        self.layout_operation.addWidget(self.button_subclip_video)
        self.layout_operation.addWidget(self.button_subclip_audio)

        self.layout_record = QHBoxLayout()
        self.layout_record.setContentsMargins(0, 0, 0, 0)
        self.button_start = QPushButton('Start')
        self.button_end = QPushButton('End')
        self.button_clear = QPushButton('Clear')
        self.layout_record.addWidget(self.button_start)
        self.layout_record.addWidget(self.button_end)
        self.layout_record.addWidget(self.button_clear)

        self.button_start.clicked.connect(self.record_start)
        self.button_end.clicked.connect(self.record_end)
        self.button_subclip_video.clicked.connect(self.record_subclip_video)
        self.button_subclip_audio.clicked.connect(self.record_subclip_audio)
        self.button_clear.clicked.connect(self.record_clear)

        # Widget layout.
        self.layout_widget = QHBoxLayout()
        self.layout_widget.setContentsMargins(0, 0, 0, 0)
        self.layout_widget.addWidget(self.button_play)
        self.layout_widget.addWidget(self.video_slider)

        self.layout_window = QVBoxLayout()
        self.layout_window.addWidget(self.widget_video)
        self.layout_window.addLayout(self.layout_record)
        self.layout_window.addLayout(self.layout_operation)
        self.layout_window.addLayout(self.layout_widget)

        # Window layout.
        self.widget_window.setLayout(self.layout_window)

        self.video_player.setVideoOutput(self.widget_video)
        self.video_player.stateChanged.connect(self.media_state_changed)
        self.video_player.positionChanged.connect(self.position_changed)
        self.video_player.durationChanged.connect(self.duration_changed)
        self.video_player.error.connect(self.error_control)

        QShortcut(Qt.Key_Up, self, self.arrow_up)
        QShortcut(Qt.Key_Down, self, self.arrow_down)
        QShortcut(Qt.Key_Left, self, self.arrow_left_event)
        QShortcut(Qt.Key_Right, self, self.arrow_right_event)
        QShortcut(Qt.Key_Space, self, self.play_video)

    def arrow_up(self):
        if self.video_player.state() != QMediaPlayer.StoppedState:
            self.video_player.setVolume(
                min(self.video_player.volume() + 10, 100))

    def arrow_down(self):
        if self.video_player.state() != QMediaPlayer.StoppedState:
            self.video_player.setVolume(max(self.video_player.volume() - 10,
                                            0))

    def arrow_left_event(self):
        """ Slot function:
        Action after the key 'arrow left' is pressed.
        Fast-forward to 10 seconds later.
        """

        self.set_position(self.video_slider.value() - 10 * 1000)

    def arrow_right_event(self):
        """ Slot function:
        Action after the key 'arrow right' is pressed.
        Go back to 10 seconds ago.
        """

        self.set_position(self.video_slider.value() + 10 * 1000)

    def mousePressEvent(self, event):
        """ Slot function:
        The starting position of the slider is 50.
        Note: This function still can't not accurately move the slider to the 
        clicked position.
        """

        slider_start_pos = self.video_slider.geometry().topLeft().x()
        if 42 <= self.height() - event.pos().y() <= 62:
            position = self.video_slider.minimum() + (
                event.pos().x() - slider_start_pos
            ) / self.video_slider.width() * self.video_duration
            if position != self.video_slider.sliderPosition():
                self.set_position(position)

    def open_video(self):
        """ Slot function:
        Open a video from the file system.
        """

        video_name, _ = QFileDialog.getOpenFileName(self, "Open Movie",
                                                    QDir.homePath())
        self.video_name = video_name

        if video_name != '':
            self.video_player.setMedia(
                QMediaContent(QUrl.fromLocalFile(video_name)))
            self.button_play.setEnabled(True)
            self.video_player.play()

            index = video_name.rfind('/')
            self.statusbar.showMessage("Info: Playing the video '" +
                                       video_name[(index + 1):] + "' ...")

    def play_video(self):
        """ Slot function:
        The slot function for the 'play' button.
        If the video player is currently paused, then play the video; 
        otherwise, pause the video.
        """

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

    def media_state_changed(self, state):
        """ Slot function:
        If the playing state changes, change the icon for the 'play' button.
        If the video player is currently playing, change the icon to 'pause'; 
        otherwise, change the icon to 'play'.
        """

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

    def position_changed(self, position):
        """ Slot function:
        Change the position of the slider.
        """

        self.video_slider.setValue(position)

    def duration_changed(self, duration):
        """ Slot function:
        If the duration of the video changed, change the range of the slider.
        This slot function is called after opening a video.
        """

        self.video_slider.setRange(0, duration)
        self.video_duration = duration
        self.record_start_time = 0
        self.record_end_time = 0

    def set_position(self, position):
        """ Slot function:
        Change the progress of the video.
        """

        self.video_player.setPosition(position)

    def error_control(self):
        """ Slot function:
        If an error occurs while opening the video, this slot function is 
        called.
        """

        self.button_play.setEnabled(False)
        self.statusbar.showMessage(
            "Error: An error occurs while opening the video.")

    def record_start(self):
        self.record_start_time = self.video_slider.sliderPosition()
        if self.record_end_time is not None and self.record_end_time != 0 and self.record_start_time > self.record_end_time:
            self.record_start_time, self.record_end_time = self.record_end_time, self.record_start_time

        self._show_record_time()

    def record_end(self):
        self.record_end_time = self.video_slider.sliderPosition()
        if self.record_start_time is not None and self.record_start_time > self.record_end_time:
            self.record_start_time, self.record_end_time = self.record_end_time, self.record_start_time

        self._show_record_time()

    def _show_record_time(self):
        if self.record_start_time is not None and self.record_end_time is not None:
            self.statusbar.showMessage(
                "Info: Starting time: ({}), and Ending time: ({}) (Duration: {})."
                .format(self.record_start_time / 1000,
                        self.record_end_time / 1000,
                        self.video_duration / 1000))

    def _check_duration(self):
        if self.video_name == "":
            self.statusbar.showMessage("Error: Please open a video first.")
        elif self.record_start_time == self.record_end_time:
            self.statusbar.showMessage("Error: Duration can NOT be 0.")
        elif self.record_start_time > self.record_end_time:
            self.statusbar.showMessage(
                "Error: The start time should be earlier than the end time.")
        else:
            return True

        return False

    def record_subclip_video(self):
        if self._check_duration():
            self.statusbar.showMessage(
                "Info: Please wait until the process ends.")
            self.thread = Thread()
            self.thread.set_params(Thread.MSG_CUT_VIDEO, self.video_name,
                                   self.record_start_time / 1000,
                                   self.record_end_time / 1000,
                                   self.combobox_degree.currentText())
            self.thread.signal_return_value.connect(self.thread_done)
            self.thread.start()

    def record_subclip_audio(self):
        if self._check_duration():
            self.statusbar.showMessage(
                "Info: Please wait until the process ends.")
            self.thread = Thread()
            self.thread.set_params(Thread.MSG_EXTRACT_AUDIO, self.video_name,
                                   self.record_start_time / 1000,
                                   self.record_end_time / 1000)
            self.thread.signal_return_value.connect(self.thread_done)
            self.thread.start()

    def record_clear(self):
        self.record_start_time = 0
        self.record_end_time = 0

        self.statusbar.showMessage(
            "Info: Starting time: ({}), and Ending time: ({}).".format(
                self.record_start_time, self.record_end_time))

    def thread_done(self, return_value, video_name):
        if return_value:
            self.statusbar.showMessage(
                "Info: The process has done and saved as {}.".format(
                    video_name))
Beispiel #10
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
Beispiel #11
0
class Player(QWidget):
    """Sub-class of QWidget"""
    def __init__(self, parent=None, *args, **kwargs):
        """Initialize class attributes"""
        super(Player, self).__init__(parent, *args, **kwargs)
        self.init_ui()

    def init_ui(self):
        """Create local components"""
        # loop
        self.loop = False
        # time label text
        self.time_text = '{:0>2d}:{:0>2d}:{:0>2d}/{:0>2d}:{:0>2d}:{:0>2d}'
        self.hours = self.minutes = self.seconds = 0
        # create media player object
        self.mediaPlayer = QMediaPlayer(self, QMediaPlayer.VideoSurface)
        # create videowidget object
        self.videoWidget = QVideoWidget()

        # create open button
        self.btn_size = QSize(16, 16)
        openButton = Button("Open")
        openButton.setToolTip("Open Media File")
        openButton.setStatusTip("Open Media File")
        openButton.setFixedHeight(24)
        openButton.setIconSize(self.btn_size)
        openButton.setIcon(
            QIcon.fromTheme("document-open", QIcon("Icons/Open.bmp")))
        # openButton.setStyleSheet("background-color: #B0C4DE")
        openButton.clicked.connect(self.abrir)

        # create play button
        self.playButton = Button()
        self.playButton.setEnabled(False)
        self.playButton.setFixedHeight(24)
        self.playButton.setIconSize(self.btn_size)
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        # self.playButton.setStyleSheet("background-color: #B0C4DE")
        self.playButton.clicked.connect(self.play)

        # create slider
        self.positionSlider = PositionSlider(self.mediaPlayer, Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.setObjectName("positionSlider")

        # create status bar
        self.statusBar = QStatusBar()
        self.statusBar.setFont(QFont("Noto sans", 8))
        self.statusBar.setFixedHeight(14)
        self.statusBar.setStyleSheet('color:#ffffff')

        # create duration time label
        self.durationLabel = QLabel()
        self.durationLabel.setStyleSheet(
            'background-color:rgba(255, 255, 255, 0)')
        self.durationLabel.setText('00:00:00/00:00:00')

        # create hbox layout
        controlLayoutWidget = QWidget(self)
        controlLayout = QHBoxLayout(controlLayoutWidget)
        controlLayoutWidget.setLayout(controlLayout)
        controlLayout.setContentsMargins(2, 2, 2, 2)
        # set widgets to the hbox layout
        controlLayout.addWidget(openButton)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.positionSlider)
        controlLayout.addWidget(self.durationLabel)
        # change hbox color
        controlLayoutWidget.setStyleSheet(
            'background-color:rgba(255, 255, 255, 50)')
        controlLayoutWidget.setWindowOpacity(0.1)

        # create vbox layout
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        # set widgets to vbox layout
        self.layout.addWidget(self.videoWidget)
        self.layout.addWidget(controlLayoutWidget)
        self.sub_controls()
        self.layout.addWidget(self.statusBar)

        self.setLayout(self.layout)

        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.statusBar.showMessage('{:->33s}{:-<33s}'.format("Have Fun", ""))
        self.key_bindings()

    def key_bindings(self):
        # bind Keys to methods
        self.onplaypause = self.create_shortcut(Qt.Key_Space, self.videoWidget,
                                                self.play)  # Space key for

        self.on_fscreen = self.create_shortcut(
            Qt.Key_F, self.videoWidget,
            self.toggle_fullscreen)  # F key for fullscreen on

        self.onforward = self.create_shortcut(
            Qt.Key_Right, self.videoWidget,
            self.forward)  # Right key for forward

        self.redvolume = self.create_shortcut(
            Qt.Key_Down, self.videoWidget,
            self.red_volume)  # Down key reduce volume

        self.incvolume = self.create_shortcut(
            Qt.Key_Up, self.videoWidget,
            self.inc_volume)  # Up key increase volume

        self.onsetloop = self.create_shortcut(
            "L",
            self.videoWidget,  # L key for repeat on,
            (lambda self=self: self.repeat.toggle() or self.play_again()))

        self.onrewind = self.create_shortcut(
            Qt.Key_Left, self.videoWidget, self.rewind)  # Left key for rewind

        self.volmute = self.create_shortcut(Qt.Key_M, self.videoWidget,
                                            self.mute)  # M for mute and unmute

        self.onopen = self.create_shortcut('Ctrl+O', self.videoWidget,
                                           self.abrir)  # Ctrl+O for open

        self.onstop = self.create_shortcut(Qt.Key_S, self.videoWidget,
                                           self.stop_media)  # S key for stop

    def create_shortcut(self, sequence, widget, obj):
        """generate key shortcuts"""
        return QShortcut(QKeySequence(sequence),
                         widget,
                         obj,
                         context=Qt.ApplicationShortcut)

    def sub_controls(self):
        """Repeat, volume, and mute controls"""
        # repeat button
        self.repeat = Button()
        self.repeat.setCheckable(True)
        self.repeat.toggle()
        self.repeat.setIconSize(self.btn_size)
        self.repeat.setFixedHeight(24)
        self.repeat.setFixedWidth(26)
        self.repeat.setToolTip("repeat")
        self.repeat.setStatusTip("repeat")

        # Icons to correspond with button state
        icon = QIcon()
        icon.addPixmap(QPixmap(os.path.join(FOLDER, "Icons/repeat(1).png")),
                       QIcon.Normal, QIcon.On)
        icon.addPixmap(QPixmap(os.path.join(FOLDER, "Icons/repeat(2).png")),
                       QIcon.Active)
        self.repeat.setIcon(icon)
        # self.repeat.setStyleSheet("background-color: #B0C4DE; margin: 0px 0px 0px 2px;")
        self.repeat.clicked.connect(self.play_again)

        # stop button
        self.stop = Button()
        self.stop.setIconSize(self.btn_size)
        self.stop.setFixedHeight(24)
        self.stop.setFixedWidth(26)
        self.stop.setToolTip("Stop playing media")
        self.stop.setStatusTip("Stop playing media")
        self.stop.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        # self.stop.setStyleSheet("background-color: #B0C4DE; margin: 0px 0px 0px 2px;")
        self.stop.clicked.connect(self.stop_media)

        # volume slider
        self.volumeSlider = VolumeSlider(self.mediaPlayer, Qt.Horizontal)
        self.volumeSlider.setRange(0, 100)
        self.volumeSlider.setFixedWidth(200)
        self.mediaPlayer.setVolume(50)
        self.volumeSlider.sliderMoved.connect(self.set_volume)

        # volume button
        self.volume = Button(self)
        self.volume.setIconSize(self.btn_size)
        self.volume.setFixedHeight(24)
        self.volume.setFixedWidth(26)
        self.volume.setToolTip("Mute or Unmute")
        self.volume.setStatusTip("Mute or Unmute")
        self.volume.setIcon(self.style().standardIcon(QStyle.SP_MediaVolume))
        # self.volume.setStyleSheet("background-color: #B0C4DE; margin: 0px 0px 0px 2px;")
        self.volume.clicked.connect(self.mute)

        # create control widget
        subControlWidget = QWidget(self)
        subControlWidget.setStyleSheet(
            'background-color:rgba(255, 255, 255, 30)')
        # create Horizontal Layout
        subControlLayout = QHBoxLayout(subControlWidget)
        subControlLayout.setContentsMargins(0, 0, 0, 0)
        subControlLayout.addWidget(self.repeat, 0, Qt.AlignLeft)
        subControlLayout.addWidget(self.stop, 1, Qt.AlignLeft)
        # sub layout for volume control
        self.sub_layout = QHBoxLayout()
        self.sub_layout.addWidget(self.volume)
        self.sub_layout.addWidget(self.volumeSlider)
        subControlLayout.addLayout(self.sub_layout)
        subControlLayout.setContentsMargins(2, 2, 2, 2)

        self.layout.addWidget(subControlWidget)

    def abrir(self, event=None, url=None):
        """" Equivalent to open for most GUIs"""
        fileName = None
        if self.videoWidget.isFullScreen():
            self.toggle_fullscreen()
        if not url:
            fileName, _ = QFileDialog.getOpenFileName(self, "Select media")
            if fileName:
                self.mediaPlayer.setMedia(
                    QMediaContent(QUrl.fromLocalFile(fileName)))
        else:
            self.mediaPlayer.setMedia(QMediaContent(QUrl(url)))
        if url or fileName:
            self.volumeSlider.setValue(self.mediaPlayer.volume())
            self.playButton.setEnabled(True)
            self.statusBar.showMessage((fileName or url))
            if not self.loop:
                self.play()

    def play(self):
        """Start media player"""
        if self.playButton.isEnabled():
            if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
                self.mediaPlayer.pause()
            else:
                self.mediaPlayer.play()

    def mediaStateChanged(self, state):
        """Callback for media player state change"""
        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))
        if state == QMediaPlayer.StoppedState and self.loop:
            self.play()

    def positionChanged(self, position):
        """Callback for media player position change"""
        if self.mediaPlayer.state() == QMediaPlayer.StoppedState:
            position = 0
        self.positionSlider.setValue(position)
        hours, position = position // 3600000, position % 3600000
        minutes, position = position // 60000, position % 60000
        seconds = position // 1000
        self.durationLabel.setText(
            self.time_text.format(hours, minutes, seconds, self.hours,
                                  self.minutes, self.seconds))

    def durationChanged(self, duration):
        """Callback for media player duration of media change"""
        self.positionSlider.setRange(0, duration)
        self.hours, duration = duration // 3600000, duration % 3600000
        self.minutes, duration = duration // 60000, duration % 60000
        self.seconds = duration // 1000
        self.durationLabel.setText(
            self.time_text.format(0, 0, 0, self.hours, self.minutes,
                                  self.seconds))

    def setPosition(self, position):
        """set media player play position"""
        self.mediaPlayer.setPosition(position)

    def handleError(self):
        """Callback for multiplayer errors"""
        self.playButton.setEnabled(False)
        self.statusBar.showMessage("Error: " + self.mediaPlayer.errorString())

    def play_again(self):
        """Set repeat on or off"""
        self.loop = not self.loop

    def stop_media(self):
        """Callback for stop button"""
        if self.loop:
            self.loop = False
            self.repeat.toggle()
        self.mediaPlayer.stop()

    def toggle_fullscreen(self):
        """Toggle in or out of fullscreen mode"""
        self.videoWidget.setWindowFlags(Qt.FramelessWindowHint
                                        | Qt.WindowStaysOnTopHint)
        if self.videoWidget.isFullScreen():
            self.videoWidget.setFullScreen(False)
            self.videoWidget.setWindowState(Qt.WindowNoState)
            self.videoWidget.setParent(self)
            self.layout.insertWidget(0, self.videoWidget)
            self.videoWidget.showNormal()
            self.show()
        else:
            self.videoWidget.setFullScreen(True)
            self.hide()

    def rewind(self, lapse=2500):
        """Rewind the current media file by 1 second"""
        new_position = self.mediaPlayer.position() - lapse
        self.setPosition(new_position)

    def forward(self, lapse=2500):
        """Forward media file by 1 second"""
        new_position = self.mediaPlayer.position() + lapse
        self.setPosition(new_position)

    def set_volume(self, vol=0):
        """Set media player volume volume"""
        if vol:
            self.mediaPlayer.setVolume(vol)

    def red_volume(self, vol=1):
        """Reduce volume by a factor of 0.01"""
        volume = self.mediaPlayer.volume()
        if volume >= 0:
            new_volume = volume - 1
            self.volumeSlider.setValue(new_volume)
            self.set_volume(new_volume)

    def inc_volume(self, vol=1):
        """Increase volume by a factor of 0.01"""
        volume = self.mediaPlayer.volume()
        if self.mediaPlayer.isMuted():
            self.mediaPlayer.setMuted(False)
            self.volume.setIcon(self.style().standardIcon(
                QStyle.SP_MediaVolume))
        if volume <= 100:
            new_volume = volume + 1
            self.volumeSlider.setValue(new_volume)
            self.set_volume(new_volume)

    def mute(self):
        """Mute media player"""
        if self.mediaPlayer.isMuted():
            self.mediaPlayer.setMuted(False)
            self.volume.setIcon(self.style().standardIcon(
                QStyle.SP_MediaVolume))
        else:
            self.mediaPlayer.setMuted(True)
            self.volume.setIcon(self.style().standardIcon(
                QStyle.SP_MediaVolumeMuted))
class VideoPlayer(QWidget):
    def __init__(self):
        super().__init__()

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

        btnSize = QSize(16, 16)
        videoWidget = QVideoWidget()

        openButton = QPushButton("Open Video")
        openButton.setToolTip("Open Video File")
        openButton.setStatusTip("Open Video File")
        openButton.setFixedHeight(24)
        openButton.setIconSize(btnSize)
        openButton.setFont(QFont("Noto Sans", 8))
        openButton.setIcon(
            QIcon.fromTheme("document-open", QIcon("D:/_Qt/img/open.png")))
        openButton.clicked.connect(self.abrir)

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

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

        self.statusBar = QStatusBar()
        self.statusBar.setFont(QFont("Noto Sans", 7))
        self.statusBar.setFixedHeight(14)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.positionSlider)

        layout = QVBoxLayout()
        layout.addWidget(videoWidget)
        layout.addLayout(controlLayout)
        layout.addWidget(self.statusBar)

        self.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.statusBar.showMessage("Ready")
        self.video_name = None

        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volumeUp)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volumeDown)

        self.video_id = None

    def abrir(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, "Selecciona los mediose", ".",
            "Video Files (*.mp4 *.flv *.ts *.mts *.avi)")

        if fileName != '':
            r = requests.post(POST_DATA_URL_VIDEO, json=dict(name=fileName))
            self.video_id = int(r.text)
            self.video_name = os.path.basename(fileName)
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(fileName)))
            self.playButton.setEnabled(True)
            self.statusBar.showMessage(fileName)
            self.play()

    def get_video_id(self):
        return self.video_id

    def pause_video(self):
        self.mediaPlayer.pause()

    def resume_video(self):
        self.mediaPlayer.play()

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

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

    def is_paused(self):
        return not self.mediaPlayer.state() == QMediaPlayer.PlayingState

    def get_position(self):
        return self.mediaPlayer.position()

    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.statusBar.showMessage("Error: " + self.mediaPlayer.errorString())
Beispiel #13
0
class EventAction():
    def __init__(self):
        #self.parent = parent
        self.isLoop = 0         #0循环列表,1单曲循环
        self.isRandom = 0       #0不随机,1随机
        self.fileList = []      #曲目名称列表
        self.randomList =[]     #播放列表
        self.soundID = 0        #当前歌曲ID
        self.playStat = False  #当前播放状态 (0未播放,1播放)
        self.openPath = "F:/mp3/" #歌曲目录
        self.isPreview = 0       #试用开关,0正常播放,1列表中的歌曲每首歌曲放10秒
        self.currentVolume = 0.1#默认的起始音量
        self.isInitPlay = 1     #是否是初始播放
        #==>>打开目录
        self.config=configparser.ConfigParser()
        self.config.read('config.ini')
        self.openDir()
        #打开目录<<==
        self.playObj = QMediaPlayer()

        self.currentImg = ""    #当前图片
        self.songText = {}      #歌词
        self.songTextKey=[]     #歌词KEY



    #打开歌曲目录
    def openDir(self):
        self.openPath = self.config.get('Save','musicPath')
        isMusicDir = os.path.isdir(self.openPath)#检查是否为目录
        if isMusicDir:
            dirFile = os.listdir(self.openPath)#目录中的所有文件
            #遍历有效音乐文件
            i=0;
            for file in dirFile:
                fileName,fileType=os.path.splitext(file)
                if fileType==".mp3" or fileType==".wav":
                    self.fileList.append(file)
                    self.randomList.append(i)
                    i+=1
        if self.isRandom==1:
            self.shuffleMusic(1)

    #随机(打乱播放顺序)
    def shuffleMusic(self,isshuffle):
        if isshuffle:
            random.shuffle(self.randomList)#乱序
        else:
            self.randomList.sort()#排序

    #初始化播放
    def initPlay(self):
        self.soundID = int(self.config.get('Save','soundID'))
        self.playStat = self.config.get('Save','playStat')
        self.pastTime = self.config.getint('Save','pastTime')
        self.currentVolume = self.config.getint('Save','volume')
        self.isRandom = self.config.getint('Save','isRandom')
        self.isLoop = self.config.getint('Save','isLoop')

        if self.soundID!="":
            self.play(self.soundID)
        if self.isRandom:#打乱列表
            self.shuffleMusic(1)
        self.playObj.setVolume(self.currentVolume)


    #播放
    def play(self,i):
        source = self.openPath + self.fileList[i]
        self.playObj.setMedia(QMediaContent(QUrl.fromLocalFile(source)))
        #解析文件中的ID3V2
        self.currentImg = ""
        f = QFile(source)
        if f.open(QIODevice.ReadOnly):
            #读取标签
            headData = f.read(10)
            data = headData[:0]
            if self.id3v2(headData):#检测是否有ID3
                #标签的大小计算
                tag = headData[6:10]
                tagSize = (tag[0]&0x7f)*0x200000+(tag[1]&0x7f)*0x4000+(tag[2]&0x7f)*0x80+(tag[3]&0x7f)
                data =f.read(tagSize)
                while len(data)>10:
                    data = self.resolve(data)
        f.close()
        self.playObj.play()

    def testPlay(self):
        #ps =QMediaMetaData()
        #print("QMediaMetaData",ps)
        #print("metaData",self.playObj.metaData(QMediaMetaData.Title))
        #print("position",self.playObj.position())
        #print("playlist",self.playObj.playlist)
        #print("availability",self.playObj.availability())
        #print("bufferStatus",self.playObj.bufferStatus())
        #print("currentMedia",self.playObj.currentMedia())
        #print("currentNetworkConfiguration",self.playObj.currentNetworkConfiguration())
        #print("duration",self.playObj.duration())
        #print("error",self.playObj.error())
        #print("errorString",self.playObj.errorString())
        #print("isAudioAvailable",self.playObj.isAudioAvailable())
        #print("isMuted",self.playObj.isMuted())
        #print("isSeekable",self.playObj.isSeekable())
        #print("media",self.playObj.media())
        #print("media:::::::A",self.playObj.media().canonicalResource().audioBitRate())
        #print("media:::::::B",self.playObj.media().canonicalResource().audioCodec())
        #print("media:::::::C",self.playObj.media().canonicalResource().channelCount())
        #print("media:::::::D",self.playObj.media().canonicalResource().dataSize())
        #print("media:::::::e",self.playObj.media().canonicalResource().isNull())
        #print("media:::::::f",self.playObj.media().canonicalResource().language())
        #print("media:::::::g",self.playObj.media().canonicalResource().mimeType())
        #print("media:::::::h",self.playObj.media().canonicalResource().request())
        #print("isVideoAvailable",self.playObj.isVideoAvailable())
        #print("mediaStatus",self.playObj.mediaStatus())
        #print("mediaStream",self.playObj.mediaStream())
        #print("playbackRate",self.playObj.playbackRate())
        #print("state",self.playObj.state())
        #print("volume",self.playObj.volume())
        # print("volume",self.playObj.filename)
        pass



    #换歌之前先停止,释放内存
    def stopPlay(self):
        self.playObj.pause()

    #上一首
    def prevPlay(self):
        self.stopPlay()
        if self.isRandom:
            key = self.searchID(self.soundID)-1
            if key<0:
                key=0
            self.soundID = self.randomList[key]
        else:
            self.soundID-=1
            if self.soundID< 0:
                self.soundID = len(self.randomList)-1
        self.play(self.soundID)

    #下一首
    def nextPlay(self):
        self.stopPlay()
        if self.isRandom:
            key = self.searchID(self.soundID)+1
            if key>(len(self.randomList)-1):
                key=len(self.randomList)-1
            self.soundID = self.randomList[key]
        else:
            self.soundID+=1
            if self.soundID > (len(self.randomList)-1):
                self.soundID = 0
        #print("next:::",self.soundID)
        self.play(self.soundID)

    #快退
    def rewindPlay(self):
        #print("<<")
        rewindTime = int(self.playObj.position()) - 10*1000
        if rewindTime < 0:
            rewindTime = 0
        self.playObj.setPosition(rewindTime)

    #快进
    def forwardPlay(self):
        #print(">>")
        forwardTime = int(self.playObj.position()) + 10*1000
        if forwardTime > int(self.playObj.duration()):
            forwardTime = int(self.playObj.duration())
        self.playObj.setPosition(forwardTime)

    #播放/暂停
    def playORpause(self):
        if self.playObj.state()==1:
            self.playObj.pause()
        else:
            self.playObj.play()

    #音量加
    def raisevolPlay(self):
        self.playObj.setVolume(self.playObj.volume()+10)
        self.currentVolume = self.playObj.volume()
    #音量减
    def lowervolPlay(self):
        self.playObj.setVolume(self.playObj.volume()-10)
        self.currentVolume = self.playObj.volume()

    #静音
    def mutePlay(self):
        if self.playObj.isMuted():
            self.playObj.setMuted(False)
        else:
            self.playObj.setMuted(True)
    #volume

    #跟据v找K
    def searchID(self,v):
        for index, item in enumerate(self.randomList):
            if item ==v:
                return index
        return 0

    #解析文件中是否有id3v2
    def id3v2(self,headData):
        if str(headData[:3],encoding=("utf-8")) != "ID3":
            return False
        return True

    #解析文件中的歌词与图片
    def resolve(self,data):
        tagName =  str(data[:4],encoding=("utf-8"))
        size = data[4:8]
        #sizeS = size[0]*0x1000000 + size[1]*0x10000 + size[2]*0x100 + size[3]
        sizeS=int.from_bytes(size, byteorder='big')
        flags = data[8:10]
        tagContent = data[10:sizeS+10]

        if tagName=="TEXT":#歌词
            #print("歌词")
            condingType=int.from_bytes(tagContent[:1], byteorder='big')
            if condingType == 0:#0代表字符使用ISO-8859-1编码方式;
                try:
                    content = str(tagContent[1:],encoding="gbk")
                except:
                    content =""
            elif condingType == 1:#1代表字符使用UTF-16编码方式;
                try:
                    content = str(tagContent[1:],encoding="UTF-16")
                except:
                    content =""
            elif condingType == 2:#2代表字符使用 UTF-16BE编码方式;
                content =""
            elif condingType == 3:#3代表字符使用UTF-8编码方式。
                try:
                    content = str(tagContent[1:],encoding="UTF-8")
                except:
                    content =""
            if content!="":
                temp={}
                self.songTextKey=[]
                contentSplit = content.splitlines()
                for k in range(len(contentSplit)):
                    if contentSplit[k][1].isdigit():
                        xxx = contentSplit[k].split("]")
                        tempKey = "%d" %(int(xxx[0][1:3])*60 +int(xxx[0][4:6]) )
                        temp[str(tempKey)] = xxx[1]
                        self.songTextKey.append(tempKey)
                    else:
                        endKey = contentSplit[k].find("]",0)
                        self.songTextKey.append(k)
                        temp[str(k)] = contentSplit[k][1:endKey]
                self.songText = temp
            else:
                self.songText = {}
        elif tagName=="APIC":#图片
            #print("图片")
            self.currentImg = tagContent[17:]
        return data[10+sizeS:]
class VideoPlayer(QWidget):
    def __init__(self,
                 repl_globals=None,
                 position_var_name=None,
                 file_name_var_name=None,
                 parent=None):
        super(VideoPlayer, self).__init__(parent)

        self.uuid = uuid.uuid4()

        self.repl_globals = repl_globals
        self.position_var_name = position_var_name
        self.file_name_var_name = file_name_var_name
        self.frame_position = self.repl_globals[self.position_var_name]

        self.setGeometry(100, 300, 600, 380)

        self.timer = QTimer()
        self.timer.timeout.connect(self.on_timer_tick)
        self.timer.start(ct.TIMER_UPDATE_TIME_MILLIS)

        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAcceptDrops(True)
        self.media_player = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
        self.media_player.setVolume(80)
        self.video_widget = QVideoWidget(self)

        self.media_player.setVideoOutput(self.video_widget)
        self.media_player.stateChanged.connect(self.on_media_state_changed)
        self.media_player.positionChanged.connect(self.on_position_change)
        self.media_player.positionChanged.connect(self.handle_label)
        self.media_player.durationChanged.connect(self.on_duration_changed)
        self.media_player.error.connect(self.handle_error)

        self.frame_viewer = QLineEdit(str(self.media_player.position()))
        self.frame_viewer.setReadOnly(True)
        self.frame_viewer.setFixedWidth(70)
        self.frame_viewer.setUpdatesEnabled(True)
        self.frame_viewer.setStyleSheet(stylesheet(self))

        self.time_viewer = QLineEdit('00:00:00')
        self.time_viewer.setReadOnly(True)
        self.time_viewer.setFixedWidth(70)
        self.time_viewer.setUpdatesEnabled(True)
        self.time_viewer.setStyleSheet(stylesheet(self))

        self.full_time_viewer = QLineEdit('00:00:00')
        self.full_time_viewer.setReadOnly(True)
        self.full_time_viewer.setFixedWidth(70)
        self.full_time_viewer.setUpdatesEnabled(True)
        self.full_time_viewer.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.position_slider = QSlider(Qt.Horizontal, self)
        self.position_slider.setStyleSheet(stylesheet(self))
        self.position_slider.setRange(0, 100)
        self.position_slider.sliderMoved.connect(self.set_position)
        self.position_slider.sliderMoved.connect(self.handle_label)
        self.position_slider.setSingleStep(1)
        self.position_slider.setPageStep(20)
        self.position_slider.setAttribute(Qt.WA_TranslucentBackground, True)

        slider_controls_layout = QHBoxLayout()
        slider_controls_layout.setContentsMargins(5, 0, 5, 0)
        slider_controls_layout.addWidget(self.playButton)
        slider_controls_layout.addWidget(self.frame_viewer)
        slider_controls_layout.addWidget(self.time_viewer)
        slider_controls_layout.addWidget(self.position_slider)
        slider_controls_layout.addWidget(self.full_time_viewer)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.video_widget)
        layout.addLayout(slider_controls_layout)

        self.setLayout(layout)

        self.myinfo = "©2019\nGeorge Dimitriadis\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \
                      "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \
                      "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes"

        #### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handle_quit)
        self.shortcut = QShortcut(QKeySequence(" "), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence("f"), self)
        self.shortcut.activated.connect(self.handle_fullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handle_info)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forward_slider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.back_slider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volume_up)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volume_down)
        self.shortcut = QShortcut(
            QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forward_slider_10)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left),
                                  self)
        self.shortcut.activated.connect(self.back_slider_10)

        self.widescreen = True
        self.setAcceptDrops(True)
        self.load_film(self.repl_globals[self.file_name_var_name])

    def on_position_change(self, position):
        self.position_slider.setValue(position)
        self.repl_globals[self.position_var_name] = position

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

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

    def on_duration_changed(self, duration):
        self.position_slider.setRange(0, duration)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.media_player.duration())
        self.full_time_viewer.setText(mtime.toString())

    def set_position(self, position):
        self.media_player.setPosition(position)
        self.media_player.pause()

    def handle_error(self):
        self.playButton.setEnabled(False)
        print("Error: ", self.media_player.errorString())

    def handle_quit(self):
        self.media_player.stop()
        del open_windows[self.uuid]
        self.close()

    def closeEvent(self, event):
        self.handle_quit()
        event.accept()

    def handle_fullscreen(self):
        if self.windowState() & Qt.WindowFullScreen:
            self.showNormal()
            print("no Fullscreen")
        else:
            self.showFullScreen()
            print("Fullscreen entered")

    def handle_info(self):
        msg = QMessageBox.about(self, "QT5 Player", self.myinfo)

    def forward_slider(self):
        self.media_player.setPosition(self.media_player.position() + 1000 * 60)

    def forward_slider_10(self):
        self.media_player.setPosition(self.media_player.position() +
                                      10000 * 60)

    def back_slider(self):
        self.media_player.setPosition(self.media_player.position() - 1000 * 60)

    def back_slider_10(self):
        self.media_player.setPosition(self.media_player.position() -
                                      10000 * 60)

    def volume_up(self):
        self.media_player.setVolume(self.media_player.volume() + 10)
        print("Volume: " + str(self.media_player.volume()))

    def volume_down(self):
        self.media_player.setVolume(self.media_player.volume() - 10)
        print("Volume: " + str(self.media_player.volume()))

    def load_film(self, f):
        self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.media_player.pause()

    def handle_label(self):
        self.time_viewer.clear()
        mtime = QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.media_player.position())
        self.time_viewer.setText(self.time.toString())
        self.frame_viewer.setText(str(self.media_player.position()))

    def on_timer_tick(self):
        if self.media_player.state() != QMediaPlayer.PlayingState:
            self.media_player.setPosition(
                self.repl_globals[self.position_var_name])

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() \
                      - QPoint(self.frameGeometry().width() / 2, \
                               self.frameGeometry().height() / 2))
            event.accept()
Beispiel #15
0
class Player(QGraphicsVideoItem):

    isSubtitle = pyqtSignal(bool)
    subtitlePos = pyqtSignal(int)
    def __init__(self, parent=None):
        super().__init__()
        self.parent = parent

        self.player = QMediaPlayer()
        self.player.setVolume(int(settings().value("Player/volume") or 100))
        self.player.setVideoOutput(self)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.timerPos)

        self.player.currentMediaChanged.connect(self.signalStart)
        self.player.currentMediaChanged.connect(self.parent.subtitleitem.subtitleControl)
        self.player.currentMediaChanged.connect(self.videoConfigure)
        """self.player.mediaStatusChanged.connect(self.metadata)

    def metadata(self, data):
        if data and self.player.isMetaDataAvailable():
            print(self.player.metaData("VideoCodec"))"""

    def videoConfigure(self, media):
        video_name = os.path.basename(media.canonicalUrl().toLocalFile())
        videos = settings().value("Player/video_names") or []
        videos_time = settings().value("Player/videos_time") or []
        try:
            self.player.setPosition(int(videos_time[videos.index(video_name)]))
        except ValueError:
            pass

    def timerStart(self):
        self.timer.start(200)

    def signalStart(self, content):
        srt = content.canonicalUrl().toLocalFile().split(".")
        srt.pop(-1)
        srt.append("srt")
        srt = ".".join(srt)
        if QFile.exists(srt):
            self.isSubtitle.emit(True)
            self.timer.start(100)
        else:
            self.isSubtitle.emit(False)
            self.timer.stop()

    def timerPos(self):
        self.subtitlePos.emit(self.player.position())

    def playerPlayOrOpen(self, arg=None):
        if type(arg) == list and len(arg) > 1:
            content = QMediaContent(QUrl.fromLocalFile(arg[1]))
            self.player.setMedia(content)
            self.play()

    def addVideo(self, video):
        content = QMediaContent(QUrl.fromLocalFile(video))
        self.player.setMedia(content)
        self.play()

    def addYoutubeVideo(self, video):
        dm = DownloadManager(self)

        content = QMediaContent(dm.addUrl(video))
        self.player.setMedia(content)
        self.play()

    def sliderChanged(self, pos):
        self.player.setPosition(pos)

    def play(self):
        self.player.play()

    def stop(self):
        self.player.stop()

    def pause(self):
        self.player.pause()

    def setMuted(self, mute):
        self.player.setMuted(mute)

    def mutedState(self):
        if self.player.isMuted():
            self.setMuted(False)
        else:
            self.setMuted(True)

    def isMuted(self):
        return  self.player.isMuted()

    def setVolume(self, value):
        self.player.setVolume(value)

    def volume(self):
        return self.player.volume()
Beispiel #16
0
class Player(QWidget):

    fullScreenChanged = pyqtSignal(bool)

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

        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)

        self.videoWidget = VideoWidget()
        self.player.setVideoOutput(self.videoWidget)

        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)

        self.playlistView = QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(self.playlist.currentIndex(), 0))

        self.playlistView.activated.connect(self.jump)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)


        openButton = QPushButton("Открыть файл", clicked=self.open)

        controls = PlayerControls()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())

        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeRate.connect(self.player.setPlaybackRate)
        controls.stop.connect(self.videoWidget.update)

        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)

        self.fullScreenButton = QPushButton("Полный экран")
        self.fullScreenButton.setCheckable(True)

        displayLayout = QHBoxLayout()
        displayLayout.addWidget(self.videoWidget, 2)
        displayLayout.addWidget(self.playlistView)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addStretch(1)
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        controlLayout.addWidget(self.fullScreenButton)

        layout = QVBoxLayout()
        layout.addLayout(displayLayout)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)

        self.setLayout(layout)

        self.metaDataChanged()

        self.addToPlaylist(playlist)

    def open(self):
        fileNames, _ = QFileDialog.getOpenFileNames(self, "Выбрать файл")
        self.addToPlaylist(fileNames)

    def addToPlaylist(self, fileNames):
        for name in fileNames:
            fileInfo = QFileInfo(name)
            if fileInfo.exists():
                url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
                if fileInfo.suffix().lower() == 'm3u':
                    self.playlist.load(url)
                else:
                    self.playlist.addMedia(QMediaContent(url))
            else:
                url = QUrl(name)
                if url.isValid():
                    self.playlist.addMedia(QMediaContent(url))

    def durationChanged(self, duration):
        duration /= 1000

        self.duration = duration
        self.slider.setMaximum(duration)

    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)

        self.updateDurationInfo(progress)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo("%s - %s" % (
                    self.player.metaData(QMediaMetaData.AlbumArtist),
                    self.player.metaData(QMediaMetaData.Title)))

    def previousClicked(self):
        # Go to the previous track if we are within the first 5 seconds of
        # playback.  Otherwise, seek to the beginning.
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)

    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()

    def playlistPositionChanged(self, position):
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(position, 0))

    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)

    def statusChanged(self, status):
        self.handleCursor(status)

        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo("Загрузка...")
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo("Видео стоп")
        elif status == QMediaPlayer.EndOfMedia:
            QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo("")

    def handleCursor(self, status):
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def bufferingProgress(self, progress):
        self.setStatusInfo("Буферизация %d%" % progress)

    def videoAvailableChanged(self, available):
        if available:
            self.fullScreenButton.clicked.connect(
                    self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.connect(
                    self.fullScreenButton.setChecked)

            if self.fullScreenButton.isChecked():
                self.videoWidget.setFullScreen(True)
        else:
            self.fullScreenButton.clicked.disconnect(
                    self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.disconnect(
                    self.fullScreenButton.setChecked)

            self.videoWidget.setFullScreen(False)


    def setTrackInfo(self, info):
        self.trackInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def setStatusInfo(self, info):
        self.statusInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def displayErrorMessage(self):
        self.setStatusInfo(self.player.errorString())

    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QTime((currentInfo/3600)%60, (currentInfo/60)%60,
                    currentInfo%60, (currentInfo*1000)%1000)
            totalTime = QTime((duration/3600)%60, (duration/60)%60,
                    duration%60, (duration*1000)%1000);

            format = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            tStr = currentTime.toString(format) + " / " + totalTime.toString(format)
        else:
            tStr = ""

        self.labelDuration.setText(tStr)
Beispiel #17
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.my_state = _STATE_PLAY

        # Controles principales para organizar la ventana.
        self.widget = QWidget(self)
        self.layout = QVBoxLayout()
        self.bottom_layout = QHBoxLayout()

        # Control de reproducción de video de Qt.
        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer()
        self.media_player.setMedia(
            QMediaContent(QUrl.fromLocalFile(MY_PATH + VIDEO_PATH)))
        self.media_player.setVideoOutput(self.video_widget)

        # Botones de reproducción y pausa.
        self.play_button = QPushButton("Pausa", self)
        self.stop_button = QPushButton("Detener", self)

        # Deslizadores para el volumen y transición del video.
        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.volume_slider.sliderMoved.connect(self.media_player.setVolume)

        # actualizar la posicion

        #self.seek_slider.sliderMoved.connect(self.change_media_player)

        #self.media_player.durationChanged.connect(self.change_duration)

        # Acomodar controles en la pantalla.
        self.layout.addWidget(self.video_widget)
        self.layout.addLayout(self.bottom_layout)

        self.layout.addWidget(self.seek_slider)

        self.bottom_layout.addWidget(self.play_button)
        self.bottom_layout.addWidget(self.stop_button)
        self.bottom_layout.addWidget(self.volume_slider)

        # Conectar los eventos con sus correspondientes funciones.
        self.play_button.clicked.connect(self.play_clicked)
        #self.stop_button.clicked.connect(self.stop_clicked)
        self.media_player.stateChanged.connect(self.state_changed)

        # Personalizar la ventana.
        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)

        self.media_player.positionChanged.connect(self.pos_changed)

        # Reproducir el video.
        self.my_signal = mi_senal()
        self.my_signal.sig.connect(self.saySomeWords)

        self.timer = QTimer()
        self.timer.timeout.connect(self.tick)
        self.timer.start(500)
        self.parar = False

        self.media_player.setNotifyInterval(1000)
        self.media_player.play()

    def tick(self):
        #print ("este es mi timer")
        if self.parar == True:
            self.media_player.pause()
            self.timer.stop()

    # senales relacionadas a eventos
    @pyqtSlot(str)
    def saySomeWords(self, words):
        print(words)
        self.media_player.pause()

    def hand_my_signal(self):
        print("Esta es mi senal")

    def play_clicked(self):
        """
        Comenzar o resumir la reproducción.
        """
        self.my_signal.sig.emit("hola a todo mundo")
        #if (self.media_player.state() in
        #    (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)):
        #    self.media_player.play()
        #else:
        #    self.media_player.pause()

    def pos_changed(self, value):
        print("la posicion es:%d" % (value))
        if value >= 4000:
            self.parar = True
        #    self.media_player.positionChanged.disconnect(self.pos_changed)

        #self.media_player.pause()

    def state_changed(self, newstate):
        print("cambio de estado")
class Player(QWidget):

    fullScreenChanged = pyqtSignal(bool)

    def __init__(self, playlist, parent=None, add_button = None):
        super(Player, self).__init__(parent)
        self.add_button = add_button

        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.error.connect(self.displayErrorMessage)

        self.videoWidget = VideoWidget()
        self.player.setVideoOutput(self.videoWidget)

        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)

        self.playlistView = QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(self.playlist.currentIndex(), 0))

        self.playlistView.activated.connect(self.jump)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)

        openButton = QPushButton("Open Audio/Video File", clicked=self.open)

        controls = PlayerControls()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())
        controls.setMuted(controls.isMuted())

        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeMuting.connect(self.player.setMuted)
        controls.changeRate.connect(self.player.setPlaybackRate)
        controls.stop.connect(self.videoWidget.update)

        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)
        self.player.mutedChanged.connect(controls.setMuted)


        displayLayout = QHBoxLayout()
        displayLayout.addWidget(self.videoWidget, 2)
        displayLayout.addWidget(self.playlistView)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        # button to add decoder
        if add_button:
            add_decoder_btn = QPushButton("Decode Keystrokes of Selected Media")
            add_decoder_btn.clicked.connect(add_button)            
            controlLayout.addWidget(add_decoder_btn)
        # controlLayout.addStretch(1)
        controlLayout.addWidget(controls)

        layout = QVBoxLayout()
        layout.addLayout(displayLayout)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)


        self.setLayout(layout)

        if not self.player.isAvailable():
            QMessageBox.warning(self, "Service not available",
                    "The QMediaPlayer object does not have a valid service.\n"
                    "Please check the media service plugins are installed.")

            controls.setEnabled(False)
            self.playlistView.setEnabled(False)
            openButton.setEnabled(False)

        self.metaDataChanged()

        self.addToPlaylist(playlist)

    def get_current_file(self):
        inds = self.playlistView.selectedIndexes()
        if len(inds) == 1:
            index = inds[0]
            location = self.playlistModel.m_playlist.media(index.row()).canonicalUrl()
            return location.path()
            
        

    def open(self):
        fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files")
        self.addToPlaylist(fileNames)

    def addToPlaylist(self, fileNames):
        for name in fileNames:
            fileInfo = QFileInfo(name)
            if fileInfo.exists():
                url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
                if fileInfo.suffix().lower() == 'm3u':
                    self.playlist.load(url)
                else:
                    self.playlist.addMedia(QMediaContent(url))
            else:
                url = QUrl(name)
                if url.isValid():
                    self.playlist.addMedia(QMediaContent(url))

    def durationChanged(self, duration):
        duration /= 1000

        self.duration = duration
        self.slider.setMaximum(duration)

    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)

        self.updateDurationInfo(progress)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo("%s - %s" % (
                    self.player.metaData(QMediaMetaData.AlbumArtist),
                    self.player.metaData(QMediaMetaData.Title)))

    def previousClicked(self):
        # Go to the previous track if we are within the first 5 seconds of
        # playback.  Otherwise, seek to the beginning.
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)

    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()

    def playlistPositionChanged(self, position):
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(position, 0))

    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)

    def statusChanged(self, status):
        self.handleCursor(status)

        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo("Loading...")
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo("Media Stalled")
        elif status == QMediaPlayer.EndOfMedia:
            QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo("")

    def handleCursor(self, status):
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def bufferingProgress(self, progress):
        self.setStatusInfo("Buffering %d%" % progress)

    def setTrackInfo(self, info):
        self.trackInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def setStatusInfo(self, info):
        self.statusInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def displayErrorMessage(self):
        self.setStatusInfo(self.player.errorString())

    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QTime((currentInfo/3600)%60, (currentInfo/60)%60,
                    currentInfo%60, (currentInfo*1000)%1000)
            totalTime = QTime((duration/3600)%60, (duration/60)%60,
                    duration%60, (duration*1000)%1000);

            format = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            tStr = currentTime.toString(format) + " / " + totalTime.toString(format)
        else:
            tStr = ""

        self.labelDuration.setText(tStr)
Beispiel #19
0
class MainWindow(QMainWindow):
    def __init__(self, audio_file_name: str):
        super().__init__()

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.icon_alarm_clock = QIcon(str(DIR_ICONS / 'alarm-clock.png'))

        self.setWindowIcon(self.icon_alarm_clock)

        self.tray = QSystemTrayIcon(self.icon_alarm_clock)
        self.tray.setToolTip(self.windowTitle())
        self.tray.activated.connect(self._on_tray_activated)
        self.tray.show()

        self.read_settings()

        self._button_group = QButtonGroup()
        self._button_group.addButton(self.ui.at_time_rb)
        self._button_group.addButton(self.ui.through_time_rb)
        self._button_group.buttonClicked.connect(self._update_states)

        self.ui.start_stop.clicked.connect(self._start_stop)
        self.ui.more_sleep.clicked.connect(self._more_sleep)
        self.ui.i_woke_up.clicked.connect(self._i_woke_up)

        self._timer = QTimer()
        self._timer.setInterval(100)
        self._timer.timeout.connect(self._tick)

        self._timer_inc_volume = QTimer()
        self._timer_inc_volume.setInterval(500)
        self._timer_inc_volume.timeout.connect(self._inc_volume_tick)

        self._woke_up = False
        self._alarm_time: QTime = None

        self.playlist = QMediaPlaylist()
        self.playlist.setPlaybackMode(QMediaPlaylist.Loop)

        url = QUrl.fromLocalFile(audio_file_name)
        self.playlist.addMedia(QMediaContent(url))

        self.player = QMediaPlayer()
        self.player.setPlaylist(self.playlist)

        self._update_states()

    def _update_states(self):
        self.ui.at_time.setEnabled(self.ui.at_time_rb.isChecked())
        self.ui.through_time.setEnabled(self.ui.through_time_rb.isChecked())
        self.ui.i_woke_up.setVisible(self._woke_up)
        self.ui.more_sleep.setVisible(self._woke_up)

        if self._woke_up:
            self.ui.start_stop.setChecked(False)

        self.ui.start_stop.setVisible(not self._woke_up)
        if self.ui.start_stop.isChecked():
            self.ui.start_stop.setText('Стоп')
        else:
            self.ui.start_stop.setText('Запустить')

        # Корректируем высоту окна после возможного скрытия кнопок
        self.resize(self.width(), self.minimumHeight())

    def _inc_volume_tick(self):
        if self.player.volume() >= 100:
            self._timer_inc_volume.stop()

        self.player.setVolume(self.player.volume() + 1)

    def _tick(self):
        remain = QTime.currentTime().secsTo(self._alarm_time)
        if remain < 0:
            remain += 24 * 3600
        elif remain == 0:
            self._woke_up = True
            self._timer.stop()
            self._update_states()

            self.player.setVolume(1)
            self.player.play()
            self._timer_inc_volume.start()
            self._set_visible(True)

        hh, mm = divmod(remain, 3600)
        mm, ss = divmod(mm, 60)

        alarm_str = self._alarm_time.toString('hh:mm:ss')
        self.ui.time_remaining.setText(f"Звонок в {alarm_str}. Осталось: {hh:0>2}:{mm:0>2}:{ss:0>2}")

    def _i_woke_up(self):
        self._woke_up = False
        self.player.stop()
        self._update_states()

    def _start(self):
        self._woke_up = False

        if self.ui.at_time_rb.isChecked():
            self._alarm_time = self.ui.at_time.time()
        elif self.ui.through_time_rb.isChecked():
            t = self.ui.through_time.time()
            self._alarm_time = add_to_current_time(t)

        self._timer.start()
        self._update_states()

    def _stop(self):
        self._woke_up = False
        self._timer.stop()
        self._update_states()

    def _start_stop(self):
        if self.ui.start_stop.isChecked():
            self._start()
        else:
            self._stop()

    def _more_sleep(self):
        self._i_woke_up()

        t = self.ui.through_time.time()
        self._alarm_time = add_to_current_time(t)

        self._timer.start()
        self.ui.start_stop.setChecked(True)
        self._update_states()

    def _set_visible(self, visible: bool):
        self.setVisible(visible)

        if visible:
            self.showNormal()
            self.activateWindow()

    def _on_tray_activated(self, reason):
        self._set_visible(not self.isVisible())

    def changeEvent(self, event: QEvent):
        if event.type() == QEvent.WindowStateChange:
            # Если окно свернули
            if self.isMinimized():
                # Прячем окно с панели задач
                QTimer.singleShot(0, self.hide)

    def read_settings(self):
        ini = QSettings(SETTINGS_FILE_NAME, QSettings.IniFormat)

        if state := ini.value('MainWindow_State'):
            self.restoreState(state)

        if geometry := ini.value('MainWindow_Geometry'):
            self.restoreGeometry(geometry)
Beispiel #20
0
class MainWindow(QWidget):

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

        self.playlistView = QListView()
        self.switch_status = 2
        self.video_widget = QVideoWidget()
        self.playlist = QMediaPlaylist()
        self.model = PlaylistModel(self.playlist)
        self.titleBar = TitleBar(self)
        self.currentTimeLabel = QLabel()
        self.timeSlider = QSlider()
        self.totalTimeLabel = QLabel()
        self.mediaPlayer = QMediaPlayer()
        self.open_btn = QPushButton('Open File')
        self.play_btn = QPushButton()
        self.prev_btn = QPushButton()
        self.stop_btn = QPushButton()
        self.next_btn = QPushButton()
        self.switch_media_widgets_btn = QPushButton()
        self.pseudo_label = QLabel()

        self.vol_label = QLabel()
        self.volume_slider = Slider(Qt.Horizontal)
        self.gui()
        self.set_children_focus_policy(Qt.NoFocus)

    def gui(self):
        self.currentTimeLabel.setMinimumSize(QSize(80, 0))
        self.currentTimeLabel.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)

        self.timeSlider.setOrientation(Qt.Horizontal)
        self.totalTimeLabel.setMinimumSize(QSize(80, 0))
        self.totalTimeLabel.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)

        self.playlistView.setAcceptDrops(True)
        self.playlistView.setProperty("showDropIndicator", True)
        self.playlistView.setDragDropMode(QAbstractItemView.DropOnly)
        self.playlistView.setAlternatingRowColors(True)
        self.playlistView.setUniformItemSizes(True)

        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowTitle('Media Player')
        self.titleBar.label.setText('Media Player')
        self.setWindowIcon(QIcon('icon_png/media_player.png'))

        self.setGeometry(600, 200, 850, 600)
        self.timeSlider.setRange(0, 0)
        self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.prev_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        self.next_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        self.stop_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.switch_media_widgets_btn.setIcon(self.style().standardIcon(QStyle.SP_FileDialogDetailedView))
        self.vol_label.setText("")
        self.vol_label.setPixmap(QPixmap("icon_png/speaker-volume.png"))
        self.currentTimeLabel.setText("00:00")
        self.totalTimeLabel.setText("00:00")
        self.volume_slider.setValue(self.mediaPlayer.volume())
        self.mediaPlayer.setVideoOutput(self.video_widget)
        self.mediaPlayer.setPlaylist(self.playlist)
        self.playlistView.setModel(self.model)
        self.video_widget.hide()

        sizegrip = QSizeGrip(self)

        self.setAcceptDrops(True)

        inner_h_box = QHBoxLayout()
        inner_h_box.addWidget(self.prev_btn)
        inner_h_box.addWidget(self.stop_btn)
        inner_h_box.addWidget(self.next_btn)

        vol_h_box = QHBoxLayout()
        vol_h_box.addWidget(self.vol_label, 0)
        vol_h_box.addWidget(self.volume_slider, 1)

        h_box = QHBoxLayout()
        h_box.addWidget(self.open_btn)
        h_box.addWidget(self.play_btn, 0)
        h_box.addLayout(inner_h_box, 0)
        h_box.addWidget(self.switch_media_widgets_btn, 0)
        h_box.addWidget(self.pseudo_label, 1)
        h_box.addLayout(vol_h_box, 0)
        h_box.addWidget(sizegrip, 0, Qt.AlignBottom | Qt.AlignRight)

        video_slider_h_box = QHBoxLayout()
        video_slider_h_box.addWidget(self.currentTimeLabel)
        video_slider_h_box.addWidget(self.timeSlider)
        video_slider_h_box.addWidget(self.totalTimeLabel)

        v_box = QVBoxLayout()
        v_box.addWidget(self.titleBar, 0)
        v_box.addWidget(self.video_widget, 1)
        v_box.addWidget(self.playlistView, 1)
        v_box.addLayout(video_slider_h_box, 0)
        v_box.addLayout(h_box, 0)

        inner_h_box.setContentsMargins(20, 0, 10, 0)
        vol_h_box.setContentsMargins(0, 0, 20, 0)
        h_box.setContentsMargins(20, 0, 0, 0)
        v_box.setContentsMargins(0, 0, 0, 0)
        video_slider_h_box.setSpacing(10)
        h_box.setSpacing(0)
        v_box.setSpacing(0)

        self.setLayout(v_box)
        self.enabler()

        # connections
        self.open_btn.clicked.connect(self.open_file)
        self.play_btn.clicked.connect(self.play_media)
        self.stop_btn.clicked.connect(self.stop_media)

        self.prev_btn.pressed.connect(self.play_prev)
        self.next_btn.pressed.connect(self.play_next)
        self.switch_media_widgets_btn.pressed.connect(self.switch_media)

        self.playlist.currentIndexChanged.connect(self.playlist_position_changed)
        selection_model = self.playlistView.selectionModel()
        selection_model.selectionChanged.connect(self.playlist_selection_changed)

        self.mediaPlayer.durationChanged.connect(self.update_duration)
        self.mediaPlayer.positionChanged.connect(self.update_position)
        self.timeSlider.valueChanged.connect(self.mediaPlayer.setPosition)

        self.mediaPlayer.stateChanged.connect(self.media_state)

        self.mediaPlayer.volumeChanged.connect(self.volume_changed)
        self.volume_slider.valueChanged.connect(self.set_volume)

    def set_children_focus_policy(self, policy):
        def recursive_set_child_focus_policy(parent_q_widget):
            for childQWidget in parent_q_widget.findChildren(QWidget):
                childQWidget.setFocusPolicy(policy)
                recursive_set_child_focus_policy(childQWidget)

        recursive_set_child_focus_policy(self)

    def enabler(self, state=False):
        if state is False:
            self.play_btn.setEnabled(False)
            self.prev_btn.setEnabled(False)
            self.stop_btn.setEnabled(False)
            self.next_btn.setEnabled(False)
        else:
            self.play_btn.setEnabled(True)
            self.stop_btn.setEnabled(True)
            self.prev_btn.setEnabled(True)
            self.next_btn.setEnabled(True)

    def switch_media(self):
        if self.switch_status == 0:
            self.video_widget.hide()
            self.playlistView.show()
            self.switch_status = 1
            self.switch_media_widgets_btn.setEnabled(True)
        elif self.switch_status == 1:
            self.video_widget.show()
            self.playlistView.hide()
            self.switch_status = 0
            self.switch_media_widgets_btn.setEnabled(True)
        else:
            self.video_widget.hide()
            self.playlistView.show()
            self.switch_media_widgets_btn.setEnabled(False)

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

    def ui_handler(self):
        if not self.playlist.isEmpty():
            self.enabler(True)
        file_path = QFileInfo(self.mediaPlayer.currentMedia().canonicalUrl().toString()).fileName()
        ext = os.path.splitext(file_path)[-1].lower()
        audio_ext = ['.flac', '.mp3']
        video_ext = ['.mp4', '.m4a', '.mov', '.flv', 'avi', '3gp', '.mkv', '.wmv']

        if ext in audio_ext:
            self.switch_status = 2
            self.switch_media()
            if self.isFullScreen():
                self.fullscreen()
        elif ext in video_ext:
            self.switch_status = 1
            self.switch_media()
        self.setWindowTitle(file_path + ' - Media Player')
        self.titleBar.label.setText(file_path + ' - Media Player')

    def stop_media(self):
        if self.mediaPlayer.state() != QMediaPlayer.StoppedState:
            self.mediaPlayer.stop()
            self.setWindowTitle('Media Player')
            self.titleBar.label.setText('Media Player')

    def fullscreen(self):
        if self.switch_status == 2 or self.isFullScreen():
            self.titleBar.show()
            self.timeSlider.show()
            self.currentTimeLabel.show()
            self.totalTimeLabel.show()
            self.volume_slider.show()
            self.open_btn.show()
            self.play_btn.show()
            self.prev_btn.show()
            self.stop_btn.show()
            self.next_btn.show()
            self.switch_media_widgets_btn.show()
            self.pseudo_label.show()
            self.vol_label.show()
            self.showNormal()
        else:
            self.titleBar.hide()
            self.timeSlider.hide()
            self.currentTimeLabel.hide()
            self.totalTimeLabel.hide()
            self.volume_slider.hide()
            self.open_btn.hide()
            self.play_btn.hide()
            self.prev_btn.hide()
            self.stop_btn.hide()
            self.next_btn.hide()
            self.switch_media_widgets_btn.hide()
            self.pseudo_label.hide()
            self.vol_label.hide()
            self.showFullScreen()

    def mouseDoubleClickEvent(self, event: QMouseEvent):
        event.accept()
        if event.button() == Qt.LeftButton:
            self.fullscreen()

    def media_state(self):

        os_sleep = WindowsInhibitor()
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
            if os.name == 'nt':
                os_sleep = WindowsInhibitor()
                os_sleep.inhibit()
        else:
            self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            if os_sleep:
                os_sleep.uninhibit()

    def play_next(self):
        self.playlist.next()

    def media_seek(self, seek):
        if not self.playlist.isEmpty():
            player = self.mediaPlayer
            if (player.duration() - seek) > player.position():
                player.setPosition(player.position() + seek)

    def play_prev(self):
        self.playlist.previous()

    def dragEnterEvent(self, e):
        if e.mimeData().hasUrls():
            e.acceptProposedAction()

    def dropEvent(self, e):
        for url in e.mimeData().urls():
            ext = os.path.splitext(url.fileName())[-1].lower()
            allowed_ext = ['.flac', '.mp3', '.mp4', '.m4a', '.mov', '.flv', 'avi', '3gp', '.mkv', '.wmv']
            if ext in allowed_ext:
                self.playlist.addMedia(
                    QMediaContent(url)
                )

        self.model.layoutChanged.emit()

        if self.mediaPlayer.state() != QMediaPlayer.PlayingState:
            i = self.playlist.mediaCount() - len(e.mimeData().urls())
            self.playlist.setCurrentIndex(i)
            if not self.playlist.isEmpty():
                self.play_media()

    def open_file(self):
        filter_files = "Media (*.mp3 *.mp4 *.mkv);; Videos files (*.mp4 *.mkv);; Music Files(*.mp3)"
        paths, _ = QFileDialog.getOpenFileNames(self, "Open file", "", filter_files)

        if paths:
            self.mediaPlayer.pause()
            for path in paths:
                self.playlist.addMedia(
                    QMediaContent(
                        QUrl.fromLocalFile(path)
                    )
                )
            i = self.playlist.mediaCount() - len(paths)
            self.playlist.setCurrentIndex(i)
            self.play_media()

        self.model.layoutChanged.emit()

    def update_duration(self, duration):
        self.mediaPlayer.duration()

        self.timeSlider.setMaximum(duration)

        if duration >= 0:
            self.totalTimeLabel.setText(hhmmss(duration))

    def update_position(self, position):
        if position >= 0:
            self.currentTimeLabel.setText(hhmmss(position))

        self.timeSlider.blockSignals(True)
        self.timeSlider.setValue(position)
        self.timeSlider.blockSignals(False)

    def playlist_selection_changed(self, ix):
        i = ix.indexes()[0].row()
        self.playlist.setCurrentIndex(i)
        self.ui_handler()

    def playlist_position_changed(self, i):
        if i > -1:
            ix = self.model.index(i)
            self.playlistView.setCurrentIndex(ix)

    def set_volume(self, value):
        self.mediaPlayer.setVolume(value)

    def volume_changed(self, value):
        self.volume_slider.setValue(value)

    def keyPressEvent(self, event):
        key = event.key()
        modifiers = int(event.modifiers())
        if (modifiers and modifiers & MOD_MASK == modifiers and
                key > 0 and key != Qt.Key_Shift and key != Qt.Key_Alt and
                key != Qt.Key_Control and key != Qt.Key_Meta):
            key_name = QKeySequence(modifiers + key).toString()
            if key_name == 'Ctrl+Right':
                self.media_seek(30000)
            elif key_name == 'Ctrl+Left':
                self.media_seek(-30000)
            elif key_name == 'Ctrl+Up':
                self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 5)
            elif key_name == 'Ctrl+Down':
                self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 5)
            elif key_name == 'Ctrl+O':
                self.open_file()

        else:
            if event.key() == Qt.Key_Space:
                self.play_media()
            elif event.key() == Qt.Key_MediaPlay:
                self.play_media()
            elif event.key() == Qt.Key_MediaNext:
                self.play_next()
            elif event.key() == Qt.Key_MediaPrevious:
                self.play_prev()
            elif event.key() == Qt.Key_Escape:
                self.close()
            elif event.key() == Qt.Key_F:
                self.fullscreen()
            elif event.key() == Qt.Key_Right:
                self.media_seek(5000)
            elif event.key() == Qt.Key_Left:
                self.media_seek(-5000)
Beispiel #21
0
class Player(Qt.QWidget):
    """docstring for Player"""
    fullScreenChanged = Qt.pyqtSignal(bool)

    def __init__(self, playlist, parent=None):
        # create player
        super(Player, self).__init__(parent)

        self.trackInfo = ''
        self.statusInfo = ''
        self.duration = 0

        # create player object
        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.name = 'Current playlist'
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)

        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        # self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)

        # connect with VideoWidget
        # self.videoWidget = VideoWidget()
        # self.player.setVideoOutput(self.videoWidget)

        # connect with PlaylistModel
        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)

        self.playlistView = Qt.QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(self.playlistModel.index(
            self.playlist.currentIndex(), 0))

        # change to next song
        self.playlistView.activated.connect(self.jump)

        self.slider = Qt.QSlider(QtCore.Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = Qt.QLabel()
        self.slider.sliderMoved.connect(self.seek)

        # create histogram
        self.labelHistogram = Qt.QLabel()
        self.labelHistogram.setText('Histogram: ')
        self.histogram = HistogramWidget()
        histogramLayout = Qt.QHBoxLayout()
        histogramLayout.addWidget(self.labelHistogram)
        histogramLayout.addWidget(self.histogram, 1)

        # create videoProbe
        self.videoProbe = Qt.QVideoProbe()
        self.videoProbe.videoFrameProbed.connect(self.histogram.processFrame)
        self.videoProbe.setSource(self.player)

        # add control
        controls = Controllers()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())
        controls.setMuted(controls.isMuted())

        # connect player's controls with Controllers
        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousAction)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeMuting.connect(self.player.setMuted)
        # setPlaybackRate is from QMediaPlayer
        controls.changeSpeed.connect(self.player.setPlaybackRate)
        # controls.stop.connect(self.videoWidget.update)

        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)
        self.player.mutedChanged.connect(controls.setMuted)

        # create fullScreenButton
        # self.fullScreenButton = Qt.QPushButton('FullScreen')
        # self.fullScreenButton.setCheckable(True)

        # displayLayout
        displayLayout = Qt.QHBoxLayout()
        # displayLayout.addWidget(self.videoWidget, 2)
        displayLayout.addWidget(self.playlistView)

        # controlLayout
        controlLayout = Qt.QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        # connect controlLayout with controls
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        # connect controlLayout with fullScreenButton
        # controlLayout.addWidget(self.fullScreenButton)

        # visualize player
        layout = Qt.QVBoxLayout()
        layout.addLayout(displayLayout)

        # layout for sliding song playing
        hLayout = Qt.QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)

        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)
        layout.addLayout(histogramLayout)

        # set icon
        self.setWindowIcon(Qt.QIcon('favicon.ico'))

        # create menus
        toolBar = Qt.QToolBar()

        # create basic actions
        self.createActions()

        # create simple button to repeat song
        self.repeatButton = Qt.QToolButton()
        self.repeatButton.setDefaultAction(self.repeatAct)

        # create playOnceButton
        self.playOnceButton = Qt.QToolButton()
        self.playOnceButton.setDefaultAction(self.playOnceAct)
        self.playOnceButton.setEnabled(False)

        # create shuffleButton
        self.shuffleButton = Qt.QToolButton()
        self.shuffleButton.setDefaultAction(self.shuffleAct)

        # create sequentialButton
        self.sequentialButton = Qt.QToolButton()
        self.sequentialButton.setDefaultAction(self.sequentialAct)

        # create fileButton for fileMenu
        fileButton = Qt.QToolButton()
        fileButton.setText('File')
        fileButton.setPopupMode(Qt.QToolButton.MenuButtonPopup)
        fileButton.setMenu(self.popFileMenu())

        # create editButton for editMenu
        closeButton = Qt.QToolButton()
        closeButton.setText('Edit')
        closeButton.setDefaultAction(self.fileCloseAct)

        # display in toolBar these buttons
        toolBar.addWidget(self.repeatButton)
        toolBar.addWidget(self.playOnceButton)
        toolBar.addWidget(self.shuffleButton)
        toolBar.addWidget(self.sequentialButton)
        toolBar.addWidget(fileButton)
        toolBar.addWidget(closeButton)

        # add toolBar to layout of the player
        layout.addWidget(toolBar)
        layout.addWidget(Qt.QGroupBox())

        self.setWindowTitle("Python Music Player")
        self.setLayout(layout)

        if not self.player.isAvailable():
            Qt.QMessageBox(self, 'Unavailable service')
            # self.displayErrorMessage()
            controls.setEnabled(False)
            self.playlistView.setEnabled(False)
            self.fullScreenButton.setEnabled(False)

        self.metaDataChanged()

        self.addToPlaylist(playlist)

    # create fileMenu
    def popFileMenu(self):
        aMenu = Qt.QMenu(self)
        aMenu.addAction(self.fileOpenAct)
        aMenu.addAction(self.fileCloseAct)
        return aMenu

    def createActions(self):
        self.repeatAct = Qt.QAction('Repeat', self, triggered=self.repeatSong)
        self.playOnceAct = Qt.QAction(
            'Play once', self, triggered=self.playOnceSong)
        self.shuffleAct = Qt.QAction(
            'Shuffle', self, triggered=self.playlist.shuffle)
        self.sequentialAct = Qt.QAction(
            'Sequential', self, triggered=self.playSequential)
        self.fileOpenAct = Qt.QAction('Open', self, triggered=self.open)
        self.fileOpenAct.setShortcut('Ctrl+O')

        self.fileCloseAct = Qt.QAction('Close', self, triggered=self.close)
        self.fileCloseAct.setShortcut('Ctrl+Q')

    def repeatSong(self):
        self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)
        self.repeatButton.setEnabled(False)
        self.playOnceButton.setEnabled(True)

    def playOnceSong(self):
        self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
        self.playOnceButton.setEnabled(False)
        self.repeatButton.setEnabled(True)

    # unproperly used
    def playSequential(self):
        self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)

    # get and display song duration
    def durationChanged(self, duration):
        duration /= 1000

        self.duration = duration
        self.slider.setMaximum(duration)

    # change slider position
    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)

        self.updateDurationInfo(progress)

    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QtCore.QTime(
                (currentInfo / 3600) % 60,  # hours
                (currentInfo / 60) % 60,  # minutes
                currentInfo % 60,  # seconds
                (currentInfo * 1000) % 1000)  # miliseconds
            totalTime = QtCore.QTime(
                (duration / 3600) % 60,  # hours
                (duration / 60) % 60,  # minutes
                duration % 60,  # seconds
                (duration * 1000) % 1000)  # miliseconds
            formating = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            toString = (currentTime.toString(formating) + ' / ' +
                        totalTime.toString(formating))
        else:
            toString = ''

        self.labelDuration.setText(toString)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo('{0} - {1}'.format(
                self.player.metaData(Qt.QMediaMetaData.AlbumArtist),
                self.player.metaData(Qt.QMediaMetaData.Title)))

    def setTrackInfo(self, info):
        self.trackInfo = info

        if self.statusInfo:
            self.setWindowTitle('{0} | {1}'.format(
                self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def playlistPositionChanged(self, position):
        self.playlistView.setCurrentIndex(
            self.playlistModel.index(position, 0))

    def statusChanged(self, status):
        self.handleCursor(status)

        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo('Loading...')
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo('Media Stalled')
        elif status == QMediaPlayer.EndOfMedia:
            Qt.QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo('')

    def handleCursor(self, status):
        if status in [QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia,
                      QMediaPlayer.StalledMedia]:
            self.setCursor(QtCore.Qt.BusyCursor)
        else:
            self.unsetCursor()

    def setStatusInfo(self, info):
        self.statusInfo = info

        if self.statusInfo:
            self.setWindowTitle('{0} | {1}'.format(
                self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def bufferingProgress(self, progress):
        self.setStatusInfo('Buffering {0}'.format(progress))

    def displayErrorMessage(self):
        self.statusInfo(self.player.errorString())

    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()

    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)

    def previousAction(self):
        self.playlist.previous()

    def close(self):
        choice = Qt.QMessageBox.question(
            self,
            'Close',
            'Close the app?',
            Qt.QMessageBox.Yes | Qt.QMessageBox.No)

        if choice == Qt.QMessageBox.Yes:
            sys.exit()

    def open(self):
        names, _ = Qt.QFileDialog.getOpenFileNames(self, 'Open Files')
        # ['/home/milka/Documents/MusicPlayer/song.mp3']
        self.addToPlaylist(names)

    def addToPlaylist(self, names):
        for name in names:
            fileInfo = Qt.QFileInfo(name)
            if fileInfo.exists():
                url = QtCore.QUrl.fromLocalFile(fileInfo.absoluteFilePath())

                # save_to_db song url
                create_song(
                    url.path(), self.duration, playlist_name=self.name)

                if fileInfo.suffix().lower() == 'm3u':
                    self.playlist.load(url)
                else:
                    self.playlist.addMedia(Qt.QMediaContent(url))
            else:
                url = QtCore.QUrl(name)
                if url.isValid():
                    self.playlist.addMedia(Qt.QMediaContent(url))
class Window(QMainWindow):

    def __init__(self):
        super().__init__()

        self.title = "Python Annotator for VideoS"
        # self.top = 100
        # self.left = 100
        # self.width = 300
        # self.height = 400
        # self.setWindowState = "Qt.WindowMaximized"
        iconName = "home.png"
        self.InitWindow()

    def InitWindow(self):
        self.setWindowTitle(self.title)
        # self.setWindowIcon(QtGui.QIcon(iconName))
        self.setWindowState(QtCore.Qt.WindowMaximized)

        self.UiComponents()

        self.show()

    def UiComponents(self):

        self.rowNo = 1
        self.colNo = 0
        self.fName = ""
        self.fName2 = ""
        self.fileNameExist = ""
        self.dropDownName = ""

        self.model = QStandardItemModel()

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.tableWidget = QTableWidget()
        self.tableWidget.cellClicked.connect(self.checkTableFrame)

        self.videoWidget = QVideoWidget()
        self.frameID=0


        self.insertBaseRow()

        openButton = QPushButton("Open...")
        openButton.clicked.connect(self.openFile)

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

        self.lbl = QLabel('00:00:00')
        self.lbl.setFixedWidth(60)
        self.lbl.setUpdatesEnabled(True)
        # self.lbl.setStyleSheet(stylesheet(self))

        self.elbl = QLabel('00:00:00')
        self.elbl.setFixedWidth(60)
        self.elbl.setUpdatesEnabled(True)
        # self.elbl.setStyleSheet(stylesheet(self))


        self.nextButton = QPushButton("-->")
        self.nextButton.clicked.connect(self.next)

        self.delButton = QPushButton("Delete")
        self.delButton.clicked.connect(self.delete)

        self.exportButton = QPushButton("Export")
        self.exportButton.clicked.connect(self.export)

        self.importButton = QPushButton("Import")
        self.importButton.clicked.connect(self.importCSV)

        # self.ctr = QLineEdit()
        # self.ctr.setPlaceholderText("Extra")

        self.startTime = QLineEdit()
        self.startTime.setPlaceholderText("Select Start Time")

        self.endTime = QLineEdit()
        self.endTime.setPlaceholderText("Select End Time")

        self.iLabel = QComboBox(self)
        self.iLabel.addItem("1. Eye Contact")
        self.iLabel.addItem("2. Pointing")
        self.iLabel.addItem("3. Response to Names")
        self.iLabel.addItem("4. Following Pointing")
        self.iLabel.addItem("5. Babbling")
        self.iLabel.addItem("6. Question-Answering")
        self.iLabel.addItem("7. Showing")
        self.iLabel.addItem("8. Following Instructions")
        self.iLabel.activated[str].connect(self.style_choice)

        # self.iLabel = QLineEdit()
        # self.iLabel.setPlaceholderText("Label")

        self.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handleLabel)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)

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

        # Main plotBox
        plotBox = QHBoxLayout()

        controlLayout = QHBoxLayout()
        # controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.lbl)
        controlLayout.addWidget(self.positionSlider)
        controlLayout.addWidget(self.elbl)

        wid = QWidget(self)
        self.setCentralWidget(wid)

        # Left Layout{
        # layout.addWidget(self.videoWidget)

        layout = QVBoxLayout()
        layout.addWidget(self.videoWidget, 3)
        # layout.addLayout(self.grid_root)
        layout.addLayout(controlLayout)
        layout.addWidget(self.errorLabel)

        plotBox.addLayout(layout, 3)
        # }

        # Right Layout {
        inputFields = QHBoxLayout()
        inputFields.addWidget(self.startTime)
        inputFields.addWidget(self.endTime)
        inputFields.addWidget(self.iLabel)
        # inputFields.addWidget(self.ctr)

        feats = QHBoxLayout()
        feats.addWidget(self.nextButton)
        feats.addWidget(self.delButton)
        feats.addWidget(self.exportButton)
        feats.addWidget(self.importButton)

        layout2 = QVBoxLayout()
        layout2.addWidget(self.tableWidget)
        layout2.addLayout(inputFields, 1)
        layout2.addLayout(feats, 2)
        # layout2.addWidget(self.nextButton)
        # }

        plotBox.addLayout(layout2, 1)

        # self.setLayout(layout)
        wid.setLayout(plotBox)

        self.shortcut = QShortcut(QKeySequence("["), self)
        self.shortcut.activated.connect(self.addStartTime)
        self.shortcut = QShortcut(QKeySequence("]"), self)
        self.shortcut.activated.connect(self.addEndTime)
        self.shortcut = QShortcut(QKeySequence("L"), self)
        self.shortcut.activated.connect(self.openFile)
        self.shortcut = QShortcut(QKeySequence("C"), self)
        self.shortcut.activated.connect(self.clearTable)

        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volumeUp)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volumeDown)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier +  Qt.Key_Right) , self)
        self.shortcut.activated.connect(self.forwardSlider10)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier +  Qt.Key_Left) , self)
        self.shortcut.activated.connect(self.backSlider10)

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

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

        if fileName != '':
            self.fileNameExist = fileName
            self.mediaPlayer.setMedia(
                    QMediaContent(QUrl.fromLocalFile(fileName)))
            self.playButton.setEnabled(True)
        self.videopath = QUrl.fromLocalFile(fileName)
        self.errorLabel.setText(fileName)
        self.errorLabel.setStyleSheet('color: black')

    def play(self):
        # self.is_playing_video = not self.is_playing_video
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()
            # self._play_video()
            # self.errorLabel.setText("Start: " + " -- " + " End:")

    def _play_video(self):
        if self.is_playing_video and self.video_fps:
            frame_idx = min(self.render_frame_idx+1, self.frame_count)
            print(frame_idx)

            if frame_idx == self.frame_count:
                self.on_play_video_clicked()
            else:
                self.target_frame_idx = frame_idx

    def style_choice(self, text):
        self.dropDownName = text
        QApplication.setStyle(QStyleFactory.create(text))


    def addStartTime(self):
        self.startTime.setText(self.lbl.text())

    def addEndTime(self):
        self.endTime.setText(self.lbl.text())

    def next(self):
        self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(self.startTime.text()))
        self.colNo += 1
        self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(self.endTime.text()))
        self.colNo += 1
        self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(str(self.iLabel.currentIndex()+1)))
        self.colNo += 1
        self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(self.iLabel.currentText().split(' ')[1]))
        self.colNo = 0
        self.rowNo += 1
        # print(self.ctr.text(), self.startTime.text(), self.iLabel.text(), self.rowNo, self.colNo)
        # print(self.iLabel.currentIndex())

    def delete(self):
        # print("delete")
        index_list = []
        for model_index in self.tableWidget.selectionModel().selectedRows():
            index = QtCore.QPersistentModelIndex(model_index)
            index_list.append(index)

        self.rowNo = self.rowNo - len(index_list)

        for index in index_list:
            self.tableWidget.removeRow(index.row())

    def clearTable(self):
        while self.tableWidget.rowCount() > 0:
            self.tableWidget.removeRow(0)
        self.insertBaseRow()
        print("Clearing")

    def export(self):
        self.fName = ((self.fileNameExist.rsplit('/', 1)[1]).rsplit('.',1))[0]
        path, _ = QFileDialog.getSaveFileName(self, 'Save File', QDir.homePath() + "/"+self.fName+".csv", "CSV Files(*.csv *.txt)")
        if path:
            with open(path, 'w') as stream:
                print("saving", path)
                writer = csv.writer(stream)
                # writer = csv.writer(stream, delimiter=self.delimit)
                for row in range(self.tableWidget.rowCount()):
                    rowdata = []
                    for column in range(self.tableWidget.columnCount()):
                        item = self.tableWidget.item(row, column)
                        if item is not None and item is not "":
                            rowdata.append(item.text())
                        else:
                            break
                    writer.writerow(rowdata)
        # self.isChanged = False
        # self.setCurrentFile(path)

    def importCSV(self):
        # if fName2 != "":
            # self.fName2 = ((self.fileNameExist.rsplit('/', 1)[1]).rsplit('.',1))[0]
            # path, _ = QFileDialog.getSaveFileName(self, 'Save File', QDir.homePath() + "/"+self.fName2+".csv", "CSV Files(*.csv *.txt)")
        # else:
        self.clearTable()
        path, _ = QFileDialog.getOpenFileName(self, 'Save File', QDir.homePath() , "CSV Files(*.csv *.txt)")
        print(path)
        if path:
            with open(path, 'r') as stream:
                print("loading", path)
                reader = csv.reader(stream)
                # reader = csv.reader(stream, delimiter=';', quoting=csv.QUOTE_ALL)
                # reader = csv.reader(stream, delimiter=';', quoting=csv.QUOTE_ALL)
                # for row in reader:
                for i, row in enumerate(reader):
                    if i == 0:
                        continue
                    else:
                        if(len(row) == 4):
                            st, et, li, ln = row
                            self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(st))
                            self.colNo += 1
                            self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(et))
                            self.colNo += 1
                            self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(str(li)))
                            self.colNo += 1
                            self.tableWidget.setItem(self.rowNo, self.colNo, QTableWidgetItem(ln))
                            self.rowNo += 1
                            self.colNo = 0

    def insertBaseRow(self):
        self.tableWidget.setColumnCount(4) #, Start Time, End Time, TimeStamp
        self.tableWidget.setRowCount(50)
        self.rowNo = 1
        self.colNo = 0
        self.tableWidget.setItem(0, 0, QTableWidgetItem("Start Time"))
        self.tableWidget.setItem(0, 1, QTableWidgetItem("End Time"))
        self.tableWidget.setItem(0, 2, QTableWidgetItem("Label Index"))
        self.tableWidget.setItem(0, 3, QTableWidgetItem("Label Name"))

    def checkTableFrame(self, row, column):
        if ((row > 0) and (column < 2)):
            # print("Row %d and Column %d was clicked" % (row, column))
            item = self.tableWidget.item(row, column)
            if (item != (None and "")):
                try:
                    itemFrame = item.text()
                    itemFrame = itemFrame.split(":")
                    frameTime = int(itemFrame[2]) + int(itemFrame[1])*60 + int(itemFrame[0])*3600
                    elblFrames = self.elbl.text().split(":")
                    elblFrameTime = int(elblFrames[2]) + int(elblFrames[1])*60 + int(elblFrames[0])*3600
                    # print("Elbl FT ", str(elblFrameTime))
                    # print("FT ", str(frameTime))
                    # print(frameTime)
                    self.mediaPlayer.setPosition(frameTime*1000+1*60)
                except:
                    self.errorLabel.setText("Some Video Error - Please Recheck Video Imported!")
                    self.errorLabel.setStyleSheet('color: red')

    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)
        mtime = QTime(0,0,0,0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

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

    def handleError(self):
        self.playButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
        self.errorLabel.setStyleSheet('color: red')

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1*60)

    def forwardSlider10(self):
            self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000*60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1*60)

    def backSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000*60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    # def mouseMoveEvent(self, event):
        # if event.buttons() == Qt.LeftButton:
        #     self.move(event.globalPos() \- QPoint(self.frameGeometry().width() / 2, \
        #                 self.frameGeometry().height() / 2))
        #     event.accept()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    ##################### update Label ##################################
    def handleLabel(self):
        self.lbl.clear()
        mtime = QTime(0,0,0,0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(self.time.toString())

    def dropEvent(self, event):
        f = str(event.mimeData().urls()[0].toLocalFile())
        self.loadFilm(f)

    def clickFile(self):
        print("File Clicked")

    def clickExit(self):
        sys.exit()
Beispiel #23
0
class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(1200, 720)
        Form.setMinimumSize(QtCore.QSize(200, 199))
        Form.setStyleSheet("background-color:black;")

        self.isOnline = False
        self.isMini = False
        self.isOnTop = True
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.mainFrame = QtWidgets.QFrame(Form)
        self.mainFrame.setMinimumSize(QtCore.QSize(200, 82))
        self.mainFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.mainFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.mainFrame.setObjectName("mainFrame")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.mainFrame)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.frame_3 = QtWidgets.QFrame(self.mainFrame)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.MinimumExpanding,
            QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.frame_3.sizePolicy().hasHeightForWidth())
        self.frame_3.setSizePolicy(sizePolicy)
        self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_3.setObjectName("frame_3")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.frame_3)
        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.Player_name = QtWidgets.QLabel(self.frame_3)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.Player_name.sizePolicy().hasHeightForWidth())
        self.Player_name.setSizePolicy(sizePolicy)
        self.Player_name.setStyleSheet("QLabel\n"
                                       "    {\n"
                                       "    font: 12pt \"Helvetica\";\n"
                                       "    color: white;\n"
                                       "    border: 0px solid #076100;\n"
                                       "    }")
        self.Player_name.setObjectName("status_label")
        self.horizontalLayout_6.addWidget(self.Player_name)
        spacerItem = QtWidgets.QSpacerItem(40, 20,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem)
        self.minimize_button = QtWidgets.QPushButton(self.frame_3)
        self.minimize_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.minimize_button.setText("")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("icon_sets/minimize.png"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.minimize_button.setIconSize(QSize(25, 17))
        self.minimize_button.setMaximumSize(QSize(25, 17))
        self.minimize_button.setIcon(icon)
        self.minimize_button.setIconSize(QtCore.QSize(27, 20))
        # self.minimize_button.setFlat(True)
        self.minimize_button.setObjectName("minimize_button")
        self.horizontalLayout_6.addWidget(self.minimize_button)
        self.maximize_button = QtWidgets.QPushButton(self.frame_3)
        self.maximize_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.maximize_button.setText("")
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap("icon_sets/maximize.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.maximize_button.setIcon(icon1)
        self.maximize_button.setIconSize(QSize(25, 17))
        self.maximize_button.setMaximumSize(QSize(25, 17))
        self.maximize_button.setIconSize(QtCore.QSize(27, 20))
        # self.maximize_button.setFlat(True)
        self.maximize_button.setObjectName("maximize_button")
        self.horizontalLayout_6.addWidget(self.maximize_button)
        self.cross_button = QtWidgets.QPushButton(self.frame_3)
        self.cross_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.cross_button.setText("")
        self.cross_button.setIconSize(QSize(25, 17))
        self.cross_button.setMaximumSize(QSize(25, 17))
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap("icon_sets/cross.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.cross_button.setIcon(icon2)
        self.cross_button.setIconSize(QtCore.QSize(27, 20))
        # self.cross_button.setFlat(True)
        self.cross_button.setObjectName("cross_button")
        self.horizontalLayout_6.addWidget(self.cross_button)
        self.verticalLayout.addWidget(self.frame_3)

        self.video_playback = Videowidget(self.frame_3)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(200)
        sizePolicy.setHeightForWidth(
            self.video_playback.sizePolicy().hasHeightForWidth())
        self.video_playback.setSizePolicy(sizePolicy)
        self.video_playback.setMinimumSize(QtCore.QSize(200, 100))
        self.video_playback.setMouseTracking(False)
        self.video_playback.setTabletTracking(False)
        self.video_playback.setAcceptDrops(False)
        self.video_playback.setAutoFillBackground(False)
        self.video_playback.setObjectName("video_playback")
        self.video_playback.setStyleSheet("background-color:grey")

        self.verticalLayout.addWidget(self.video_playback)
        self.pos_frame = QtWidgets.QFrame(self.mainFrame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(
            self.pos_frame.sizePolicy().hasHeightForWidth())
        self.pos_frame.setSizePolicy(sizePolicy)
        self.pos_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.pos_frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.pos_frame.setObjectName("pos_frame")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.pos_frame)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.position_slider = PosSlider(self.pos_frame)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(100)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.position_slider.sizePolicy().hasHeightForWidth())
        self.position_slider.setSizePolicy(sizePolicy)
        self.position_slider.setMouseTracking(True)
        self.position_slider.setAutoFillBackground(False)
        self.position_slider.setStyleSheet(
            "QSlider::handle:horizontal \n"
            "    {\n"
            "    background: transparent;\n"
            "    width: 8px;\n"
            "    }\n"
            "QSlider::groove:horizontal {\n"
            "    border: 1px solid white;\n"
            "    height: 8px;\n"
            "    background: qlineargradient(y1: 0, y2: 1,stop: 0 #2e3436, stop: 1.0 #000000);\n"
            "}\n"
            " QSlider::sub-page:horizontal {\n"
            "    background:qlineargradient( y1: 0, y2: 1,\n"
            "        stop: 0 #42a6db, stop: 1 #0074e0); \n"
            "    border: 1px solid white;\n"
            "    height: 8px;\n"
            "}\n"
            "QSlider::handle:horizontal:hover {\n"
            "    background: black;\n"
            "    height: 8px;\n"
            "    width: 8px;\n"
            "    border: 1px solid white;\n"
            "    }\n"
            "")
        self.position_slider.setOrientation(QtCore.Qt.Horizontal)
        self.position_slider.setInvertedAppearance(False)
        self.position_slider.setInvertedControls(False)
        self.position_slider.setObjectName("position_slider")
        self.horizontalLayout.addWidget(self.position_slider)

        self.time_status = QtWidgets.QLabel(self.pos_frame)
        font = QtGui.QFont()
        font.setFamily("Arial Rounded MT Bold")
        font.setPointSize(8)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.time_status.setFont(font)
        self.time_status.setStyleSheet(
            "QLabel\n"
            "    {\n"
            "    \n"
            "    font: 8pt \"Arial Rounded MT Bold\";\n"
            "    color: white;\n"
            "    border: 0px solid #076100;\n"
            "\n"
            "    }")
        self.time_status.setObjectName("time_status")
        self.horizontalLayout.addWidget(self.time_status)

        self.backslash = QtWidgets.QLabel(self.pos_frame)
        font = QtGui.QFont()
        font.setFamily("Arial Rounded MT Bold")
        font.setPointSize(8)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.backslash.setFont(font)
        self.backslash.setStyleSheet(
            "QLabel\n"
            "    {\n"
            "    \n"
            "    font: 8pt \"Arial Rounded MT Bold\";\n"
            "    color: white;\n"
            "    border: 0px solid #076100;\n"
            "\n"
            "    }")
        self.backslash.setObjectName("backslash")
        self.horizontalLayout.addWidget(self.backslash)

        self.duration_status = QtWidgets.QLabel(self.pos_frame)
        font = QtGui.QFont()
        font.setFamily("Arial Rounded MT Bold")
        font.setPointSize(8)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.duration_status.setFont(font)
        self.duration_status.setStyleSheet(
            "QLabel\n"
            "    {\n"
            "    \n"
            "    font: 8pt \"Arial Rounded MT Bold\";\n"
            "    color: white;\n"
            "    border: 0px solid #076100;\n"
            "\n"
            "    }")
        self.duration_status.setObjectName("duration_status")
        self.horizontalLayout.addWidget(self.duration_status)
        self.verticalLayout.addWidget(self.pos_frame)

        self.frame_2 = QtWidgets.QFrame(self.mainFrame)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.MinimumExpanding,
            QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(22)
        # sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())

        self.frame_2.setSizePolicy(sizePolicy)
        self.frame_2.setContentsMargins(0, 0, 0, 0)
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.frame_2.setStyleSheet("")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame_2)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")

        self.play_button = QtWidgets.QPushButton(self.frame_2)
        self.play_button.setEnabled(False)
        self.play_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.play_button.setStyleSheet(
            "QPushButton[play=true]{image:url(icon_sets/play/play.png);width:22px;height:22px}\n"
            "QPushButton[play=false]{image:url(icon_sets/pause/pause.png);width:22px;height:22px }\n"
        )
        self.play_button.setProperty("play", True)
        self.play_button.setText("")
        self.play_button.setObjectName("play_button")
        self.horizontalLayout_4.addWidget(self.play_button)

        self.playback_button = QtWidgets.QPushButton(self.frame_2)
        self.playback_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.playback_button.setStyleSheet(
            "QPushButton{image:url(icon_sets/playback/playback.png);width:22px;height:22px }\n"
        )
        self.playback_button.setText("")
        self.playback_button.setObjectName("playback_button")
        self.horizontalLayout_4.addWidget(self.playback_button)

        self.always_on_top_button = QtWidgets.QPushButton(self.frame_2)
        self.always_on_top_button.setCursor(
            QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.always_on_top_button.setStyleSheet(
            "QPushButton[top=false]{image : url(icon_sets/always_on_top/top_off.png) }\n"
            "QPushButton[top=true]{image : url(icon_sets/always_on_top/top_on.png) }\n"
        )
        self.always_on_top_button.setProperty("top", True)
        self.always_on_top_button.setText("")
        self.always_on_top_button.setObjectName("always_on_top_button")
        self.horizontalLayout_4.addWidget(self.always_on_top_button)

        self.miniplayer_button = QtWidgets.QPushButton(self.frame_2)
        self.miniplayer_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.miniplayer_button.setStyleSheet(
            "QPushButton[mini=false]{image : url(icon_sets/standard_player/standard.png) }\n"
            # "QPushButton[mini=false]:hover{ image:url(icon_sets/standard_player/.png) }\n"
            "QPushButton[mini=true]{image : url(icon_sets/mini_player/mini.png) }\n"
            # "QPushButton[mini=true]:hover{ image:url(icon_sets/mini_player/.png) }\n"
        )
        self.miniplayer_button.setProperty("mini", False)
        self.miniplayer_button.setContentsMargins(0, 0, 0, 0)
        self.miniplayer_button.setText("")
        self.miniplayer_button.setObjectName("miniplayer_button")
        self.horizontalLayout_4.addWidget(self.miniplayer_button)

        self.open_File_button = QtWidgets.QPushButton(self.frame_2)
        self.open_File_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.open_File_button.setStyleSheet(
            "QPushButton{image:url(icon_sets/new_file/new_file.png);width:22px;height:22px }\n"
        )
        self.open_File_button.setText("")
        self.open_File_button.setObjectName("playback_button")
        self.horizontalLayout_4.addWidget(self.open_File_button)

        spacerItem1 = QtWidgets.QSpacerItem(40, 20,
                                            QtWidgets.QSizePolicy.Expanding,
                                            QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem1)

        self.screenshot_button = QtWidgets.QPushButton(self.frame_2)
        self.screenshot_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.screenshot_button.setStyleSheet(
            "QPushButton{image : url(icon_sets/snapshot/snapshot.png);width:22px;height:22px} \n"
        )
        self.screenshot_button.setText("")
        self.screenshot_button.setObjectName("screenshot_button")
        self.horizontalLayout_4.addWidget(self.screenshot_button)
        ''' Video Setting button for Video subs and dubs'''
        # self.video_setting_button = QtWidgets.QPushButton(self.frame_2)
        # self.video_setting_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        # self.video_setting_button.setText("")
        # self.video_setting_button.setIconSize(QtCore.QSize(22, 22))
        # self.video_setting_button.setStyleSheet("QPushButton{image : url(icon_sets/video_setting/video_settings.png) }\n"
        #                                         )
        # self.video_setting_button.setObjectName("video_setting_button")
        # self.horizontalLayout_4.addWidget(self.video_setting_button)

        self.setting_button = QtWidgets.QPushButton(self.frame_2)
        self.setting_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.setting_button.setStyleSheet(
            "QPushButton{image : url(icon_sets/settings/settings.png) }\n")
        self.setting_button.setText("")
        self.setting_button.setObjectName("setting_button")
        self.horizontalLayout_4.addWidget(self.setting_button)

        self.Quality_box = QtWidgets.QComboBox(self.frame_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.Quality_box.sizePolicy().hasHeightForWidth())
        self.Quality_box.setSizePolicy(sizePolicy)
        self.Quality_box.setStyleSheet(
            "QComboBox\n"
            "    {\n"
            "	border-image :url(icon_sets/quality/border.png);\n"
            "    color: #fcffff;\n"
            "    font-size: 8pt;\n"
            "    font-weight: bold;\n"
            #    "    width: 41px;\n"
            "    background-color: #000000;\n"
            "    }\n"
            "    QComboBox QAbstractItemView \n"
            "    {\n"
            "    background: #fcffff;\n"
            "    border: 2px solid darkgray;\n"
            "    selection-background-color: #000000;\n"
            "    }\n"
            "QComboBox::drop-down {\n"
            "    border: 0px;\n"
            "    subcontrol-origin: padding;\n"
            "    subcontrol-position: top right;\n"
            "\n"
            "    border-top-right-radius: 3px;\n"
            "    border-bottom-right-radius: 3px;\n"
            "}\n")
        self.Quality_box.setIconSize(QtCore.QSize(0, 0))
        self.Quality_box.setDuplicatesEnabled(False)
        self.Quality_box.setObjectName("comboBox")
        self.Quality_box.addItem("     -")
        self.horizontalLayout_4.addWidget(self.Quality_box)

        self.volume_button = QtWidgets.QPushButton(self.frame_2)
        self.volume_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.volume_button.setText("")
        icon9 = QtGui.QIcon()
        icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume1.png"),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.volume_button.setIcon(icon9)
        self.volume_button.setIconSize(QtCore.QSize(22, 22))
        self.volume_button.setCheckable(True)
        # self.volume_button.setFlat(True)
        self.volume_button.setObjectName("volume_button")
        self.horizontalLayout_4.addWidget(self.volume_button)

        self.volumeslider = VolSlider(self.frame_2)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.volumeslider.sizePolicy().hasHeightForWidth())
        self.volumeslider.setSizePolicy(sizePolicy)
        self.volumeslider.setAutoFillBackground(False)
        self.volumeslider.setStyleSheet(
            "QSlider::handle:horizontal \n"
            "    {\n"
            "    background: transparent;\n"
            "    width: 5px;\n"
            "    }\n"
            "QSlider::groove:horizontal {\n"
            "    border: 1px solid #444444;\n"
            "    height: 5px;\n"
            "    background: qlineargradient(y1: 0, y2: 1,stop: 0 grey, stop: 1.0 grey);\n"
            "}\n"
            " QSlider::sub-page:horizontal {\n"
            "    background:qlineargradient( y1: 0, y2: 1,\n"
            "        stop: 0 #42a6db, stop: 1 #0074e0); \n"
            "    border: 1px solid #777;\n"
            "    height: 5px;\n"
            "}\n"
            "QSlider::handle:horizontal:hover {\n"
            "    background: black;\n"
            "    height: 5px;\n"
            "    width: 5px;\n"
            "    border: 1px solid #0074e0;\n"
            "    }\n"
            "QSlider::sub-page:horizontal:disabled{background:qlineargradient( y1: 0, y2: 1,\n"
            "        stop: 0 #909090, stop: 1 #A8A8A8 );}\n"
            "")
        self.volumeslider.setOrientation(QtCore.Qt.Horizontal)
        self.volumeslider.setObjectName("volume_slider")
        self.horizontalLayout_4.addWidget(self.volumeslider)

        self.volume_percentage = QtWidgets.QLabel(self.frame_2)
        self.volume_percentage.setStyleSheet(
            "QLabel\n"
            "    {\n"
            "    font: 7pt \"Arial Rounded MT Bold\";\n"
            "    color: white;\n"
            "    border: 0px solid #076100;\n"
            "    }")
        self.volume_percentage.setObjectName("volume_status")
        self.volume_percentage.setMinimumWidth(35)
        self.volume_percentage.setText(" 75 %")
        self.horizontalLayout_4.addWidget(self.volume_percentage)

        self.verticalLayout.addWidget(self.frame_2)

        self.frame = QtWidgets.QFrame(self.mainFrame)
        font = QtGui.QFont()
        font.setFamily("Lucida Console")
        self.frame.setFont(font)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.frame)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")

        sizegrip_2 = QtWidgets.QSizeGrip(Form)
        sizegrip_2.setStyleSheet("image:url(icon_sets/.png)")
        self.horizontalLayout_5.addWidget(
            sizegrip_2, 0, QtCore.Qt.AlignBottom | QtCore.Qt.AlignLeft)

        # self.enter_url_label = QtWidgets.QLabel(self.frame)
        # font = QtGui.QFont()
        # font.setFamily("Arial Rounded MT Bold")
        # font.setPointSize(8)
        # font.setBold(False)
        # font.setItalic(False)
        # font.setWeight(50)
        # self.enter_url_label.setFont(font)
        # self.enter_url_label.setStyleSheet("QLabel\n"
        #                                    "    {\n"
        #                                    "    \n"
        #                                    "    font: 8pt \"Arial Rounded MT Bold\";\n"
        #                                    "    color: white;\n"
        #                                    "    border: 0px solid #076100;\n"
        #                                    "    }")
        # self.enter_url_label.setObjectName("enter_url_label")
        # self.horizontalLayout_5.addWidget(self.enter_url_label)

        self.url_box = QtWidgets.QComboBox(self.frame)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.MinimumExpanding,
            QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(200)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.url_box.sizePolicy().hasHeightForWidth())
        self.url_box.setSizePolicy(sizePolicy)
        self.url_box.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.url_box.setMouseTracking(False)
        self.url_box.setAcceptDrops(False)
        self.url_box.setWhatsThis("")
        self.url_box.setAccessibleDescription("")
        self.url_box.setAutoFillBackground(True)
        self.url_box.setStyleSheet("QComboBox\n"
                                   "    {\n"
                                   "    border: 2px solid #0074e0;\n"
                                   "    color: #fcffff;\n"
                                   "    font-size: 8pt;\n"
                                   "    font-weight: bold;\n"
                                   "    background-color: #000000;\n"
                                   "    border-radius: 6px;\n"
                                   "    }\n"
                                   "    QComboBox QAbstractItemView \n"
                                   "    {\n"
                                   "    background: #fcffff;\n"
                                   "    border: 2px solid darkgray;\n"
                                   "    selection-background-color: #000000;\n"
                                   "    }\n"
                                   "QComboBox::down-arrow {\n"
                                   "     image: url(icon_sets/url/url4.png)\n"
                                   "}\n"
                                   "QComboBox::drop-down {\n"
                                   "    subcontrol-origin: padding;\n"
                                   "    subcontrol-position: top right;\n"
                                   "    width: 20px;\n"
                                   " \n"
                                   "    border-top-right-radius: 3px;\n"
                                   "    border-bottom-right-radius: 3px;\n"
                                   "}")
        self.url_box.setInputMethodHints(QtCore.Qt.ImhUrlCharactersOnly)
        self.url_box.setEditable(True)
        self.url_box.setCurrentText("")
        self.url_box.setMaxVisibleItems(100)
        self.url_box.setMaxCount(100)
        self.url_box.setInsertPolicy(QtWidgets.QComboBox.InsertAtCurrent)
        self.url_box.setSizeAdjustPolicy(
            QtWidgets.QComboBox.AdjustToContentsOnFirstShow)
        self.url_box.setMinimumContentsLength(2)
        self.url_box.setIconSize(QtCore.QSize(20, 20))
        self.url_box.setDuplicatesEnabled(False)
        self.url_box.setFrame(True)
        self.url_box.setObjectName("url_box")
        self.horizontalLayout_5.addWidget(self.url_box)
        self.verticalLayout.addWidget(self.frame)

        sizegrip_1 = QtWidgets.QSizeGrip(Form)
        sizegrip_1.setStyleSheet(
            "image:url(icon_sets/size.png);width:15; height:18;")
        self.horizontalLayout_5.addWidget(
            sizegrip_1, 0, QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight)

        self.verticalLayout_2.addWidget(self.mainFrame)

        self.retranslateUi(Form)
        self.url_box.setCurrentIndex(-1)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Q-Stream Player"))
        self.Player_name.setText(_translate("Form", "Q-Stream Player"))
        self.time_status.setText(_translate("Form", "00:00:00"))
        self.backslash.setText(_translate("Form", "/"))
        self.duration_status.setText(_translate("Form", "00:00:00"))
        # self.enter_url_label.setText(_translate("Form", statusList[4]))

        # Set intial Volume
        self.volumeslider.setRange(0, 100)
        self.volumeslider.setValue(75)
        self.mediaPlayer.setVolume(75)
        self.position_slider.setRange(0, 100)

        # connecting buttons
        self.miniplayer_button.clicked.connect(self.setupMiniPlayer)
        self.position_slider.sliderMoved.connect(self.setPosition)
        self.position_slider.sliderMoved.connect(self.handleLabel)
        self.volume_button.clicked.connect(self.mute)
        self.volumeslider.valueChanged.connect(self.setVolume)
        self.screenshot_button.clicked.connect(self.screenshot)
        self.playback_button.clicked.connect(self.stopplayback)
        self.always_on_top_button.clicked.connect(self.checkOnTop)
        self.play_button.clicked.connect(self.play)
        self.open_File_button.clicked.connect(self.openFile)
        # self.video_setting_button.clicked.connect(self.handleQuality)
        self.setting_button.clicked.connect(self.handleSetting)
        self.Quality_box.currentTextChanged.connect(self.handleQuality)
        self.cross_button.clicked.connect(self.exit)
        self.maximize_button.clicked.connect(self.max)
        self.minimize_button.clicked.connect(self.min)

        # Shortcuts
        shortcut = QShortcut(QKeySequence('Esc'), self.video_playback)
        shortcut.activated.connect(self.EscFun)
        shortcut = QShortcut(QKeySequence('Space'), self.video_playback)
        shortcut.activated.connect(self.play)
        shortcut = QShortcut(QKeySequence('f'), self.video_playback)
        shortcut.activated.connect(self.fullscreen_video)
        shortcut = QShortcut(QKeySequence('c'), self.video_playback)
        shortcut.activated.connect(self.setupMiniPlayer)
        shortcut = QShortcut(QKeySequence('o'), self.video_playback)
        shortcut.activated.connect(self.openFile)
        shortcut = QShortcut(QKeySequence('a'), self.video_playback)
        shortcut.activated.connect(self.checkOnTop)
        shortcut = QShortcut(QKeySequence("Return"), self.video_playback)
        shortcut.activated.connect(self.playOnline)
        shortcut = QShortcut(QKeySequence('m'), self.video_playback)
        shortcut.activated.connect(self.mute)
        shortcut = QShortcut(QKeySequence(Qt.Key_Right), self.video_playback)
        shortcut.activated.connect(self.forwardSlider)
        shortcut = QShortcut(QKeySequence(Qt.Key_Left), self.video_playback)
        shortcut.activated.connect(self.backSlider)
        self.volupshortcut = QShortcut(QKeySequence(Qt.Key_Up),
                                       self.video_playback)
        self.volupshortcut.activated.connect(self.volumeUp)
        self.voldownshortcut = QShortcut(QKeySequence(Qt.Key_Down),
                                         self.video_playback)
        self.voldownshortcut.activated.connect(self.volumeDown)
        shortcut = QShortcut(QKeySequence(Qt.ControlModifier + Qt.Key_Right),
                             self.video_playback)
        shortcut.activated.connect(self.forwardSlider10)
        shortcut = QShortcut(QKeySequence(Qt.ControlModifier + Qt.Key_Left),
                             self.video_playback)
        shortcut.activated.connect(self.backSlider10)
        shortcut = QShortcut(QKeySequence(Qt.AltModifier + Qt.Key_Left),
                             self.video_playback)
        shortcut.activated.connect(self.backSlider5)
        shortcut = QShortcut(QKeySequence(Qt.AltModifier + Qt.Key_Right),
                             self.video_playback)
        shortcut.activated.connect(self.forwardSlider5)

        # loading history to Url Box
        items = self.load()
        self.url_box.addItems(items)
        self.url_box.setCurrentIndex(-1)

        # icon size
        # iconSize = QSize(5,5)
        # self.play_button.setIconSize(iconSize)
        # self.playback_button.setIconSize(iconSize)
        # self.screenshot_button.setIconSize(iconSize)
        # self.always_on_top_button.setIconSize(iconSize)
        # self.miniplayer_button.setIconSize(iconSize)
        # self.setting_button.setIconSize(iconSize)
        # self.volume_button.setIconSize(iconSize)

        # button size
        btnSize = QSize(22, 22)
        self.play_button.setMaximumSize(btnSize)
        self.playback_button.setMaximumSize(btnSize)
        self.screenshot_button.setMaximumSize(btnSize)
        self.always_on_top_button.setMaximumSize(btnSize)
        self.miniplayer_button.setMaximumSize(btnSize)
        # self.video_setting_button.setMaximumSize(btnSize)
        self.setting_button.setMaximumSize(btnSize)
        self.volume_button.setMaximumSize(btnSize)

        # set margin
        self.horizontalLayout.setContentsMargins(10, 5, 9, 0)
        self.horizontalLayout_4.setContentsMargins(9, 0, 9, 0)
        self.horizontalLayout_4.setSpacing(4)
        self.horizontalLayout_5.setContentsMargins(0, 5, 5, 5)
        self.horizontalLayout_6.setContentsMargins(9, 0, 9, 0)

        # Media player settings
        self.mediaPlayer.setVideoOutput(self.video_playback)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.positionChanged.connect(self.handleLabel)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)

    def handleLabel(self):
        self.time_status.clear()
        mtime = QtCore.QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.time_status.setText(self.time.toString())

    def hide_all(self):
        self.frame_3.close()
        # self.frame.close()
        self.url_box.close()
        self.playback_button.close()
        self.screenshot_button.close()
        self.Quality_box.close()
        self.volume_button.close()
        # self.video_setting_button.close()
        # self.setting_button.close()

    def show_all(self):
        self.frame_3.show()
        # self.frame.show()
        self.url_box.show()
        self.playback_button.show()
        self.screenshot_button.show()
        self.Quality_box.show()
        self.volume_button.show()
        # self.video_setting_button.show()
        self.setting_button.show()

    def checkOnTop(self):
        self.isOnTop = not self.isOnTop
        if self.isOnTop:
            self.always_on_top_button.setProperty("top", True)
            self.always_on_top_button.setStyle(
                self.always_on_top_button.style())
            Form.setWindowFlags(Form.windowFlags()
                                | QtCore.Qt.WindowStaysOnTopHint)
        else:
            self.always_on_top_button.setProperty("top", False)
            self.always_on_top_button.setStyle(
                self.always_on_top_button.style())
            Form.setWindowFlags(Form.windowFlags()
                                & ~QtCore.Qt.WindowStaysOnTopHint)
        Form.show()

    def miniProperty(self):
        self.video_playback.setMinimumSize(QSize(200, 100))
        self.video_playback.resize(QSize(550, 270))
        Form.resize(QSize(550, 270))
        Form.setMinimumSize(QSize(200, 175))
        self.mainFrame.setMinimumSize(QSize(200, 60))
        self.mainFrame.resize(QSize(200, 53))

    def standardProperty(self):
        self.video_playback.setMinimumSize(QSize(200, 100))
        self.mainFrame.setMinimumSize(QSize(200, 82))
        Form.setMinimumSize(QSize(200, 202))
        Form.resize(550, 369)

    def setupMiniPlayer(self):
        self.isMini = not self.isMini
        if self.isMini:
            self.miniplayer_button.setProperty("mini", True)
            self.miniplayer_button.setStyle(self.miniplayer_button.style())
            self.hide_all()
            self.miniProperty()

        else:
            self.miniplayer_button.setProperty("mini", False)
            self.miniplayer_button.setStyle(self.miniplayer_button.style())
            self.standardProperty()

            self.show_all()

    def load(self):
        scorefile = "db.bat"
        if os.path.exists(scorefile):
            with open(scorefile, 'rb') as sf:
                scores = pickle.load(sf)
        else:
            scores = []

        with open(scorefile, "wb") as sf:
            pickle.dump(scores, sf)
        return scores

    def scor_func(self, url):
        scorefile = "db.bat"
        if os.path.exists(scorefile):
            with open(scorefile, 'rb') as sf:
                scores = pickle.load(sf)
        else:
            scores = []
        scores.append(url)

        with open(scorefile, "wb") as sf:
            if len(scores) > 100:
                print("here", scores)
                scores = scores[1:]
            pickle.dump(scores, sf)
        return scores

    def mute(self):
        if self.mediaPlayer.isMuted():
            print('[ ! Full Volume]')
            self.mediaPlayer.setMuted(False)
            icon9 = QtGui.QIcon()
            icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume1.png"),
                            QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.volume_button.setIcon(icon9)
            self.volume_button.setIconSize(QSize(22, 22))
            self.volumeslider.setEnabled(True)
            # shortcut Enable
            self.volupshortcut.setEnabled(True)
            self.voldownshortcut.setEnabled(True)

        else:
            print('[ ! Mute Volume]')
            self.mediaPlayer.setMuted(True)
            icon9 = QtGui.QIcon()
            icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume2.png"),
                            QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.volume_button.setIcon(icon9)
            self.volume_button.setIconSize(QSize(22, 22))
            self.volumeslider.setEnabled(False)
            # shrotcut disable
            self.volupshortcut.setEnabled(False)
            self.voldownshortcut.setEnabled(False)

    def play(self):
        if self.mediaPlayer.isVideoAvailable():
            if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
                print("[ ! PAUSE PRESSED ]")
                self.mediaPlayer.pause()
            else:
                print("[ ! PLAY PRESSED ]")
                self.mediaPlayer.play()

    def playOnline(self):
        if self.url_box.currentText() != '':
            print('[ ! GETTING VIDEO ONLINE ]')
            fileName = self.url_box.currentText()
            res = requests.get('https://mediaplayerserver.herokuapp.com/',
                               params={"key": fileName})
            try:
                self.streams = json.loads(res.text)
                try:
                    self.mediaPlayer.setMedia(
                        QMediaContent(QUrl(self.streams['best'])))
                    self.play_video()
                    self.isOnline = True
                    self.addQuality()
                    if self.url_box.findText(fileName, Qt.MatchExactly) < 0:
                        self.url_box.addItem(fileName)
                        self.scor_func(fileName)
                except KeyError:
                    print("[ ! Error Video Not Supported By platform]")
            except json.JSONDecodeError:
                print("[ ! Error NoPluginError]")
            finally:
                self.url_box.setCurrentText("")

    def openFile(self):
        print('[ ! OPEN FILE ]')
        username = getpass.getuser()
        if sys.platform == 'win32':
            path = 'C:/Users/' + username + '/Videos/'
        elif sys.platform == 'linux' or sys.platform == 'Darwin':
            path = '/home/' + username + '/Videos/'

        formats = str.join(' ', [
            '*.%s' % str(fmt).strip('b').strip("'")
            for fmt in QtGui.QMovie.supportedFormats()
        ])

        fileName, _ = QFileDialog.getOpenFileName(
            self.video_playback, "Select media file", path,
            "Video Files (*.mp4 *.flv *.ts *.mts *.avi *.mkv)")
        if fileName != '':
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(fileName)))
            self.play_video()

    # def decodeLink(self,url):
    #     try:
    #         streams = streamlink.streams(url)
    #         keys = [k for k in streams.keys()]
    #         data = dict()
    #         for k in keys:
    #             data[k] = streams[k].url
    #         return data

    #     except streamlink.NoPluginError:
    #         return None

    # def playOnline(self):
    #         if self.url_box.currentText() != '':
    #             print('[ ! GETTING VIDEO ONLINE ]')
    #             fileName = self.url_box.currentText()
    #             self.streams = self.decodeLink(fileName)
    #             try:
    #                 self.mediaPlayer.setMedia(QMediaContent(QUrl(self.streams['best'])))
    #                 self.play_video()
    #                 self.isOnline = True
    #                 self.addQuality()
    #                 if self.url_box.findText(fileName, Qt.MatchExactly) < 0:
    #                     self.url_box.addItem(fileName)
    #                     self.scor_func(fileName)
    #             except KeyError:
    #                 print("[ ! Error Video Not Supported By platform]")
    #             finally:
    #                 self.url_box.setCurrentText("")

    def play_video(self):
        print('[ ! PLAYING VIDEO ]')
        self.play_button.setEnabled(True)
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()

    def mediaStateChanged(self, state):
        print('[ ! CHANGING MEDIA STATE ]')
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.play_button.setProperty('play', False)
            self.play_button.setStyle(self.play_button.style())
        else:
            self.play_button.setProperty('play', True)
            self.play_button.setStyle(self.play_button.style())

    def stopplayback(self):
        print('[ ! STOP PLAYBACK VIDEO ]')
        self.mediaPlayer.stop()
        self.play_video()

    def positionChanged(self, position):
        print('[ ! POSITION CHANGED ]')
        self.position_slider.setValue(position)

    def durationChanged(self, duration):
        print('[ ! DURATION CHANGED ]')
        self.position_slider.setRange(0, duration)
        self.duration_status.clear()
        mtime = QtCore.QTime(0, 0, 0, 0)
        time = mtime.addMSecs(self.mediaPlayer.duration())
        self.duration_status.setText(time.toString())

    def setPosition(self, position):
        print('[ ! POSITION SET ]')
        self.mediaPlayer.setPosition(position)

    def setVolumePos(self, remain):
        print('[ ! REMANING VOLUME ]')
        print(remain)
        self.volumeslider.setRange(remain, 100)

    def setVolume(self, vol):
        print('[ ! SET VOLUME ]')
        print("set volume  = " + str(vol))
        if vol >= 0 and vol <= 100:
            self.volume_percentage.setText(" " + str(vol) + " %")
        if vol <= 0:
            icon9 = QtGui.QIcon()
            icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume2.png"),
                            QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.volume_button.setIcon(icon9)
        else:
            icon9 = QtGui.QIcon()
            icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume1.png"),
                            QtGui.QIcon.Normal, QtGui.QIcon.Off)
            self.volume_button.setIcon(icon9)

        self.volumeslider.setValue(vol)
        self.mediaPlayer.setVolume(vol)

    def screenshot(self):

        print('[ ! SCREENSHOT ]')
        wincen = Form.geometry()
        topX = wincen.topLeft().x()
        topY = wincen.topLeft().y()
        geo = self.video_playback.geometry()
        image = pyautogui.screenshot(region=(topX, topY + 38, geo.width(),
                                             geo.height() - 35))

        filename = "screenshot" + str(uuid.uuid4()) + ".png"
        username = getpass.getuser()

        if sys.platform == 'win32':
            path = 'C:/Users/' + username + '/Pictures/' + filename
        elif sys.platform == 'linux' or sys.platform == 'Darwin':
            path = '/home/' + username + '/Pictures/' + filename
        image.save(path)

    def EscFun(self):
        if self.video_playback.isFullScreen():
            Form.show()
            self.video_playback.setFullScreen(False)

    def fullscreen_video(self):
        if self.mediaPlayer.isVideoAvailable():
            if self.video_playback.isFullScreen():
                self.video_playback.setFullScreen(False)
                print('[ ! Normal Screen ]')
                Form.show()
            else:
                print('[ ! Full Screen ]')
                self.video_playback.setFullScreen(True)
                Form.hide()

    def getFormat(self):
        li = [k for k in self.streams.keys()]
        for q in li:
            if q.startswith('audio'):
                li.remove(q)
                try:
                    li.remove('audio_opus')
                except ValueError:
                    pass
        return li

    def changeQuality(self, quality):
        pos = self.mediaPlayer.position()
        try:
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl(self.streams[quality])))
        except KeyError:
            pass
        self.setPosition(pos)
        self.mediaPlayer.play()

    def handleSetting(self):
        from setting import SettingDialog
        dlg = SettingDialog()
        dlg.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        dlg.exec_()

    def addQuality(self):
        self.Quality_box.clear()
        self.Quality_box.addItems(self.getFormat())

    def handleQuality(self):
        if self.isOnline:
            self.changeQuality(self.Quality_box.currentText())

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000)

    def forwardSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000)

    def forwardSlider5(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 5000)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000)

    def backSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000)

    def backSlider5(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 5000)

    def volumeUp(self):
        self.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def max(self):
        if not Form.isMaximized():
            print("[! Window is Maximized]")
            Form.showMaximized()
        else:
            print("[! Window is Normal]")
            Form.showNormal()

    def min(self):
        if not Form.isMinimized():
            print("[! Window is Minimized]")
            Form.showMinimized()
        else:
            print("[! Window is Normal]")
            Form.showNormal()

    def exit(self):
        self.mediaPlayer.stop()
        sys.exit()
Beispiel #24
0
class videoPlayer(QVideoWidget):
    def __init__(self, parent):

        super(QVideoWidget, self).__init__(parent)
        self.player = QMediaPlayer(self)
        self.player.setVolume(50)
        self.player.setVideoOutput(self)
        self.player.mediaStatusChanged.connect(self.mediaStatusChanged)

    def update(self, path):

        if path: path = QUrl.fromLocalFile(path)
        self.player.setMedia(QMediaContent(path))
        self.player.play()

    def rotate(self, path, sign):

        self.update(None)
        clip = VideoFileClip(path)
        clip.rotate(90 * sign)

        if path.endswith(('gif')):
            clip.write_gif(path)
        else:
            clip.write_videofile(path)

        clip.close()

    def pause(self):

        status = self.player.state()
        if status == QMediaPlayer.PlayingState: self.player.pause()
        elif status == QMediaPlayer.PausedState: self.player.play()

    def position(self, delta):

        self.player.setPosition(self.player.position() + delta)

    def volume(self, delta):

        if self.player.isAudioAvailable():

            self.player.setVolume(self.player.volume() + delta)

    def mute(self):

        if self.player.isAudioAvailable():

            self.player.setMuted(not self.player.isMuted())

    def stop(self):
        self.player.stop()

    def mediaStatusChanged(self, status):

        if status == QMediaPlayer.EndOfMedia: self.player.play()

        elif status not in (2, 1):

            self.parent().setCurrentIndex(1)

    def wheelEvent(self, event):

        self.volume(event.angleDelta().y() // 12)
Beispiel #25
0
class QgsFmvPlayer(QMainWindow, Ui_PlayerWindow):
    """ Video Player Class """
    def __init__(self, iface, path=None, parent=None):
        """ Constructor """
        super(QgsFmvPlayer, self).__init__(parent)
        self.setupUi(self)
        self.parent = parent
        self.iface = iface
        self.fileName = None
        self.metadataDlg = None
        self.createingMosaic = False
        self.currentInfo = 0.0

        self.RecGIF = QMovie(":/imgFMV/images/record.gif")

        self.videoWidget.customContextMenuRequested[QPoint].connect(
            self.contextMenuRequested)

        self.duration = 0
        self.playerMuted = False
        self.HasFileAudio = False

        self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.player.setNotifyInterval(1000)  # One second
        self.pass_time = 0.1
        self.playlist = QMediaPlaylist()

        #         self.player.setVideoOutput(
        #             self.videoWidget)  # Standar Surface

        self.player.setVideoOutput(
            self.videoWidget.videoSurface())  # Custom Surface

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)

        self.player.stateChanged.connect(self.setCurrentState)

        self.playerState = QMediaPlayer.StoppedState
        self.playFile(path)

        self.sliderDuration.setRange(0, self.player.duration() / 1000)

        self.volumeSlider.setValue(self.player.volume())
        self.volumeSlider.enterEvent = self.showVolumeTip

        if self.metadataDlg is None:
            self.metadataDlg = QgsFmvMetadata(parent=self, player=self)
            self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg)
            self.metadataDlg.setMinimumWidth(500)
            self.metadataDlg.hide()

    def HasMetadata(self, videoPath):
        """ Check if video have Metadata or not """
        try:
            p = _spawn([
                '-i', videoPath, '-map', 'data-re', '-codec', 'copy', '-f',
                'data', '-'
            ])

            stdout_data, _ = p.communicate()

            if stdout_data == b'':
                qgsu.showUserAndLogMessage(QCoreApplication.translate(
                    "QgsFmvPlayer", "This video don't have Metadata ! : "),
                                           level=QGis.Info)
                return False

            return True
        except Exception as e:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", "Metadata Callback Failed! : "),
                                       str(e),
                                       level=QGis.Info)

    def HasAudio(self, videoPath):
        """ Check if video have Metadata or not """
        try:
            p = _spawn([
                '-i', videoPath, '-show_streams', '-select_streams', 'a',
                '-loglevel', 'error'
            ],
                       type="ffprobe")

            stdout_data, _ = p.communicate()

            if stdout_data == b'':
                qgsu.showUserAndLogMessage(QCoreApplication.translate(
                    "QgsFmvPlayer", "This video don't have Audio ! : "),
                                           level=QGis.Info)
                return False

            return True
        except Exception as e:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", "Audio check Failed! : "),
                                       str(e),
                                       level=QGis.Info)

    def callBackMetadata(self, currentTime, nextTime):
        """ Metadata CallBack """
        try:
            # TODO : Speed this function
            #             stdout_data = _check_output(['-i', self.fileName,
            #                         '-ss', currentTime,
            #                         '-to', nextTime,
            #                         '-f', 'data', '-'])

            t = callBackMetadataThread(cmds=[
                '-i', self.fileName, '-ss', currentTime, '-to', nextTime,
                '-map', 'data-re', '-f', 'data', '-'
            ])
            t.start()
            t.join(1)
            if t.is_alive():
                t.p.terminate()
                t.join()
            if t.stdout == b'':
                return

            for packet in StreamParser(t.stdout):
                try:
                    self.addMetadata(packet.MetadataList())
                    UpdateLayers(packet,
                                 parent=self,
                                 mosaic=self.createingMosaic)
                    self.iface.mapCanvas().refresh()
                    QApplication.processEvents()
                    return
                except Exception as e:
                    None
        except Exception as e:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", "Metadata Callback Failed! : "),
                                       str(e),
                                       level=QGis.Info)

    def addMetadata(self, packet):
        ''' Add Metadata to List '''
        self.clearMetadata()
        row = 0
        for key in sorted(packet.keys()):
            self.metadataDlg.VManager.insertRow(row)
            self.metadataDlg.VManager.setItem(row, 0,
                                              QTableWidgetItem(str(key)))
            self.metadataDlg.VManager.setItem(
                row, 1, QTableWidgetItem(str(packet[key][0])))
            self.metadataDlg.VManager.setItem(
                row, 2, QTableWidgetItem(str(packet[key][1])))
            row += 1
        self.metadataDlg.VManager.setVisible(False)
        self.metadataDlg.VManager.resizeColumnsToContents()
        self.metadataDlg.VManager.setVisible(True)
        self.metadataDlg.VManager.verticalScrollBar().setSliderPosition(
            self.sliderPosition)

    def clearMetadata(self):
        ''' Clear Metadata List '''
        try:
            self.sliderPosition = self.metadataDlg.VManager.verticalScrollBar(
            ).sliderPosition()
            self.metadataDlg.VManager.setRowCount(0)
        except:
            None

    def saveInfoToJson(self):
        """ Save video Info to json """
        if not self.KillAllProcessors():
            return
        out_json, _ = QFileDialog.getSaveFileName(self, "Save File", "",
                                                  "Json Files (*.json)")
        if out_json == "":
            return
        try:
            self.VPProbeToJson = Converter()
            self.VPTProbeToJson = QThread()

            self.VPProbeToJson.moveToThread(self.VPTProbeToJson)

            self.VPProbeToJson.finished.connect(self.QThreadFinished)

            self.VPProbeToJson.error.connect(self.QThreadError)

            self.VPProbeToJson.progress.connect(
                self.progressBarProcessor.setValue)

            self.VPTProbeToJson.start(QThread.LowPriority)

            QMetaObject.invokeMethod(self.VPProbeToJson, 'probeToJson',
                                     Qt.QueuedConnection,
                                     Q_ARG(str, self.fileName),
                                     Q_ARG(str, out_json))

        except Exception as e:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Error saving Json"))
            self.QThreadFinished("probeToJson", "Closing ProbeToJson")

    def showVideoInfo(self):
        ''' Show default probe info '''
        try:

            self.VPProbe = Converter()
            self.VPTProbe = QThread()

            self.VPProbe.moveToThread(self.VPTProbe)

            self.VPProbe.finishedJson.connect(self.QThreadFinished)

            self.VPProbe.error.connect(self.QThreadError)

            self.VPProbe.progress.connect(self.progressBarProcessor.setValue)

            self.VPTProbe.start(QThread.LowPriority)

            QMetaObject.invokeMethod(self.VPProbe, 'probeShow',
                                     Qt.QueuedConnection,
                                     Q_ARG(str, self.fileName))

        except Exception as e:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer", "Error Info Show"))
            self.QThreadFinished("probeShow", "Closing Probe")
        return

    def state(self):
        ''' Return Current State '''
        return self.playerState

    def setCurrentState(self, state):
        ''' Set Current State '''
        if state != self.playerState:
            self.playerState = state

            if state == QMediaPlayer.StoppedState:
                self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png"))

        return

    def showColorDialog(self):
        ''' Show Color dialog '''
        self.ColorDialog = ColorDialog(parent=self)
        self.ColorDialog.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint)
        # Fail if not uncheked
        self.actionMagnifying_glass.setChecked(False)
        self.actionZoom_Rectangle.setChecked(False)
        self.ColorDialog.exec_()
        return

    def createMosaic(self, value):
        ''' Function for create Video Mosaic '''
        home = os.path.expanduser("~")

        qgsu.createFolderByName(home, "QGIS_FMV")
        homefmv = os.path.join(home, "QGIS_FMV")
        root, ext = os.path.splitext(os.path.basename(self.fileName))
        qgsu.createFolderByName(homefmv, root)
        self.createingMosaic = value
        # Create Group
        CreateGroupByName()
        return

    def contextMenuRequested(self, point):
        ''' Context Menu Video '''
        menu = QMenu()

        #         actionColors = menu.addAction(
        #             QCoreApplication.translate("QgsFmvPlayer", "Color Options"))
        #         actionColors.setShortcut("Ctrl+May+C")
        #         actionColors.triggered.connect(self.showColorDialog)

        actionMute = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer", "Mute/Unmute"))
        actionMute.setShortcut("Ctrl+May+U")
        actionMute.triggered.connect(self.setMuted)

        menu.addSeparator()
        actionAllFrames = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer", "Extract All Frames"))
        actionAllFrames.setShortcut("Ctrl+May+A")
        actionAllFrames.triggered.connect(self.ExtractAllFrames)

        actionCurrentFrames = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer",
                                       "Extract Current Frame"))
        actionCurrentFrames.setShortcut("Ctrl+May+Q")
        actionCurrentFrames.triggered.connect(self.ExtractCurrentFrame)

        menu.addSeparator()
        actionShowMetadata = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer", "Show Metadata"))
        actionShowMetadata.setShortcut("Ctrl+May+M")
        actionShowMetadata.triggered.connect(self.OpenQgsFmvMetadata)

        menu.exec_(self.mapToGlobal(point))

    # Start Snnipet FILTERS
    def grayFilter(self, value):
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetGray(value)
        self.videoWidget.UpdateSurface()
        return

    def edgeFilter(self, value):
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetEdgeDetection(value)
        self.videoWidget.UpdateSurface()
        return

    def invertColorFilter(self, value):
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetInvertColor(value)
        self.videoWidget.UpdateSurface()
        return

    def autoContrastFilter(self, value):
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetAutoContrastFilter(value)
        self.videoWidget.UpdateSurface()
        return

    def monoFilter(self, value):
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetMonoFilter(value)
        self.videoWidget.UpdateSurface()
        return

    def magnifier(self, value):
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetMagnifier(value)
        self.videoWidget.UpdateSurface()
        return

    def zoomRect(self, value):
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetZoomRect(value)
        self.videoWidget.UpdateSurface()
        return

    def UncheckUtils(self, sender, value):
        #         p = self.player.position()
        #         self.player.setVideoOutput(
        #             self.videoWidget.videoSurface())  # Custom surface
        #         self.player.setPosition(p)
        QApplication.processEvents()
        name = sender.objectName()
        self.actionMagnifying_glass.setChecked(
            True if name == "actionMagnifying_glass" else False)
        self.actionZoom_Rectangle.setChecked(True if name ==
                                             "actionZoom_Rectangle" else False)

        sender.setChecked(value)
        return

    def UncheckFilters(self, sender, value):
        #         p = self.player.position()
        #         self.player.setVideoOutput(
        #             self.videoWidget.videoSurface())  # Custom surface
        #         self.player.setPosition(p)
        #         QApplication.processEvents()
        name = sender.objectName()

        self.actionGray.setChecked(True if name == "actionGray" else False)
        self.actionInvert_Color.setChecked(True if name ==
                                           "actionInvert_Color" else False)
        self.actionMono_Filter.setChecked(True if name ==
                                          "actionMono_Filter" else False)
        self.actionCanny_edge_detection.setChecked(
            True if name == "actionCanny_edge_detection" else False)
        self.actionAuto_Contrast_Filter.setChecked(
            True if name == "actionAuto_Contrast_Filter" else False)

        self.videoWidget.SetGray(True if name == "actionGray" else False)
        self.videoWidget.SetEdgeDetection(
            True if name == "actionCanny_edge_detection" else False)
        self.videoWidget.SetInvertColor(True if name ==
                                        "actionInvert_Color" else False)
        self.videoWidget.SetMonoFilter(True if name ==
                                       "actionMono_Filter" else False)
        self.videoWidget.SetAutoContrastFilter(
            True if name == "actionAuto_Contrast_Filter" else False)

        sender.setChecked(value)
        return

    # End Snnipet FILTERS

    def isMuted(self):
        ''' Is muted video property'''
        return self.playerMuted

    def setMuted(self):
        ''' Muted video '''
        if self.player.isMuted():
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png"))
            self.player.setMuted(False)
            self.volumeSlider.setEnabled(True)
        else:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png"))
            self.player.setMuted(True)
            self.volumeSlider.setEnabled(False)
        return

    def stop(self):
        ''' Stop video'''
        self.player.stop()
        self.videoWidget.update()
        return

    def volume(self):
        ''' Volume Slider '''
        return self.volumeSlider.value()

    def setVolume(self, volume):
        ''' Tooltip and set value'''
        self.player.setVolume(volume)
        self.showVolumeTip(volume)
        if 0 < volume <= 30:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_30.png"))
        elif 30 < volume <= 60:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_60.png"))
        elif 60 < volume <= 100:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png"))
        elif volume == 0:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png"))

    def EndMedia(self):
        ''' Button end video position '''
        if self.player.isVideoAvailable():
            self.player.setPosition(self.player.duration())
            self.videoWidget.update()
        return

    def StartMedia(self):
        ''' Button start video position '''
        if self.player.isVideoAvailable():
            self.player.setPosition(0)
            self.videoWidget.update()
        return

    def forwardMedia(self):
        ''' Button forward Video '''
        forwardTime = int(self.player.position()) + 10 * 1000
        if forwardTime > int(self.player.duration()):
            forwardTime = int(self.player.duration())
        self.player.setPosition(forwardTime)

    def rewindMedia(self):
        ''' Button rewind Video '''
        rewindTime = int(self.player.position()) - 10 * 1000
        if rewindTime < 0:
            rewindTime = 0
        self.player.setPosition(rewindTime)

    def AutoRepeat(self, checked):
        ''' Button AutoRepeat Video '''
        if checked:
            self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
        else:
            self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
        return

    def showVolumeTip(self, _):
        ''' Volume Slider Tooltip Trick '''
        self.style = self.volumeSlider.style()
        self.opt = QStyleOptionSlider()
        self.volumeSlider.initStyleOption(self.opt)
        rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt,
                                               self.style.SC_SliderHandle)
        self.tip_offset = QPoint(5, 15)
        pos_local = rectHandle.topLeft() + self.tip_offset
        pos_global = self.volumeSlider.mapToGlobal(pos_local)
        QToolTip.showText(pos_global,
                          str(self.volumeSlider.value()) + " %", self)

    def showMoveTip(self, currentInfo):
        ''' Player Silder Move Tooptip Trick '''
        self.style = self.sliderDuration.style()
        self.opt = QStyleOptionSlider()
        self.sliderDuration.initStyleOption(self.opt)
        rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt,
                                               self.style.SC_SliderHandle)
        self.tip_offset = QPoint(5, 15)
        pos_local = rectHandle.topLeft() + self.tip_offset
        pos_global = self.sliderDuration.mapToGlobal(pos_local)

        tStr = _seconds_to_time(currentInfo)

        QToolTip.showText(pos_global, tStr, self)

    def durationChanged(self, duration):
        ''' Duration video change signal '''
        duration /= 1000
        self.duration = duration
        self.sliderDuration.setMaximum(duration)

    def positionChanged(self, progress):
        ''' Current Video position change '''
        progress /= 1000

        if not self.sliderDuration.isSliderDown():
            self.sliderDuration.setValue(progress)

        self.updateDurationInfo(progress)

    def updateDurationInfo(self, currentInfo):
        ''' Update labels duration Info and CallBack Metadata '''
        duration = self.duration
        self.currentInfo = currentInfo
        if currentInfo or duration:

            totalTime = _seconds_to_time(duration)
            currentTime = _seconds_to_time(currentInfo)
            tStr = currentTime + " / " + totalTime

            nextTime = currentInfo + self.pass_time
            currentTimeInfo = _seconds_to_time_frac(currentInfo)
            nextTimeInfo = _seconds_to_time_frac(nextTime)
            # Metadata CallBack
            self.callBackMetadata(currentTimeInfo, nextTimeInfo)

        else:
            tStr = ""

        self.labelDuration.setText(tStr)

    def handleCursor(self, status):
        ''' Change cursor '''
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia,
                      QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def statusChanged(self, status):
        ''' Signal Status video change '''
        self.handleCursor(status)
        if status == QMediaPlayer.LoadingMedia:
            self.videoAvailableChanged(False)
        elif status == QMediaPlayer.StalledMedia:
            self.videoAvailableChanged(False)
        if status == QMediaPlayer.EndOfMedia:
            self.videoAvailableChanged(True)
        elif status == QMediaPlayer.InvalidMedia:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", self.player.errorString()),
                                       level=QGis.Warning)
            self.videoAvailableChanged(False)
        else:
            self.videoAvailableChanged(True)

    def playFile(self, videoPath):
        ''' Play file from path '''
        try:
            RemoveVideoLayers()
            RemoveGroupByName()
            self.fileName = videoPath
            self.playlist = QMediaPlaylist()
            url = QUrl.fromLocalFile(videoPath)
            self.playlist.addMedia(QMediaContent(url))
            self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
            self.player.setPlaylist(self.playlist)

            self.setWindowTitle("Playing : " +
                                os.path.basename(os.path.normpath(videoPath)))

            if self.HasMetadata(videoPath):
                CreateVideoLayers()
                self.clearMetadata()
                self.lb_cursor_coord.setText(
                    "<span style='font-size:10pt; font-weight:bold;'>Lon :</span>"
                    +
                    "<span style='font-size:9pt; font-weight:normal;'>Null</span>"
                    +
                    "<span style='font-size:10pt; font-weight:bold;'> Lat :</span>"
                    +
                    "<span style='font-size:9pt; font-weight:normal;'>Null</span>"
                )
            else:
                self.btn_GeoReferencing.setEnabled(False)

            self.HasFileAudio = True
            if not self.HasAudio(videoPath):
                self.actionAudio.setEnabled(False)
                self.actionSave_Audio.setEnabled(False)
                self.HasFileAudio = False

            self.playClicked(True)

        except Exception as e:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", 'Open Video File : '),
                                       str(e),
                                       level=QGis.Warning)

    def ReciconUpdate(self, frame):
        self.btn_Rec.setIcon(QIcon(self.RecGIF.currentPixmap()))

    def RecordVideo(self, value):
        ''' Cut Video '''
        currentTime = _seconds_to_time(self.currentInfo)

        if value is False:
            self.endRecord = currentTime
            _, file_extension = os.path.splitext(self.fileName)
            out, _ = QFileDialog.getSaveFileName(self, "Save As", "",
                                                 file_extension)
            if not out:
                self.RecGIF.frameChanged.disconnect(self.ReciconUpdate)
                self.RecGIF.stop()
                self.btn_Rec.setIcon(QIcon(":/imgFMV/images/record.png"))
                return False

            lfn = out.lower()
            if not lfn.endswith((file_extension)):
                out += file_extension

            p = _spawn([
                '-i', self.fileName, '-ss', self.startRecord, '-to',
                self.endRecord, '-c', 'copy', out
            ])
            p.communicate()
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Save file succesfully!"))

            self.RecGIF.frameChanged.disconnect(self.ReciconUpdate)
            self.RecGIF.stop()
            self.btn_Rec.setIcon(QIcon(":/imgFMV/images/record.png"))
        else:
            self.startRecord = currentTime
            self.RecGIF.frameChanged.connect(self.ReciconUpdate)
            self.RecGIF.start()
        return

    def videoAvailableChanged(self, available):
        ''' Buttons for video available '''
        # self.btn_Color.setEnabled(available)
        self.btn_CaptureFrame.setEnabled(available)
        self.gb_PlayerControls.setEnabled(available)
        return

    def toggleGroup(self, state):
        ''' Toggle GroupBox '''
        sender = self.sender()
        if state:
            sender.setFixedHeight(sender.sizeHint().height())
        else:
            sender.setFixedHeight(15)

    def playClicked(self, state):
        ''' Stop and Play video '''
        if self.playerState in (QMediaPlayer.StoppedState,
                                QMediaPlayer.PausedState):
            self.btn_play.setIcon(QIcon(":/imgFMV/images/pause.png"))
            self.player.play()
        elif self.playerState == QMediaPlayer.PlayingState:
            self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png"))
            self.player.pause()

    def seek(self, seconds):
        '''Slider Move'''
        self.player.setPosition(seconds * 1000)
        self.showMoveTip(seconds)

    def convertVideo(self):
        '''Convert Video To Other Format '''
        if not self.KillAllProcessors():
            return
        sel = "mp4 Files (*.mp4)"
        out, _ = QFileDialog.getSaveFileName(
            self, "Save Video as...", None,
            "ogg files (*.ogg);;avi Files (*.avi);;mkv Files (*.mkv);;webm Files (*.webm);;flv Files (*.flv);;mov Files (*.mov);;mp4 Files (*.mp4);;mpg Files (*.mpg);;mp3 Files (*.mp3)",
            sel)

        if not out:
            return False

        lfn = out.lower()
        if not lfn.endswith(('.ogg', '.avi', '.mkv', '.webm', '.flv', '.mov',
                             '.mp4', '.mp3', '.mpg')):
            # The default.
            out += '.mp4'

        try:
            self.VPConverter = Converter()
            self.VPTConverter = QThread()

            self.VPConverter.moveToThread(self.VPTConverter)

            self.VPConverter.finished.connect(self.QThreadFinished)

            self.VPConverter.error.connect(self.QThreadError)

            self.VPConverter.progress.connect(
                self.progressBarProcessor.setValue)

            self.VPTConverter.start(QThread.LowPriority)

            # TODO : Make Correct format Conversion and embebed metadata
            info = self.VPConverter.probeInfo(self.fileName)
            if info is not None:
                if self.HasFileAudio:
                    audio_codec = info.audio.codec
                    audio_samplerate = info.audio.audio_samplerate
                    audio_channels = info.audio.audio_channels

                video_codec = info.video.codec
                video_width = info.video.video_width
                video_height = info.video.video_height
                video_fps = info.video.video_fps

            _, out_ext = os.path.splitext(out)

            if self.HasFileAudio:
                options = {
                    'format': out_ext[1:],
                    'audio': {
                        'codec': audio_codec,
                        'samplerate': audio_samplerate,
                        'channels': audio_channels
                    },
                    'video': {
                        'codec': video_codec,
                        'width': video_width,
                        'height': video_height,
                        'fps': video_fps
                    }
                }
            else:
                options = {
                    'format': out_ext[1:],
                    'video': {
                        'codec': video_codec,
                        'width': video_width,
                        'height': video_height,
                        'fps': video_fps
                    }
                }
            QMetaObject.invokeMethod(self.VPConverter, 'convert',
                                     Qt.QueuedConnection,
                                     Q_ARG(str,
                                           self.fileName), Q_ARG(str, out),
                                     Q_ARG(dict, options), Q_ARG(bool, False))

        except Exception as e:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Error converting video "))
            self.QThreadFinished("convert", "Closing convert")

    def ShowPlot(self, bitrate_data, frame_count, output=None):
        ''' Show plot,because show not work using threading '''
        matplot.figure().canvas.set_window_title(self.fileName)
        matplot.title("Stream Bitrate vs Time")
        matplot.xlabel("Time (sec)")
        matplot.ylabel("Frame Bitrate (kbit/s)")
        matplot.grid(True)
        # map frame type to color
        frame_type_color = {
            # audio
            'A': 'yellow',
            # video
            'I': 'red',
            'P': 'green',
            'B': 'blue'
        }

        global_peak_bitrate = 0.0
        global_mean_bitrate = 0.0

        # render charts in order of expected decreasing size
        for frame_type in ['I', 'P', 'B', 'A']:

            # skip frame type if missing
            if frame_type not in bitrate_data:
                continue

            # convert list of tuples to numpy 2d array
            frame_list = bitrate_data[frame_type]
            frame_array = numpy.array(frame_list)

            # update global peak bitrate
            peak_bitrate = frame_array.max(0)[1]
            if peak_bitrate > global_peak_bitrate:
                global_peak_bitrate = peak_bitrate

            # update global mean bitrate (using piecewise mean)
            mean_bitrate = frame_array.mean(0)[1]
            global_mean_bitrate += mean_bitrate * \
                (len(frame_list) / frame_count)

            # plot chart using gnuplot-like impulses
            matplot.vlines(frame_array[:, 0], [0],
                           frame_array[:, 1],
                           color=frame_type_color[frame_type],
                           label="{} Frames".format(frame_type))

        self.progressBarProcessor.setValue(90)
        # calculate peak line position (left 15%, above line)
        peak_text_x = matplot.xlim()[1] * 0.15
        peak_text_y = global_peak_bitrate + \
            ((matplot.ylim()[1] - matplot.ylim()[0]) * 0.015)
        peak_text = "peak ({:.0f})".format(global_peak_bitrate)

        # draw peak as think black line w/ text
        matplot.axhline(global_peak_bitrate, linewidth=2, color='black')
        matplot.text(peak_text_x,
                     peak_text_y,
                     peak_text,
                     horizontalalignment='center',
                     fontweight='bold',
                     color='black')

        # calculate mean line position (right 85%, above line)
        mean_text_x = matplot.xlim()[1] * 0.85
        mean_text_y = global_mean_bitrate + \
            ((matplot.ylim()[1] - matplot.ylim()[0]) * 0.015)
        mean_text = "mean ({:.0f})".format(global_mean_bitrate)

        # draw mean as think black line w/ text
        matplot.axhline(global_mean_bitrate, linewidth=2, color='black')
        matplot.text(mean_text_x,
                     mean_text_y,
                     mean_text,
                     horizontalalignment='center',
                     fontweight='bold',
                     color='black')

        matplot.legend()
        if output != "":
            matplot.savefig(output)
        else:
            matplot.show()

        self.progressBarProcessor.setValue(100)

    def CreateBitratePlot(self):
        ''' Create video Plot Bitrate Thread '''
        if not self.KillAllProcessors():
            return
        try:
            self.VPBitratePlot = CreatePlotsBitrate()
            self.VPTBitratePlot = QThread()

            self.VPBitratePlot.moveToThread(self.VPTBitratePlot)

            self.VPBitratePlot.finished.connect(self.QThreadFinished)

            self.VPBitratePlot.return_fig.connect(self.ShowPlot)

            self.VPBitratePlot.error.connect(self.QThreadError)

            self.VPBitratePlot.progress.connect(
                self.progressBarProcessor.setValue)

            self.VPTBitratePlot.start(QThread.LowPriority)

            sender = self.sender().objectName()

            if sender == "actionAudio":
                QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot',
                                         Qt.QueuedConnection,
                                         Q_ARG(str, self.fileName),
                                         Q_ARG(str, None), Q_ARG(str, 'audio'))

            elif sender == "actionVideo":
                QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot',
                                         Qt.QueuedConnection,
                                         Q_ARG(str, self.fileName),
                                         Q_ARG(str, None), Q_ARG(str, 'video'))

            elif sender == "actionSave_Audio":
                selfilter = "Portable Network Graphics (*.png)"
                fileaudio, _ = QFileDialog.getSaveFileName(
                    self, "Save Audio Bitrate Plot", "",
                    "EPS Encapsulated Postscript (*.eps);;"
                    "PGF code for LaTex (*.pgf);;"
                    "Portable document format(*pdf);;"
                    "Portable Network Graphics (*.png);;"
                    "Postscript (*.ps);;"
                    "Raw RGBA bitmap (*.raw*.rgba);;"
                    "Scalable vector graphics (*.svg*.svgz)", selfilter)
                if fileaudio == "":
                    return

                QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot',
                                         Qt.QueuedConnection,
                                         Q_ARG(str, self.fileName),
                                         Q_ARG(str, fileaudio),
                                         Q_ARG(str, 'audio'))

            elif sender == "actionSave_Video":
                selfilter = "Portable Network Graphics (*.png)"
                filevideo, _ = QFileDialog.getSaveFileName(
                    self, "Save Video Bitrate Plot", "",
                    "EPS Encapsulated Postscript (*.eps);;"
                    "PGF code for LaTex (*.pgf);;"
                    "Portable document format(*pdf);;"
                    "Portable Network Graphics (*.png);;"
                    "Postscript (*.ps);;"
                    "Raw RGBA bitmap (*.raw*.rgba);;"
                    "Scalable vector graphics (*.svg*.svgz)", selfilter)
                if filevideo == "":
                    return

                QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot',
                                         Qt.QueuedConnection,
                                         Q_ARG(str, self.fileName),
                                         Q_ARG(str, filevideo),
                                         Q_ARG(str, 'video'))

        except Exception as e:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Failed creating Plot Bitrate"))

    def ExtractAllFrames(self):
        """ Extract All Video Frames Thread """
        if not self.KillAllProcessors():
            return

        options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
        directory = QFileDialog.getExistingDirectory(
            self,
            QCoreApplication.translate("QgsFmvPlayer", "Save images"),
            '',
            options=options)

        if directory:

            self.VPExtractFrames = ExtractFramesProcessor()
            self.VPTExtractAllFrames = QThread()

            self.VPExtractFrames.moveToThread(self.VPTExtractAllFrames)
            self.VPExtractFrames.finished.connect(self.QThreadFinished)
            self.VPExtractFrames.error.connect(self.QThreadError)
            self.VPExtractFrames.progress.connect(
                self.progressBarProcessor.setValue)
            self.VPTExtractAllFrames.start(QThread.LowPriority)

            QMetaObject.invokeMethod(self.VPExtractFrames,
                                     'ExtractFrames', Qt.QueuedConnection,
                                     Q_ARG(str, directory),
                                     Q_ARG(str, self.fileName))
        return

    def ExtractCurrentFrame(self):
        """ Extract Current Frame Thread """
        image = self.videoWidget.GetCurrentFrame()
        out_image, _ = QFileDialog.getSaveFileName(
            self, "Save Current Frame", "",
            "Image File (*.png *.jpg *.bmp *.tiff)")

        if out_image == "":
            return

        if out_image:
            t = threading.Thread(target=self.SaveCapture,
                                 args=(
                                     image,
                                     out_image,
                                 ))
            t.start()
        return

    def SaveCapture(self, image, output):
        ''' Save Current Image '''
        image.save(output)
        QApplication.processEvents()
        return

    def QThreadFinished(self, process, msg, outjson=None):
        ''' Finish Threads '''
        if process == "ExtractFramesProcessor":
            self.VPExtractFrames.deleteLater()
            self.VPTExtractAllFrames.terminate()
            self.VPTExtractAllFrames.deleteLater()
        elif process == "CreatePlotsBitrate":
            self.VPBitratePlot.deleteLater()
            self.VPTBitratePlot.terminate()
            self.VPTBitratePlot.deleteLater()
        elif process == "convert":
            self.VPConverter.deleteLater()
            self.VPTConverter.terminate()
            self.VPTConverter.deleteLater()
        elif process == "probeToJson":
            self.VPProbeToJson.deleteLater()
            self.VPTProbeToJson.terminate()
            self.VPTProbeToJson.deleteLater()
        elif process == "probeShow":
            self.VPProbe.deleteLater()
            self.VPTProbe.terminate()
            self.VPTProbe.deleteLater()
            self.showVideoInfoDialog(outjson)

        QApplication.processEvents()
        self.progressBarProcessor.setValue(0)
        return

    def QThreadError(self, processor, e, exception_string):
        """ Threads Errors"""
        qgsu.showUserAndLogMessage(QCoreApplication.translate(
            "QgsFmvPlayer", processor),
                                   'Failed!\n'.format(exception_string),
                                   level=QGis.Warning)

        self.QThreadFinished(processor, "Closing Processor")

        return

    def OpenQgsFmvMetadata(self):
        """ Open Metadata Dock """
        if self.metadataDlg is None:
            self.metadataDlg = QgsFmvMetadata(parent=self, player=self)
            self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg)
            self.metadataDlg.show()
        else:
            self.metadataDlg.show()
        return

    def KillAllProcessors(self):
        """Kill All Processors"""
        """ Extract all frames Processors """
        try:
            if self.VPTExtractAllFrames.isRunning():
                ret = qgsu.CustomMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "HEY...Active background process!"),
                    QCoreApplication.translate("QgsFmvPlayer",
                                               "Do you really want close?"))
                if ret == QMessageBox.Yes:
                    self.QThreadFinished("ExtractFramesProcessor",
                                         "Closing Extract Frames Processor")
                else:
                    return False
        except:
            None
        """ Bitrates Processors"""
        try:
            if self.VPTBitratePlot.isRunning():
                ret = qgsu.CustomMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "HEY...Active background process!"),
                    QCoreApplication.translate("QgsFmvPlayer",
                                               "Do you really want close?"))
                if ret == QMessageBox.Yes:
                    self.QThreadFinished("CreatePlotsBitrate",
                                         "Closing Plot Bitrate")
                else:
                    return False
        except:
            None
        """ Converter Processors """
        try:
            if self.VPTConverter.isRunning():
                ret = qgsu.CustomMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "HEY...Active background process!"),
                    QCoreApplication.translate("QgsFmvPlayer",
                                               "Do you really want close?"))
                if ret == QMessageBox.Yes:
                    self.QThreadFinished("convert", "Closing convert")
                else:
                    return False
        except:
            None
        """ probeToJson Processors """
        try:
            if self.VPTProbeToJson.isRunning():
                ret = qgsu.CustomMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "HEY...Active background process!"),
                    QCoreApplication.translate("QgsFmvPlayer",
                                               "Do you really want close?"))
                if ret == QMessageBox.Yes:
                    self.QThreadFinished("probeToJson", "Closing Info to Json")
                else:
                    return False
        except:
            None
        """ probeShow Processors """
        try:
            if self.VPTProbe.isRunning():
                ret = qgsu.CustomMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "HEY...Active background process!"),
                    QCoreApplication.translate("QgsFmvPlayer",
                                               "Do you really want close?"))
                if ret == QMessageBox.Yes:
                    self.QThreadFinished("probeShow",
                                         "Closing Show Video Info")
                else:
                    return False
        except:
            None
        return True

    def showVideoInfoDialog(self, outjson):
        """ Show Video Information Dialog """
        view = QTreeView()
        model = QJsonModel()
        view.setModel(model)
        model.loadJsonFromConsole(outjson)

        self.VideoInfoDialog = QDialog(self)
        self.VideoInfoDialog.setWindowTitle("Video Information : " +
                                            self.fileName)
        self.VideoInfoDialog.setWindowIcon(
            QIcon(":/imgFMV/images/video_information.png"))

        self.verticalLayout = QVBoxLayout(self.VideoInfoDialog)
        self.verticalLayout.addWidget(view)
        view.expandAll()
        view.header().setSectionResizeMode(QHeaderView.ResizeToContents)

        self.VideoInfoDialog.setWindowFlags(Qt.Window
                                            | Qt.WindowCloseButtonHint)
        self.VideoInfoDialog.setObjectName("VideoInfoDialog")
        self.VideoInfoDialog.resize(500, 400)
        self.VideoInfoDialog.show()

    def closeEvent(self, evt):
        """ Close Event """
        if self.KillAllProcessors() is False:
            evt.ignore()
            return

        self.player.stop()
        self.parent._PlayerDlg = None
        self.parent.ToggleActiveFromTitle()
        RemoveVideoLayers()
        RemoveGroupByName()

        # Restore Filters State
        self.videoWidget.RestoreFilters()
        # QApplication.processEvents()
        del self.player
Beispiel #26
0
class DBPlayer(QWidget):
    # signal
    signaltxt = pyqtSignal(str)
    signalnum = pyqtSignal(int)

    def __init__(self):
        super(DBPlayer, self).__init__()
        self.setMaximumSize(16777215, 35)
        # Init Player
        self.messtitle = TITL_PROG
        self.namemedia = ''
        self.albumname = ''
        self.currentPlaylist = QMediaPlaylist()
        self.player = QMediaPlayer()
        self.player.stateChanged.connect(self.qmp_stateChanged)
        self.player.positionChanged.connect(self.qmp_positionChanged)
        self.player.volumeChanged.connect(self.qmp_volumeChanged)
        self.player.durationChanged.connect(self.qmp_durationChanged)
        self.player.setVolume(60)
        # Init GUI
        self.setLayout(self.addControls())
        self.infoBox = None

    def addControls(self):
        # buttons
        self.playBtn = QPushButton()
        self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playBtn.setStyleSheet('border: 0px;')
        stopBtn = QPushButton()
        stopBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        stopBtn.setStyleSheet('border: 0px;')
        prevBtn = QPushButton()
        prevBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        prevBtn.setStyleSheet('border: 0px;')
        nextBtn = QPushButton()
        nextBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        nextBtn.setStyleSheet('border: 0px;')
        volumeDescBtn = QPushButton('▼')
        volumeDescBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaVolume))
        volumeDescBtn.setMaximumWidth(30)
        volumeDescBtn.setStyleSheet('border: 0px;')
        volumeIncBtn = QPushButton('▲')
        volumeIncBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaVolume))
        volumeIncBtn.setMaximumWidth(40)
        volumeIncBtn.setStyleSheet('border: 0px;')
        infoBtn = QPushButton()
        infoBtn.setIcon(self.style().standardIcon(
            QStyle.SP_FileDialogContentsView))
        infoBtn.setStyleSheet('border: 0px;')

        # seek slider
        self.seekSlider = QSlider(Qt.Horizontal, self)
        self.seekSlider.setMinimum(0)
        self.seekSlider.setMaximum(100)
        self.seekSlider.setTracking(False)

        # labels position start/end
        self.seekSliderLabel1 = QLabel('0:00')
        self.seekSliderLabel2 = QLabel('0:00')

        # layout
        controlArea = QHBoxLayout()
        controlArea.addWidget(prevBtn)
        controlArea.addWidget(self.playBtn)
        controlArea.addWidget(stopBtn)
        controlArea.addWidget(nextBtn)
        controlArea.addWidget(self.seekSliderLabel1)
        controlArea.addWidget(self.seekSlider)
        controlArea.addWidget(self.seekSliderLabel2)
        controlArea.addWidget(infoBtn)
        controlArea.addWidget(volumeDescBtn)
        controlArea.addWidget(volumeIncBtn)

        # link buttons to media
        self.seekSlider.sliderMoved.connect(self.seekPosition)
        self.playBtn.clicked.connect(self.playHandler)
        stopBtn.clicked.connect(self.stopHandler)
        volumeDescBtn.clicked.connect(self.decreaseVolume)
        volumeIncBtn.clicked.connect(self.increaseVolume)
        prevBtn.clicked.connect(self.prevItemPlaylist)
        nextBtn.clicked.connect(self.nextItemPlaylist)
        infoBtn.clicked.connect(self.displaySongInfo)

        return controlArea

    def playHandler(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
            message = (' [Paused at position %s]' %
                       self.seekSliderLabel1.text())
            self.messtitle = self.namemedia + message
            self.signaltxt.emit(self.messtitle)
        else:
            if self.player.state() == QMediaPlayer.StoppedState:
                if self.player.mediaStatus() == QMediaPlayer.NoMedia:
                    if self.currentPlaylist.mediaCount() != 0:
                        self.player.setPlaylist(self.currentPlaylist)
                elif self.player.mediaStatus() == QMediaPlayer.LoadedMedia:
                    self.player.play()
                elif self.player.mediaStatus() == QMediaPlayer.BufferedMedia:
                    self.player.play()
            elif self.player.state() == QMediaPlayer.PlayingState:
                pass
            elif self.player.state() == QMediaPlayer.PausedState:
                self.player.play()
            if self.player.volume() is not None and self.player.state(
            ) == QMediaPlayer.PlayingState:
                message = ' [Volume %d]' % self.player.volume()
                self.messtitle = self.namemedia + message
                self.signaltxt.emit(self.messtitle)

    def stopHandler(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.stopState = True
            self.player.stop()
        elif self.player.state() == QMediaPlayer.PausedState:
            self.player.stop()
        elif self.player.state() == QMediaPlayer.StoppedState:
            pass
        if self.player.volume() is not None and self.player.state(
        ) == QMediaPlayer.PlayingState:
            self.messtitle = self.namemedia + (' [Stopped]')
            self.signaltxt.emit(self.messtitle)

    def qmp_stateChanged(self):
        if self.player.state() == QMediaPlayer.StoppedState:
            self.player.stop()
        # buttons icon play/pause change
        if self.player.state() == QMediaPlayer.PlayingState:
            self.playBtn.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))
        else:
            self.playBtn.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))

    def qmp_positionChanged(self, position):
        # update position slider
        self.seekSlider.setValue(position)
        # update the text label
        self.seekSliderLabel1.setText(
            '%d:%02d' % (int(position / 60000), int((position / 1000) % 60)))

    def seekPosition(self, position):
        sender = self.sender()
        if isinstance(sender, QSlider):
            if self.player.isSeekable():
                self.player.setPosition(position)

    def qmp_volumeChanged(self):
        if self.player.volume() is not None:
            message = (' [Playing at Volume %d]' % (self.player.volume()))
            if self.namemedia != '':
                self.messtitle = self.namemedia + message
            else:
                self.messtitle = "Initialisation player " + message
            self.signaltxt.emit(self.messtitle)

    def qmp_durationChanged(self, duration):
        self.seekSlider.setRange(0, duration)
        self.seekSliderLabel2.setText(
            '%d:%02d' % (int(duration / 60000), int((duration / 1000) % 60)))
        nummedia = self.currentPlaylist.mediaCount()
        curmedia = self.currentPlaylist.currentIndex()
        #artist = self.player.metaData(QMediaMetaData.Author)
        #tittle = self.player.metaData(QMediaMetaData.Title)
        self.namemedia = path.basename(self.homMed[curmedia])
        self.namemedia = '[%02d/%02d' % (
            curmedia + 1, nummedia) + '] "' + self.namemedia + '"'
        self.buildPlaylist()
        message = (' [Playing at Volume %d]' % (self.player.volume()))
        if self.player.volume() is not None and self.player.state(
        ) == QMediaPlayer.PlayingState:
            self.messtitle = self.namemedia + message
            self.signaltxt.emit(self.messtitle)

    def buildPlaylist(self):
        """Build play list."""
        nummedia = self.currentPlaylist.mediaCount()
        curmedia = self.currentPlaylist.currentIndex() + 1
        compteur = 1
        self.textplaylist = '<b>' + self.albumname + '</b>'
        self.textplaylist += '<table class="tftable" border="0">'
        for namemedia in self.homMed:
            media = path.basename(namemedia)
            media = '[%02d/%02d' % (compteur, nummedia) + '] "' + media + '"'
            if curmedia == compteur:
                self.textplaylist += '<tr><td><b>' + media + '</b></td></tr>'
            else:
                self.textplaylist += '<tr><td>' + media + '</td></tr>'
            compteur += 1
        self.textplaylist = self.textplaylist + '</table>'
        self.playBtn.setToolTip(self.textplaylist)
        self.signalnum.emit(curmedia - 1)

    def increaseVolume(self):
        """Volume +."""
        vol = self.player.volume()
        vol = min(vol + 5, 100)
        self.player.setVolume(vol)

    def decreaseVolume(self):
        """Volume -."""
        vol = self.player.volume()
        vol = max(vol - 5, 0)
        self.player.setVolume(vol)

    def prevItemPlaylist(self):
        self.player.playlist().previous()
        if self.currentPlaylist.currentIndex() == -1:
            self.player.playlist().previous()

    def nextItemPlaylist(self):
        self.player.playlist().next()
        if self.currentPlaylist.currentIndex() == -1:
            self.player.playlist().next()

    def addMediaslist(self, listmedias, position, albumname):
        if self.currentPlaylist.mediaCount() > 0:
            self.currentPlaylist.removeMedia(0,
                                             self.currentPlaylist.mediaCount())
            self.player.stop()
            self.stopHandler()
        self.currentPlaylist.removeMedia(0, self.currentPlaylist.mediaCount())
        self.albumname = albumname
        if listmedias:
            self.homMed = listmedias
            for media in self.homMed:
                self.currentPlaylist.addMedia(
                    QMediaContent(QUrl.fromLocalFile(media)))
            self.currentPlaylist.setCurrentIndex(position)
            self.playHandler()

    def displaySongInfo(self):
        # extract datas
        metaDataKeyList = self.player.availableMetaData()
        fullText = '<table class="tftable" border="0">'
        for key in metaDataKeyList:
            value = str(self.player.metaData(key)).replace("'", "").replace(
                "[", "").replace("]", "")
            if key == 'Duration':
                value = '%d:%02d' % (int(
                    int(value) / 60000), int((int(value) / 1000) % 60))
            fullText = fullText + '<tr><td>' + key + '</td><td>' + value + '</td></tr>'
        fullText = fullText + '</table>'
        # re-init
        if self.infoBox is not None:
            self.infoBox.destroy()
        # infos box
        self.infoBox = QMessageBox(self)
        self.infoBox.setWindowTitle('Detailed Song Information')
        self.infoBox.setTextFormat(Qt.RichText)
        self.infoBox.addButton('OK', QMessageBox.AcceptRole)
        self.infoBox.setText(fullText)
        self.infoBox.show()
Beispiel #27
0
class Player(QWidget):
    audio_path = "audio"
    lyrics_path = "lyrics"
    timings_path = os.path.join("lyrics", "timing")
    settings_path = "settings.json"

    fullScreenChanged = pyqtSignal(bool)

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

        self.setWindowTitle("SongScreen")

        self.setFocusPolicy(Qt.StrongFocus)

        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        # self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)

        # self.videoWidget = VideoWidget()
        # self.player.setVideoOutput(self.videoWidget)

        self.slider = MediaProgressWidget()  # QSlider(Qt.Horizontal)
        self.markers = []

        self.songtext_widget = SongTextWidget()
        self.songtext_widget.show()

        # self.playlistModel = PlaylistModel()
        # self.playlistModel.setPlaylist(self.playlist)
        #
        # self.playlistView = QListView()
        # self.playlistView.setModel(self.playlistModel)
        # self.playlistView.setCurrentIndex(
        #     self.playlistModel.index(self.playlist.currentIndex(), 0))
        #
        # self.playlistView.activated.connect(self.jump)

        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)

        # openButton = QPushButton("Open", clicked=self.open)

        controls = PlayerControlsWidget()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())
        # controls.setMuted(controls.isMuted())

        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.stop_clicked)
        # controls.stop.connect(self.videoWidget.update)
        # controls.next.connect(self.playlist.next)
        # controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        # controls.changeMuting.connect(self.player.setMuted)
        # controls.changeRate.connect(self.player.setPlaybackRate)

        self.player.stateChanged.connect(controls.setState)
        self.player.stateChanged.connect(self.setState)
        self.player.volumeChanged.connect(controls.setVolume)
        # self.player.mutedChanged.connect(controls.setMuted)

        # self.fullScreenButton = QPushButton("FullScreen")
        # self.fullScreenButton.setCheckable(True)
        #
        # self.colorButton = QPushButton("Color Options...")
        # self.colorButton.setEnabled(False)
        # self.colorButton.clicked.connect(self.showColorDialog)

        displayLayout = QHBoxLayout()
        # displayLayout.addWidget(self.videoWidget, 2)
        # displayLayout.addWidget(self.songtext_widget)
        # displayLayout.addWidget(self.playlistView)

        self.song_select_widget = SongSelectWidget()
        self.song_select_widget.song_selected.connect(self.load_song)

        self.screen_select_widget = ScreenSelectWidget()
        self.screen_select_widget.screen_selected.connect(self.display_lyrics_on_screen)
        self.screen_select_widget.active_screen = QApplication.desktop().screenNumber(self.songtext_widget)

        self.settings_button = QPushButton()
        self.settings_button.setText(self.tr("Settings..."))
        self.settings_button.clicked.connect(self.show_settings)

        sidebarLayout = QVBoxLayout()
        sidebarLayout.setContentsMargins(10, 1, 0, 1);

        sidebarLayout.addWidget(self.settings_button)
        sidebarLayout.addStretch(1);
        sidebarLayout.addWidget(self.screen_select_widget)

        displayLayout.addWidget(self.song_select_widget)
        displayLayout.addLayout(sidebarLayout)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        # controlLayout.addWidget(openButton)
        # controlLayout.addStretch(1)
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        controlLayout.addWidget(self.labelDuration)
        # controlLayout.addWidget(self.fullScreenButton)
        # controlLayout.addWidget(self.colorButton)

        layout = QVBoxLayout()
        layout.addLayout(displayLayout)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        # hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)

        self.setLayout(layout)

        if not self.player.isAvailable():
            QMessageBox.warning(self, "Service not available",
                                "The QMediaPlayer object does not have a valid service.\n"
                                "Please check the media service plugins are installed.")

            controls.setEnabled(False)
            self.playlistView.setEnabled(False)
            # openButton.setEnabled(False)
            self.colorButton.setEnabled(False)
            self.fullScreenButton.setEnabled(False)

        self.metaDataChanged()

        self._loading_audio = False
        self._finished_song = False
        self._lyrics_fading = False

        self._song_number = -1

        self.settings = {
            'font_size': 40,
            'line_increment': 2,
            'lyrics_language': '',
        }
        self._load_settings()

        self.settings_widget = SettingsWidget(self.settings, self.lyrics_path)
        self.settings_widget.font_size_changed.connect(self.songtext_widget.set_font_size)
        self.settings_widget.line_increment_changed.connect(self.songtext_widget.set_line_increment)
        self.settings_widget.language_changed.connect(self._language_changed)

        self.song_select_widget.reset(self.available_song_numbers)

    @property
    def lyrics_language_path(self):
        path = QStandardPaths.locate(QStandardPaths.AppDataLocation, self.lyrics_path, QStandardPaths.LocateDirectory)
        return os.path.join(path, self.settings['lyrics_language'])

    @property
    def available_song_numbers(self):
        audios = set(
            [int(os.path.splitext(filename)[0]) for filename in os.listdir(self.audio_path) if filename[0] != '.'])
        try:
            lyrics = set(
                [int(os.path.splitext(filename)[0])
                 for filename in os.listdir(self.lyrics_language_path)
                 if filename[0] != '.']
            )
        except (ValueError, FileNotFoundError):
            lyrics = set()

        return sorted(list(audios.intersection(lyrics)))

    def show_settings(self):
        self.settings_widget.hide()
        self.settings_widget.show()

    def display_lyrics_on_screen(self, screen_number):
        desktop = QApplication.desktop()

        if screen_number >= desktop.screenCount():
            screen_number = desktop.screenNumber(self)

        rect = desktop.availableGeometry(screen_number)

        for _ in range(3):
            if screen_number != desktop.screenNumber(self):
                self.songtext_widget.setWindowFlags(Qt.FramelessWindowHint)
                self.songtext_widget.hide()
                self.songtext_widget.move(rect.x(), rect.y())
                self.songtext_widget.resize(rect.width(), rect.height())
                self.songtext_widget.showFullScreen()
            else:
                self.songtext_widget.setWindowFlags(Qt.WindowTitleHint)
                self.songtext_widget.hide()
                self.songtext_widget.move(rect.x(), rect.y())
                self.songtext_widget.resize(self.songtext_widget.minimumSize())
                self.songtext_widget.show()

        self.screen_select_widget.active_screen = screen_number

        self.activateWindow()

    def load_song(self, song_number):
        if self._song_number == song_number:
            self.seek(0)
        else:
            if self._song_number > 0:
                self._save_timings()

            self._song_number = song_number
            self.slider.dirty = False
            self._load_audio()
            self._load_lyrics()

            # self.player.play()

    def _load_audio(self):
        filename = os.path.join(self.audio_path, "{:03}.mp3".format(self._song_number))
        self.playlist.clear()
        fileInfo = QFileInfo(filename)
        if fileInfo.exists():
            url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
            if fileInfo.suffix().lower() == 'm3u':
                self.playlist.load(url)
            else:
                self.playlist.addMedia(QMediaContent(url))
                self._loading_audio = True

            self.player.play()

    def _load_lyrics(self):
        with open(os.path.join(self.lyrics_language_path, "{}.json".format(self._song_number)), 'r') as f:
            song_markers = json.load(f)

            self.markers = []

            for m in song_markers['markers']:
                marker = MediaMarker(self.slider, m['name'])
                marker.text = m['text']
                marker.progress = 0.0
                self.markers.append(marker)

            self.songtext_widget.title = "{}  {}".format(self._song_number, song_markers['title'])
            self.songtext_widget.markers = self.markers
            self.songtext_widget.fade_in()

        try:
            with open(os.path.join(self.timings_path, "{}.json".format(self._song_number)), 'r') as f:
                timings = json.load(f)
                for m, t in zip(self.markers, timings):
                    m.progress = t
        except FileNotFoundError:
            pass

        self.slider.markers = self.markers

    def _language_changed(self, _):
        available_song_numbers = self.available_song_numbers
        self.song_select_widget.reset(available_song_numbers)
        if self._song_number in available_song_numbers:
            self._load_lyrics()

    # def open(self):
    #     fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files")
    #     self.addToPlaylist(fileNames)
    #
    # def addToPlaylist(self, fileNames):
    #     for name in fileNames:
    #         fileInfo = QFileInfo(name)
    #         if fileInfo.exists():
    #             url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
    #             if fileInfo.suffix().lower() == 'm3u':
    #                 self.playlist.load(url)
    #             else:
    #                 self.playlist.addMedia(QMediaContent(url))
    #         else:
    #             url = QUrl(name)
    #             if url.isValid():
    #                 self.playlist.addMedia(QMediaContent(url))

    def durationChanged(self, duration):
        duration /= 1000

        self.duration = duration
        self.slider.setMaximum(duration)

        if self._loading_audio:
            self._loading_audio = False

            line_total = 0
            for marker in self.markers:
                line_total += marker.linecount - 1

            silence_ratio = 5.0 / self.duration
            offset = 1.8 / line_total

            linecount = 0
            for marker in self.markers:
                if marker.progress == 0.0:
                    marker.progress = offset + (1 - offset) * (1 - silence_ratio) * linecount / line_total
                linecount += marker.linecount - 1

            self.player.pause()

    @property
    def _should_fade_out(self):
        return self.player.position() / 1000 >= self.duration - 5

    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)

        self.updateDurationInfo(progress)

        if self.duration > 0:
            # if self.player.state() == QMediaPlayer.PlayingState:
            self.songtext_widget.progress = progress / self.duration

            if self._should_fade_out:
                self._fade_out_lyrics()

    def _fade_out_lyrics(self):
        if not self._lyrics_fading:
            self._lyrics_fading = True
            self.songtext_widget.fade_out()

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo("%s - %s" % (
                self.player.metaData(QMediaMetaData.AlbumArtist),
                self.player.metaData(QMediaMetaData.Title)))

    def previousClicked(self):
        # Go to the previous track if we are within the first 5 seconds of
        # playback.  Otherwise, seek to the beginning.
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)

    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()

    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)

    def setState(self, status):

        if status == QMediaPlayer.StoppedState:
            self._finished_song = True

        elif status == QMediaPlayer.PlayingState:
            if self._finished_song or (self._lyrics_fading and not self._should_fade_out):
                self._finished_song = False
                self._lyrics_fading = False
                self.songtext_widget.fade_in()

    def stop_clicked(self):
        self.player.stop()
        self._fade_out_lyrics()

    def statusChanged(self, status):
        self.handleCursor(status)

        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo("Loading...")
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo("Media Stalled")
        elif status == QMediaPlayer.EndOfMedia:
            QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo("")

    def handleCursor(self, status):
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def bufferingProgress(self, progress):
        self.setStatusInfo("Buffering %d%" % progress)

    def videoAvailableChanged(self, available):
        if available:
            self.fullScreenButton.clicked.connect(
                self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.connect(
                self.fullScreenButton.setChecked)

            if self.fullScreenButton.isChecked():
                self.videoWidget.setFullScreen(True)
        else:
            self.fullScreenButton.clicked.disconnect(
                self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.disconnect(
                self.fullScreenButton.setChecked)

            self.videoWidget.setFullScreen(False)

        self.colorButton.setEnabled(available)

    def setTrackInfo(self, info):
        self.trackInfo = info

        # if self.statusInfo != "":
        #     self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        # else:
        #     self.setWindowTitle(self.trackInfo)

    def setStatusInfo(self, info):
        self.statusInfo = info

        # if self.statusInfo != "":
        #     self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        # else:
        #     self.setWindowTitle(self.trackInfo)

    def displayErrorMessage(self):
        self.setStatusInfo(self.player.errorString())

    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60,
                                currentInfo % 60, (currentInfo * 1000) % 1000)
            totalTime = QTime((duration / 3600) % 60, (duration / 60) % 60,
                              duration % 60, (duration * 1000) % 1000);

            format = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            tStr = currentTime.toString(format) + " / " + totalTime.toString(format)
        else:
            tStr = ""

        self.labelDuration.setText(tStr)

    def showColorDialog(self):
        if self.colorDialog is None:
            brightnessSlider = QSlider(Qt.Horizontal)
            brightnessSlider.setRange(-100, 100)
            brightnessSlider.setValue(self.videoWidget.brightness())
            brightnessSlider.sliderMoved.connect(
                self.videoWidget.setBrightness)
            self.videoWidget.brightnessChanged.connect(
                brightnessSlider.setValue)

            contrastSlider = QSlider(Qt.Horizontal)
            contrastSlider.setRange(-100, 100)
            contrastSlider.setValue(self.videoWidget.contrast())
            contrastSlider.sliderMoved.connect(self.videoWidget.setContrast)
            self.videoWidget.contrastChanged.connect(contrastSlider.setValue)

            hueSlider = QSlider(Qt.Horizontal)
            hueSlider.setRange(-100, 100)
            hueSlider.setValue(self.videoWidget.hue())
            hueSlider.sliderMoved.connect(self.videoWidget.setHue)
            self.videoWidget.hueChanged.connect(hueSlider.setValue)

            saturationSlider = QSlider(Qt.Horizontal)
            saturationSlider.setRange(-100, 100)
            saturationSlider.setValue(self.videoWidget.saturation())
            saturationSlider.sliderMoved.connect(
                self.videoWidget.setSaturation)
            self.videoWidget.saturationChanged.connect(
                saturationSlider.setValue)

            layout = QFormLayout()
            layout.addRow("Brightness", brightnessSlider)
            layout.addRow("Contrast", contrastSlider)
            layout.addRow("Hue", hueSlider)
            layout.addRow("Saturation", saturationSlider)

            button = QPushButton("Close")
            layout.addRow(button)

            self.colorDialog = QDialog(self)
            self.colorDialog.setWindowTitle("Color Options")
            self.colorDialog.setLayout(layout)

            button.clicked.connect(self.colorDialog.close)

        self.colorDialog.show()

    def closeEvent(self, close_event):
        self._save_timings()
        self._save_settings()
        self.songtext_widget.close()
        self.settings_widget.close()

    def keyPressEvent(self, key_event):
        if key_event.key() == Qt.Key_Space:
            key_event.accept()
            if self.player.state() == QMediaPlayer.PlayingState:
                self.player.pause()
            elif self.player.state() in [QMediaPlayer.PausedState, QMediaPlayer.StoppedState]:
                self.player.play()
        elif key_event.key() == Qt.Key_M:
            key_event.accept()
            self.slider.set_closest_marker_to_current_progress()

    def _save_timings(self):
        if self.slider.dirty:
            with open(os.path.join(self.timings_path, "{}.json".format(self._song_number)), 'w') as f:
                json.dump([marker.progress for marker in self.markers], f, indent=2)

    def _save_settings(self):
        # TODO : refactor and use QSettings directly

        # with open(self.settings_path, 'w') as f:
        self.settings.update({
            'lyrics_screen': QApplication.desktop().screenNumber(self.songtext_widget),
            'control_window_position': self.pos(),
        })

        # json.dump(self.settings, f, indent=2)

        settings = QSettings("Maccesch", "SongScreen")

        for key, value in self.settings.items():
            settings.setValue(key, value)

    def _load_settings(self):
        # try:
        #     with open(self.settings_path, 'r') as f:
        #         settings = json.load(f)
        settings = QSettings("Maccesch", "SongScreen")

        if settings.contains('lyrics_screen'):
            self.display_lyrics_on_screen(settings.value('lyrics_screen'))

        if settings.contains('control_window_position'):
            self.move(settings.value('control_window_position'))

        for key in settings.allKeys():
            self.settings[key] = settings.value(key)

        # self.settings.update(settings)

        self.songtext_widget.set_font_size(self.settings['font_size'])
        self.songtext_widget.set_line_increment(self.settings['line_increment'])

        # except (FileNotFoundError, ValueError):
        #     pass

        if not os.path.exists(self.lyrics_language_path) or not self.settings['lyrics_language']:
            languages = list(
                filter(lambda p: os.path.isdir(os.path.join(self.lyrics_path, p)) and p != "timings",
                       os.listdir(self.lyrics_path))
            )
            self.settings['lyrics_language'] = languages[0] if languages else ""
Beispiel #28
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # iniciando conexio con google
        self.translate_client = translate.Client()

        self.my_state = _STATE_PLAY

        # Controles principales para organizar la ventana.
        self.widget = QWidget(self)
        self.layout = QVBoxLayout()
        self.bottom_layout = QHBoxLayout()

        # status layout
        self.statusLayout = StatusLayout()

        # Sutitles layout
        self.subLayout = SubtitleLayout()

        # time stuff
        self.time_layout = QHBoxLayout()
        self.label_time = QLabel()
        self.label_mi = QLabel()
        self.label_end = QLabel()

        # inicializar subtitulos
        self.list_frames = sub.frames(MY_PATH + SUB_PATH)
        self.text_frame = self.list_frames.pop()

        # Control de reproducción de video de Qt.
        self.video_widget = QVideoWidget(self)
        self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.media_player.setMedia(
            QMediaContent(QUrl.fromLocalFile(MY_PATH + VIDEO_PATH)))
        self.media_player.setVideoOutput(self.video_widget)

        # Botones de reproducción y pausa.

        # Deslizadores para el volumen y transición del video.
        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.volume_slider.sliderMoved.connect(self.media_player.setVolume)

        # actualizar la posicion

        self.seek_slider.sliderMoved.connect(self.change_media_player)
        self.media_player.positionChanged.connect(self.change_seek_bar)

        self.media_player.durationChanged.connect(self.change_duration)

        # Acomodar controles en la pantalla.
        self.layout.addLayout(self.statusLayout)
        self.layout.addWidget(self.video_widget)
        self.layout.addLayout(self.bottom_layout)
        self.layout.addLayout(self.time_layout)
        self.layout.addWidget(self.seek_slider)

        # andir layout
        self.layout.addLayout(self.subLayout)
        #conections
        self.subLayout.prev_button.clicked.connect(self.click_prev)
        self.subLayout.next_button.clicked.connect(self.click_next)

        self.bottom_layout.addWidget(self.volume_slider)

        # time stuff
        self.time_layout.addWidget(self.label_time)
        self.time_layout.addWidget(self.label_mi)
        self.time_layout.addWidget(self.label_end)

        #self.set_sub_text(self.labels_sub2, self.frame.txt)
        self.subLayout.set_sub_text(
            self.subLayout.labelSub1,
            self.text_frame.f1.get_txt_conver_asteric())
        self.subLayout.set_sub_text(
            self.subLayout.labelSub2,
            self.text_frame.f2.get_txt_conver_asteric())

        # Conectar los eventos con sus correspondientes funciones.
        self.statusLayout.play_button.clicked.connect(self.play_clicked)
        self.statusLayout.stop_button.clicked.connect(self.stop_clicked)
        self.media_player.stateChanged.connect(self.state_changed)

        # conectando labels
        self.connect_labels()

        # Personalizar la ventana.
        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)

        # setear Timer
        self.timer = QTimer()
        self.timer.timeout.connect(self.timer_change_status)
        self.timer.start(_TIMER_TICK)

        # Reproducir el video.
        self.media_player.setNotifyInterval(_NOTIFY_INTERVAL)
        self.media_player.play()

    def connect_labels(self):
        for element in self.subLayout.labelSub1:
            element.clicked.connect(self.label_cliked)

        for element in self.subLayout.labelSub2:
            element.clicked.connect(self.label_cliked)

    def miles_minutes(self, value):
        s, ms = divmod(value, 1000)
        m, s = divmod(s, 60)
        h, m = divmod(m, 60)
        return h, m, s, ms

# modificar el valor del seek

    def change_media_player(self, value):
        self.media_player.setPosition(value)

    def timer_change_status(self):
        #print ("timer")
        if self.my_state == _STATE_PAUSE:
            self.media_player.pause()
            self.timer.stop()

    def change_seek_bar(self, value):
        if self.my_state == _STATE_PLAY:
            # detiene la ejecusion del video si el frame ya acabo
            if value > self.text_frame.end:
                self.my_state = _STATE_PAUSE

        #if (value > self.text_frame.end and self.my_state == _STATE_PLAY):
        #    print ("pasa")
        #    self.media_player.pause()
        #    self.my_state = _STATE_PAUSE

        #self.text_frame = self.list_frames.pop()
        #if self.text_frame != None:
        #    self.sub_text_lab1       = self.text_frame.txt1
        #    self.sub_text_lab2       = self.text_frame.txt2
        #else :
        #    self.sub_text_lab1       = ""
        #    self.sub_text_lab2       = ""
        #    self.text_frame.end = 0

        #print ("casa")

            (h, m, s, ms) = self.miles_minutes(value)
            time = "%d:%d:%d.%d" % (h, m, s, ms)
            self.label_time.setText(time)
            self.label_mi.setText(str(value))
            self.label_end.setText(str(self.text_frame.end))

            #self.label_sub1.setText(self.frame.txt)
            #self.set_sub_text(self.labels_sub1, self.sub_text_lab1)
            #self.set_sub_text(self.labels_sub2, self.sub_text_lab2)
            self.seek_slider.setValue(value)

        return True

# se modifico la duracion

    def change_duration(self, value):
        self.seek_slider.setRange(0, value)


# senales relacionadas a eventos

    def play_clicked(self):
        """
        Comenzar o resumir la reproducción.
        """
        if (self.media_player.state()
                in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)):
            self.media_player.play()
        else:
            self.media_player.pause()

    def click_prev(self):
        if self.my_state == _STATE_PLAY:
            self.media_player.pause()
        self.timer.stop()
        self.media_player.setPosition(self.text_frame.start)
        self.timer.start(_TIMER_TICK)
        self.media_player.play()
        self.my_state = _STATE_PLAY

    def click_next(self):
        if self.my_state == _STATE_PLAY:
            self.media_player.pause()
        self.timer.stop()
        self.text_frame = self.list_frames.pop()
        self.media_player.setPosition(self.text_frame.start)
        self.timer.start(_TIMER_TICK)
        self.media_player.play()
        self.my_state = _STATE_PLAY

        self.subLayout.set_sub_text(
            self.subLayout.labelSub1,
            self.text_frame.f1.get_txt_conver_asteric())
        self.subLayout.set_sub_text(
            self.subLayout.labelSub2,
            self.text_frame.f2.get_txt_conver_asteric())

    def stop_clicked(self):
        """
        Detener la reproducción.
        """
        self.media_player.stop()

    def state_changed(self, newstate):
        """
        Actualizar el texto de los botones de reproducción y pausa.
        """
        states = {
            QMediaPlayer.PausedState: "Resumir",
            QMediaPlayer.PlayingState: "Pausa",
            QMediaPlayer.StoppedState: "Reproducir"
        }
        self.statusLayout.play_button.setText(states[newstate])
        self.statusLayout.stop_button.setEnabled(
            newstate != QMediaPlayer.StoppedState)

    def eventFilter(self, obj, event):
        """
        Establecer o remover pantalla completa al obtener
        el evento MouseButtonDblClick.
        """
        if event.type() == QEvent.MouseButtonDblClick:
            obj.setFullScreen(not obj.isFullScreen())
        return False

    def keyPressEvent(self, event):
        if type(event) == QtGui.QKeyEvent:
            if event.key() == Qt.Key_Space:
                print("tecla space")
            else:
                #print (event.key())
                if self.text_frame.new_key(event.key()) == True:
                    #print("cambiar al siguiente Frame")
                    self.text_frame = self.list_frames.pop()
                    if self.my_state == _STATE_PLAY:
                        self.media_player.pause()
                    self.media_player.setPosition(self.text_frame.start)
                    self.timer.start(_TIMER_TICK)
                    self.media_player.play()
                    self.my_state = _STATE_PLAY

                self.subLayout.set_sub_text(
                    self.subLayout.labelSub1,
                    self.text_frame.f1.get_txt_conver_asteric())
                self.subLayout.set_sub_text(
                    self.subLayout.labelSub2,
                    self.text_frame.f2.get_txt_conver_asteric())

            event.accept()
        else:
            event.ignore()

    def label_cliked(self, word):
        #print(word)
        result = self.translate_client.translate(
            word, target_language=_TARGET_LANGUAGE)
        txt = "%s = %s" % (result['input'], result['translatedText'])
        print(txt)
Beispiel #29
0
class VideoPlayer(QWidget):

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

        self.setAttribute( Qt.WA_NoSystemBackground, True )

        self.colorDialog = None

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVolume(80)
        self.videoWidget = QVideoWidget(self)
        
        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setEnabled(False)
        self.lbl.setFixedWidth(60)
        self.lbl.setUpdatesEnabled(True)
        self.lbl.setStyleSheet(stylesheet(self))
        
        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setEnabled(False)
        self.elbl.setFixedWidth(60)
        self.elbl.setUpdatesEnabled(True)
        self.elbl.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet (stylesheet(self)) 
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handleLabel)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)
        
        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(5, 0, 5, 0)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.lbl)
        controlLayout.addWidget(self.positionSlider)
        controlLayout.addWidget(self.elbl)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.videoWidget)
        layout.addLayout(controlLayout)

        self.setLayout(layout)
        
        self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \
				"LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \
				"SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes\nf = Fullscreen On/Off"

        self.widescreen = True

        self.setAcceptDrops(True)
        self.setWindowTitle("QT5 Player")
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
        self.setGeometry(700, 400, 400, 290)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu);
        self.customContextMenuRequested[QtCore.QPoint].connect(self.contextMenuRequested)
        self.hideSlider()
        self.show()
        self.playFromURL()
		
		#### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence("u"), self)
        self.shortcut.activated.connect(self.playFromURL)
        self.shortcut = QShortcut(QKeySequence("o"), self)
        self.shortcut.activated.connect(self.openFile)
        self.shortcut = QShortcut(QKeySequence(" "), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence("f"), self)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handleInfo)
        self.shortcut = QShortcut(QKeySequence("s"), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volumeUp)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volumeDown)	
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier +  Qt.Key_Right) , self)
        self.shortcut.activated.connect(self.forwardSlider10)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier +  Qt.Key_Left) , self)
        self.shortcut.activated.connect(self.backSlider10)
        self.shortcut = QShortcut(QKeySequence("c") , self)
        self.shortcut.activated.connect(self.showColorDialog)

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

    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie",
                QDir.homePath(), "Videos (*.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v)")

        if fileName != '':
            self.loadFilm(fileName)
            print("File loaded")

    def playFromURL(self):
        self.mediaPlayer.pause()
        clip = QApplication.clipboard()
        myurl = clip.text()
        if myurl.startswith("http"):
            self.mediaPlayer.setMedia(QMediaContent(QUrl(myurl)))
        elif myurl.startswith("/"):
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(myurl)))
        else:
            return
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()
        self.hideSlider()
        print(myurl)

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()
    
    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)
        mtime = QTime(0,0,0,0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

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

    def handleError(self):
        self.playButton.setEnabled(False)
        print("Error: " + self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        print("Goodbye ...")
        app.quit()
	
    def contextMenuRequested(self,point):
        menu = QtWidgets.QMenu()
        actionFile = menu.addAction("open File (o)")
        actionclipboard = menu.addSeparator() 
        actionURL = menu.addAction("URL / File from Clipboard (u)")
        actionclipboard = menu.addSeparator() 
        actionToggle = menu.addAction("show / hide Slider (s)") 
        actionFull = menu.addAction("Fullscreen (f)")
        action169 = menu.addAction("16 : 9")
        action43 = menu.addAction("4 : 3")
        actionColors = menu.addAction("Color Options (c)")
        actionSep = menu.addSeparator()
        actionInfo = menu.addAction("Info (i)")
        actionsep2 = menu.addSeparator() 
        actionQuit = menu.addAction("Exit (q)") 

        actionFile.triggered.connect(self.openFile)
        actionQuit.triggered.connect(self.handleQuit)
        actionFull.triggered.connect(self.handleFullscreen)
        actionInfo.triggered.connect(self.handleInfo)
        actionToggle.triggered.connect(self.toggleSlider)
        actionURL.triggered.connect(self.playFromURL)
        action169.triggered.connect(self.screen169)
        action43.triggered.connect(self.screen43)
        actionColors.triggered.connect(self.showColorDialog)
        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self,event):
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mscale = event.angleDelta().y() / 5
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.778) 
        else:
            self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.33)            

    def screen169(self):
        self.widescreen = True
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.778
        self.setGeometry(mleft, mtop, mwidth, mwidth / mratio)

    def screen43(self):
        self.widescreen = False
        mwidth = self.frameGeometry().width()
        mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.33
        self.setGeometry(mleft, mtop, mwidth, mwidth / mratio)

    def handleFullscreen(self):
        if self.windowState() & QtCore.Qt.WindowFullScreen:
            self.showNormal()
            print("no Fullscreen")
        else:
            self.showFullScreen()
            print("Fullscreen entered")

    def handleInfo(self):
            msg = QMessageBox()
            msg.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen)
            msg.setGeometry(self.frameGeometry().left() + 30, self.frameGeometry().top() + 30, 300, 400)
            msg.setIcon(QMessageBox.Information)
            msg.setText("QT5 Player")
            msg.setInformativeText(self.myinfo)
            msg.setStandardButtons(QMessageBox.Close)
            msg.exec()
            
    def toggleSlider(self):	
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()
	
    def hideSlider(self):
            self.playButton.hide()
            self.lbl.hide()
            self.positionSlider.hide()
            self.elbl.hide()
            mwidth = self.frameGeometry().width()
            mheight = self.frameGeometry().height()
            mleft = self.frameGeometry().left()
            mtop = self.frameGeometry().top()
            if self.widescreen == True:
                self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778) 
            else:
                self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33)
	
    def showSlider(self):
            self.playButton.show()
            self.lbl.show()
            self.positionSlider.show()
            self.elbl.show()
            mwidth = self.frameGeometry().width()
            mheight = self.frameGeometry().height()
            mleft = self.frameGeometry().left()
            mtop = self.frameGeometry().top()
            self.positionSlider.setFocus()
            if self.widescreen == True:
                self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55) 
            else:
                self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33)
	
    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000*60)

    def forwardSlider10(self):
            self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000*60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000*60)

    def backSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000*60)
		
    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))
	
    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))
		
    def mouseMoveEvent(self, event):   
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() \
						- QPoint(self.frameGeometry().width() / 2, \
						self.frameGeometry().height() / 2))
            event.accept() 
		
    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasFormat('text/plain'):
            event.accept()
        else:
            event.ignore()

########### drag files #############
    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            f = str(event.mimeData().urls()[0].toLocalFile())
            self.loadFilm(f)
        elif event.mimeData().hasText():
            f = str(event.mimeData().text())
            self.mediaPlayer.setMedia(QMediaContent(QUrl(f)))
            self.mediaPlayer.play()
	
    def loadFilm(self, f):
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
            print(str(self.mediaPlayer.media().canonicalResource().resolution()))
	  
    def openFileAtStart(self, filelist):
            matching = [s for s in filelist if ".myformat" in s]
            if len(matching) > 0:
                self.loadFilm(matching)

##################### update Label ##################################
    def handleLabel(self):
            self.lbl.clear()
            mtime = QTime(0,0,0,0)
            self.time = mtime.addMSecs(self.mediaPlayer.position())
            self.lbl.setText(self.time.toString())
###################################################################

    def showColorDialog(self):
        if self.colorDialog is None:
            brightnessSlider = QSlider(Qt.Horizontal)
            brightnessSlider.setRange(-100, 100)
            brightnessSlider.setValue(self.videoWidget.brightness())
            brightnessSlider.sliderMoved.connect(
                    self.videoWidget.setBrightness)
            self.videoWidget.brightnessChanged.connect(
                    brightnessSlider.setValue)

            contrastSlider = QSlider(Qt.Horizontal)
            contrastSlider.setRange(-100, 100)
            contrastSlider.setValue(self.videoWidget.contrast())
            contrastSlider.sliderMoved.connect(self.videoWidget.setContrast)
            self.videoWidget.contrastChanged.connect(contrastSlider.setValue)

            hueSlider = QSlider(Qt.Horizontal)
            hueSlider.setRange(-100, 100)
            hueSlider.setValue(self.videoWidget.hue())
            hueSlider.sliderMoved.connect(self.videoWidget.setHue)
            self.videoWidget.hueChanged.connect(hueSlider.setValue)

            saturationSlider = QSlider(Qt.Horizontal)
            saturationSlider.setRange(-100, 100)
            saturationSlider.setValue(self.videoWidget.saturation())
            saturationSlider.sliderMoved.connect(
                    self.videoWidget.setSaturation)
            self.videoWidget.saturationChanged.connect(
                    saturationSlider.setValue)

            layout = QFormLayout()
            layout.addRow("Brightness", brightnessSlider)
            layout.addRow("Contrast", contrastSlider)
            layout.addRow("Hue", hueSlider)
            layout.addRow("Saturation", saturationSlider)

            button = QPushButton("Close Window")
            button.setFixedWidth(120)
            layout.addRow(button)

            self.colorDialog = QDialog(self)
            self.colorDialog.setWindowTitle("Color Options")
            self.colorDialog.setLayout(layout)

            button.clicked.connect(self.colorDialog.close)
            self.colorDialog.setGeometry(300, 250, 300, 100)

        self.colorDialog.show()
Beispiel #30
0
class MainWindowMusicPlayer(QMainWindow):
    stopState: bool

    def __init__(self):
        super().__init__()
        self.currentPlaylist = QMediaPlaylist()
        self.player = QMediaPlayer()
        self.userAction = -1  # 0 - stopped, 1 - playing 2 - paused
        self.player.mediaStatusChanged.connect(self.qmp_media_status_changed)
        self.player.stateChanged.connect(self.qmp_state_changed)
        self.player.positionChanged.connect(self.qmp_position_changed)
        self.player.volumeChanged.connect(self.qmp_volume_changed)
        self.player.setVolume(60)
        # Status bar
        self.statusBar().showMessage('No Media'
                                     ' :: %d' % self.player.volume())
        self.home_screen()

    def home_screen(self):
        self.setWindowTitle('Music Player')

        self.create_menubar()

        self.create_toolbar()

        controlBar = self.add_controls()

        # need to add both information screen
        # and control bar to the central widget.
        centralWidget = QWidget()
        centralWidget.setLayout(controlBar)
        self.setCentralWidget(centralWidget)

        # Set size of the MainWindow
        self.resize(200, 100)

        self.show()

    def create_menubar(self):
        menubar = self.menuBar()
        file_menu = menubar.addMenu('File')
        file_menu.addAction(self.file_open())
        file_menu.addAction(self.song_info())
        file_menu.addAction(self.folder_open())
        file_menu.addAction(self.exit_action())

    def create_toolbar(self):
        pass

    def add_controls(self):
        controlArea = QVBoxLayout()
        seekSliderLayout = QHBoxLayout()
        controls = QHBoxLayout()
        playlistCtrlLayout = QHBoxLayout()

        # creating buttons
        playBtn = QPushButton('Play')  # play button
        pauseBtn = QPushButton('Pause')  # pause button
        stopBtn = QPushButton('Stop')  # stop button
        volumeDescBtn = QPushButton('V (-)')  # Decrease Volume
        volumeIncBtn = QPushButton('V (+)')  # Increase Volume

        # creating playlist controls
        prevBtn = QPushButton('Prev Song')
        nextBtn = QPushButton('Next Song')

        # creating seek slider
        seekSlider = QSlider()
        seekSlider.setMinimum(0)
        seekSlider.setMaximum(100)
        seekSlider.setOrientation(Qt.Horizontal)
        seekSlider.setTracking(False)
        seekSlider.sliderMoved.connect(self.seek_position)
        # seekSlider.valueChanged.connect(self.seekPosition)

        seekSliderLabel1 = QLabel('0.00')
        seekSliderLabel2 = QLabel('0.00')
        seekSliderLayout.addWidget(seekSliderLabel1)
        seekSliderLayout.addWidget(seekSlider)
        seekSliderLayout.addWidget(seekSliderLabel2)

        # Add handler for each button. Not using the default slots.
        playBtn.clicked.connect(self.play_handler)
        pauseBtn.clicked.connect(self.pause_handler)
        stopBtn.clicked.connect(self.stop_handler)
        volumeDescBtn.clicked.connect(self.decrease_volume)
        volumeIncBtn.clicked.connect(self.increase_volume)

        # Adding to the horizontal layout
        controls.addWidget(volumeDescBtn)
        controls.addWidget(playBtn)
        controls.addWidget(pauseBtn)
        controls.addWidget(stopBtn)
        controls.addWidget(volumeIncBtn)

        # playlist control button handlers
        prevBtn.clicked.connect(self.prev_item_playlist)
        nextBtn.clicked.connect(self.next_item_playlist)
        playlistCtrlLayout.addWidget(prevBtn)
        playlistCtrlLayout.addWidget(nextBtn)

        # Adding to the vertical layout
        controlArea.addLayout(seekSliderLayout)
        controlArea.addLayout(controls)
        controlArea.addLayout(playlistCtrlLayout)
        return controlArea

    # Music playback function
    def play_handler(self):
        self.userAction = 1
        self.statusBar().showMessage('Playing at Volume %d' %
                                     self.player.volume())
        if self.player.state() == QMediaPlayer.StoppedState:
            if self.player.mediaStatus() == QMediaPlayer.NoMedia:
                print(self.currentPlaylist.mediaCount())
                if self.currentPlaylist.mediaCount() == 0:
                    self.open_file()
                if self.currentPlaylist.mediaCount() != 0:
                    self.player.setPlaylist(self.currentPlaylist)
            elif self.player.mediaStatus() ==\
                    QMediaPlayer.LoadedMedia:
                self.player.play()
            elif self.player.mediaStatus() ==\
                    QMediaPlayer.BufferedMedia:
                self.player.play()
        elif self.player.state() == QMediaPlayer.PlayingState:
            pass
        elif self.player.state() == QMediaPlayer.PausedState:
            self.player.play()

    # Music pause function
    def pause_handler(self):
        self.userAction = 2
        self.statusBar().showMessage(
            'Paused %s at position'
            ' %s at Volume %d' %
            (self.player.metaData(QMediaMetaData.Title),
             self.centralWidget().layout().itemAt(0).layout().itemAt(
                 0).widget().text(), self.player.volume()))
        self.player.pause()

    # Music stop function
    def stop_handler(self):
        self.userAction = 0
        self.statusBar().showMessage('Stopped at Volume %d' %
                                     (self.player.volume()))
        if self.player.state() == QMediaPlayer.PlayingState:
            self.stopState = True
            self.player.stop()
        elif self.player.state() == QMediaPlayer.PausedState:
            self.player.stop()
        elif self.player.state() == QMediaPlayer.StoppedState:
            pass

    # Music status change function
    def qmp_media_status_changed(self):
        if self.player.mediaStatus() == QMediaPlayer.LoadedMedia \
                and self.userAction == 1:
            durationT = self.player.duration()
            self.centralWidget().layout().itemAt(0).layout() \
                .itemAt(1).widget().setRange(0, durationT)
            self.centralWidget().layout().itemAt(0).layout() \
                .itemAt(2).widget().setText(
                '%d:%02d' % (int(durationT / 60000),
                             int((durationT / 1000) % 60)))
            self.player.play()

    # Music playing change function
    def qmp_state_changed(self):
        if self.player.state() == QMediaPlayer.StoppedState:
            self.player.stop()

    # Music time change function
    def qmp_position_changed(self, position, senderType=False):
        sliderLayout = self.centralWidget().layout().itemAt(0)\
            .layout()
        if not senderType:
            sliderLayout.itemAt(1).widget().setValue(position)
        # update the text label
        sliderLayout.itemAt(0).widget()\
            .setText('%d:%02d' %
                     (int(position / 60000),
                      int((position / 1000) % 60)))

    def seek_position(self, position):
        sender = self.sender()
        if isinstance(sender, QSlider):
            if self.player.isSeekable():
                self.player.setPosition(position)

    # Music volume change function
    def qmp_volume_changed(self):
        msg = self.statusBar().currentMessage()
        msg = msg[:-2] + str(self.player.volume())
        self.statusBar().showMessage(msg)

    # Music volume + change function
    def increase_volume(self):
        vol = self.player.volume()
        vol = min(vol + 5, 100)
        self.player.setVolume(vol)

    # Music volume - change function
    def decrease_volume(self):
        vol = self.player.volume()
        vol = max(vol - 5, 0)
        self.player.setVolume(vol)

    # File open function
    def file_open(self):
        fileAc = QAction(QIcon('icons\\open.png'), 'Open File', self)
        fileAc.setShortcut('Ctrl+O')
        fileAc.setStatusTip('Open File')
        fileAc.triggered.connect(self.open_file)
        return fileAc

    # File opening function
    def open_file(self):
        file_Chosen = QFileDialog.getOpenFileUrl(self, 'Open Music File',
                                                 expanduser('~'),
                                                 'Audio (*.mp3 *.ogg *.wav)',
                                                 '*.mp3 *.ogg *.wav')
        if file_Chosen is not None:
            self.currentPlaylist.addMedia(QMediaContent(file_Chosen[0]))

    # Folder open function
    def folder_open(self):
        folderAc = QAction(QIcon('icons\\open_fld.png'), 'Open Folder', self)
        folderAc.setShortcut('Ctrl+D')
        folderAc.setStatusTip('Open Folder '
                              '(Will add all the files in'
                              ' the folder)')
        folderAc.triggered.connect(self.add_files)
        return folderAc

    # Folder opening function
    def add_files(self):
        folder_Chosen = QFileDialog\
            .getExistingDirectory(self,
                                  'Open Music Folder',
                                  expanduser('~'))
        if folder_Chosen is not None:
            it = QDirIterator(folder_Chosen)
            it.next()
            while it.hasNext():
                if it.fileInfo().isDir() == False\
                        and it.filePath() != '.':
                    fInfo = it.fileInfo()
                    print(it.filePath(), fInfo.suffix())
                    if fInfo.suffix() in ('mp3', 'ogg', 'wav'):
                        print('added file ', fInfo.fileName())
                        self.currentPlaylist. \
                            addMedia(QMediaContent(
                            QUrl.fromLocalFile(it.filePath())))
                it.next()

    # Song information function
    def song_info(self):
        infoAc = QAction(QIcon('icons\\info.png'), 'Info', self)
        infoAc.setShortcut('Ctrl+I')
        infoAc.setStatusTip('Displays Current Song Information')
        infoAc.triggered.connect(self.display_song_info)
        return infoAc

    # Show song information
    def display_song_info(self):
        metaDataKeyList = self.player.availableMetaData()
        fullText = '<table class="tftable" border="0">'
        for key in metaDataKeyList:
            value = self.player.metaData(key)
            fullText = \
                fullText + '<tr><td>' + key + '</td><td>' + \
                str(value) + '</td></tr>'
        fullText = fullText + '</table>'
        infoBox = QMessageBox(self)
        infoBox.setWindowTitle('Detailed Song Information')
        infoBox.setTextFormat(Qt.RichText)
        infoBox.setText(fullText)
        infoBox.addButton('OK', QMessageBox.AcceptRole)
        infoBox.show()

    # Switch to previous song
    def prev_item_playlist(self):
        self.player.playlist().previous()

    # Switch to next song
    def next_item_playlist(self):
        self.player.playlist().next()

    # exit function
    def exit_action(self):
        exitAc = QAction(QIcon('icons\\exit.png'), '&Exit', self)
        exitAc.setShortcut('Ctrl+Q')
        exitAc.setStatusTip('Exit App')
        exitAc.triggered.connect(self.close)
        return exitAc

    # exiting function
    @staticmethod
    def exit():
        sys.exit(app.exec_())
Beispiel #31
0
class Window(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        # load config
        self.data = yaml_loader()

        # load ui
        self.setupUi(self)

        # load icons
        self.setWindowTitle("Sputofy")
        self.setWindowIcon(QIcon(os.path.join(RES_PATH, "logo.svg")))

        loopIcon = QIcon()
        loopIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "loopIconOFF.svg")))
        self.loopBtn.setIcon(loopIcon)
        prevIcon = QIcon()
        prevIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "backwardIcon.svg")))
        self.prevBtn.setIcon(prevIcon)
        playIcon = QIcon()
        playIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "playIcon.svg")))
        self.playBtn.setIcon(playIcon)
        nextIcon = QIcon()
        nextIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "forwardIcon.svg")))
        self.nextBtn.setIcon(nextIcon)
        randomIcon = QIcon()
        randomIcon.addPixmap(
            QPixmap(os.path.join(RES_PATH, "randomIconOFF.svg")))
        self.randomBtn.setIcon(randomIcon)
        volumeIcon = QIcon()
        volumeIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "volumeIcon.svg")))
        self.volumeBtn.setIcon(volumeIcon)

        # window's settings
        self.xCor = self.data['last_position']['xPos']
        self.yCor = self.data['last_position']['yPos']
        self.widthSize = self.data['last_window_size']['width']
        self.heightSize = self.data['last_window_size']['height']

        self.setGeometry(self.xCor, self.yCor, self.widthSize, self.heightSize)

        # load YouTubeToMP3
        self.YouTubeToMP3 = YouTubeToMP3Window()

        # open YouTubeToMP3 using button
        self.actionYT_MP3.triggered.connect(self.YouTubeToMP3.show_window)

        # info action
        self.actionInfo.triggered.connect(self.info_handle)

        #===========================  mediaplayer  ==============================

        # create media player object
        self.mediaPlayer = QMediaPlayer(None)

        # open button
        self.actionOpen_Song.triggered.connect(self.open_song)
        self.actionOpen_Folder.triggered.connect(self.open_folder)

        # play button
        self.playBtn.setEnabled(False)
        self.playBtn.clicked.connect(
            self.play_video
        )  # when btn is pressed: if it is playing it pause, if it is paused it plays
        # QShortcut(QKeySequence("Space"), self).activated.connect(self.play_video)metodo da ricordare in caso di problemi #TODO

        # duration slider
        self.durationSlider.setEnabled(False)
        self.durationSliderMaxValue = 0
        self.durationSlider.valueChanged.connect(
            self.mediaPlayer.setPosition
        )  # set mediaPlayer position using the value took from the slider
        QShortcut('Right', self, lambda: self.durationSlider.setValue(
            self.durationSlider.value() + 10000))  # 1s = 1000ms
        QShortcut('Left', self, lambda: self.durationSlider.setValue(
            self.durationSlider.value() - 10000))  # 1s = 1000ms
        QShortcut('Shift+Right', self, lambda: self.durationSlider.setValue(
            self.durationSliderMaxValue - 1000))  # jump to the end-1s of song
        QShortcut('Shift+Left', self,
                  lambda: self.durationSlider.setValue(0))  # restart song

        # volumeSlider
        self.volumeSlider.setProperty("value", 100)
        self.volumeSlider.setRange(0, 100)
        self.volumeSlider.setValue(
            self.data['volume']
            if self.data['volume'] != 0 else self.data['volume'] + 1
        )  # set slider value | if saved volume is equal to 0 load with volume = 1 else load the saved volume
        self.mediaPlayer.setVolume(
            self.data['volume']
            if self.data['volume'] != 0 else self.data['volume'] + 1
        )  # set mediaPlayer volume | if saved volume is equal to 0 load with volume = 1 else load the saved volume
        self.volumeLabel.setText(
            f"{self.data['volume']}%"
            if self.data['volume'] != 0 else f"{self.data['volume']+1}%"
        )  # set volume label text | if saved volume is equal to 0 load with volume = 1 else load the saved volume
        self.volumeSlider.valueChanged.connect(
            self.mediaPlayer.setVolume
        )  # set mediaPlayer volume using the value took from the slider

        QShortcut('Up', self, lambda: self.volumeSlider.setValue(
            self.volumeSlider.value() + 1))  # volume + 1
        QShortcut('Down', self, lambda: self.volumeSlider.setValue(
            self.volumeSlider.value() - 1))  # volume - 1

        QShortcut(
            'Shift+Up', self,
            lambda: self.volumeSlider.setValue(100))  # set maximum volume
        QShortcut(
            'Shift+Down', self,
            lambda: self.volumeSlider.setValue(0))  # set minimun volume(mute)

        # volumeBtn
        self.volumeBtn.clicked.connect(
            self.volume_toggle)  # mute/unmute volume pressing btn
        self.isMuted = False  # starting with a non-muted volume
        self.previousVolume = self.data[
            'volume']  # loading last registered volume

        # media player signals
        self.mediaPlayer.durationChanged.connect(
            self.duration_changed)  # set range of duration slider
        self.mediaPlayer.positionChanged.connect(
            self.position_changed)  # duration slider progress
        self.mediaPlayer.stateChanged.connect(
            self.player_state)  # see when it's playing or in pause
        self.mediaPlayer.volumeChanged.connect(
            self.volume_icon)  # change volumebtn icon

        #===========================  playlist  ==============================

        # create the playlist
        self.playlist = QMediaPlaylist()
        self.playlist.setPlaybackMode(2)
        self.mediaPlayer.setPlaylist(self.playlist)

        # clear the playlist
        self.playlistIsEmpty = True

        # playlistList model
        self.model = PlaylistModel(self.playlist)
        self.playlistView.setModel(self.model)
        self.playlist.currentIndexChanged.connect(
            self.playlist_position_changed)
        selection_model = self.playlistView.selectionModel()
        selection_model.selectionChanged.connect(
            self.playlist_selection_changed)

        #===========================  playlist function  ==============================

        self.mediaList = []  # array of loaded songs
        self.currentPlaylist = ""  # current loaded playlist name
        self.isCustomPlaylist = False

        # add song name on title
        self.playlist.currentMediaChanged.connect(self.set_title)

        # playlist buttons
        self.nextBtn.clicked.connect(self.next_song)  # seek track forward

        self.prevBtn.clicked.connect(self.prev_song)  # seek track backward

        self.mediaPlayer.mediaStatusChanged.connect(
            self.auto_next_track
        )  # once song is ended seek track forward and play it

        self.actionLoopIt.triggered.connect(
            self.loop_song)  # (1) loop the same song

        self.actionShuffle.triggered.connect(
            self.shuffle_playlist)  # change song's order

        self.loopBtn.clicked.connect(self.loop)  # (3) loop the playlist

        self.randomBtn.clicked.connect(
            self.random)  # (4) play random song without end

        # create new playlist
        self.actionCreatePlaylist.triggered.connect(self.custom_playlist)

        # delete current playlist
        self.actionDeletePlaylist.triggered.connect(self.delete_playlist)

        # remove all songs
        self.actionClearQueue.triggered.connect(self.clear_queue)

        # load playlist
        self.actionDict = {}  # dictionary of action Objects

        for action in self.data['playlistList']:
            self.actionDict[action] = self.menuPlaylist.addAction(
                action, partial(self.load_playlist, action))

        if len(self.data['playlistList']) == 0:
            self.menuPlaylist.menuAction().setVisible(False)

#================== Songs opening ==================#

    def open_folder(self):
        foldername = QFileDialog.getExistingDirectory(self, "Open folder",
                                                      "c:\\")

        if foldername:
            self.playlist.clear()
            self.mediaList.clear()

            for song in os.listdir(foldername):
                media = f"{foldername}/{song}"
                self.playlist.addMedia(QMediaContent(QUrl(media)))
                self.mediaList.append(media)

            self.playlist.setCurrentIndex(0)

            self.playBtn.setEnabled(True)
            self.durationSlider.setEnabled(True)

            self.playlistIsEmpty = False
            self.isCustomPlaylist = False

            self.model.layoutChanged.emit()  # load songs in list view
            self.set_title()

            self.mediaPlayer.pause()  # adjust play/pause icon

    def open_song(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open Song", "c:\\")

        if filename:
            if self.playlistIsEmpty == False:
                self.playlist.clear()
                self.mediaList.clear()
                self.playlistIsEmpty = True

            self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(filename)))
            self.mediaList.append(filename)

            self.playBtn.setEnabled(True)
            self.durationSlider.setEnabled(True)

            self.isCustomPlaylist = False

            self.model.layoutChanged.emit()  # load song in list view
            self.set_title()

            # adjust play/pause icon
            if self.playlist.mediaCount(
            ) == 1:  # if there is 1 song and you add another
                self.playlist.setCurrentIndex(0)
                self.mediaPlayer.pause()

    def load_playlist(self, playlistName):
        self.playlist.clear()
        self.mediaList.clear()

        # reload config
        self.data = yaml_loader()

        for song in self.data['playlistList'][playlistName]:
            self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(song)))
            self.mediaList.append(song)

        self.playlist.setCurrentIndex(0)

        self.playBtn.setEnabled(True)
        self.durationSlider.setEnabled(True)

        self.playlistIsEmpty = False
        self.isCustomPlaylist = True

        self.model.layoutChanged.emit()  # load songs in list view

        self.currentPlaylist = playlistName  # name of current loaded playlist
        self.set_title()

        self.statusbar.showMessage(f'Playlist "{playlistName}" loaded', 4000)
        self.menuPlaylist.menuAction().setVisible(True)

        # adjust play/pause icon
        self.mediaPlayer.pause()

    def set_title(self):
        if self.playlist.mediaCount() == 0:
            self.setWindowTitle("Sputofy")

        else:
            if self.isCustomPlaylist == False:
                self.setWindowTitle(
                    f"Sputofy - {os.path.splitext(self.playlist.currentMedia().canonicalUrl().fileName())[0]} - {self.playlist.currentIndex()+1}/{self.playlist.mediaCount()}"
                )
            else:
                self.setWindowTitle(
                    f"Sputofy - {self.currentPlaylist} - {os.path.splitext(self.playlist.currentMedia().canonicalUrl().fileName())[0]} - {self.playlist.currentIndex()+1}/{self.playlist.mediaCount()}"
                )

#=======================================================#

#================== Player Functions ==================#

    def play_video(self):
        if self.durationSlider.isEnabled():  # if slider was enabled
            if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
                self.mediaPlayer.pause()
            else:
                self.mediaPlayer.play()

    def duration_changed(self, duration):
        self.durationSlider.setRange(0, duration)

        if duration > 0:
            self.totalTime_Label.setText(time_format(round(
                duration / 1000)))  # duration is in ms
        self.durationSliderMaxValue = duration

    def position_changed(self, position):
        if position >= 0:
            self.elapsedTime_Label.setText(time_format(
                (position / 1000)))  # position is in ms

        # Disable the events to prevent updating triggering a setPosition event (can cause stuttering).
        self.durationSlider.blockSignals(True)
        self.durationSlider.setValue(position)
        self.durationSlider.blockSignals(False)

#=======================================================#

#================== Playlist Settings ==================#
#TODO Work in progress

    def playlist_array(self):
        index = self.playlist.mediaCount()
        mediaList = []
        for i in range(index):
            # songPath = (self.playlist.media(path).canonicalUrl().path())#.split("/",1)[1]
            # mediaList.append(songPath)
            # print(self.playlist.media(i).canonicalUrl().path())
            mediaList.append(self.playlist.media(i).canonicalUrl().fileName())
        return mediaList

    def custom_playlist(self):
        if not self.playlist.mediaCount() == 0:
            name, is_notEmpty = QInputDialog.getText(self, "playlist",
                                                     "save playlist as:")

            if name:

                if name in self.data['playlistList']:
                    self.statusbar.showMessage(
                        "playlist not created (name is already used)", 4000)
                else:
                    self.data['playlistList'][name] = self.mediaList
                    yaml_dump(self.data)

                    # add new action Object to dictionary
                    self.actionDict[name] = self.menuPlaylist.addAction(
                        name, partial(self.load_playlist, name))

                    self.load_playlist(
                        name)  # instantly loading the new playlist
            else:
                self.statusbar.showMessage(
                    "playlist not created (you should give a name to your baby :/)",
                    4000)
        else:
            self.statusbar.showMessage("there are no songs to playlist", 4000)

    def delete_playlist(self):
        if self.isCustomPlaylist:

            if len(self.data['playlistList']) == 1:
                self.menuPlaylist.menuAction().setVisible(False)

            self.data['playlistList'].pop(
                self.currentPlaylist)  # remove playlist from dictionary

            self.menuPlaylist.removeAction(self.actionDict[
                self.currentPlaylist])  # remove relative action
            self.actionDict.pop(
                self.currentPlaylist)  # remove relative action Object

            self.playlist.clear()
            self.model.layoutChanged.emit()
            self.setWindowTitle("Sputofy")

            yaml_dump(self.data)

            self.statusbar.showMessage(
                'succesfully deleted "' + self.currentPlaylist + '" playlist',
                4000)
        else:
            self.statusbar.showMessage("cannot delete a non custom playlist",
                                       4000)

    def clear_queue(self):
        self.playlist.clear()
        self.mediaList.clear()
        self.playBtn.setEnabled(False)
        self.model.layoutChanged.emit()

    def playlist_position_changed(self, i):
        if i > -1:
            ix = self.model.index(i)
            self.playlistView.setCurrentIndex(ix)

    def playlist_selection_changed(self, ix):
        # We receive a QItemSelection from selectionChanged.
        i = ix.indexes()[0].row()
        self.posizione = i
        self.playlist.setCurrentIndex(i)
        self.mediaPlayer.play()

#=======================================================#

#================== Playback Settings ==================#

    def next_song(self):
        if self.playlist.currentIndex() == self.playlist.mediaCount() - 1:
            self.playlist.setCurrentIndex(0)
        else:
            self.playlist.next()

    def prev_song(self):
        if self.playlist.currentIndex() == 0:
            self.playlist.setCurrentIndex(self.playlist.mediaCount() - 1)
        else:
            self.playlist.previous()

    def loop_song(self):
        if self.playlist.playbackMode() != 1:

            self.playlist.setPlaybackMode(1)

            self.actionLoopIt.setText("Loop it: ON")
            self.loopBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "loopIconOFF.svg")))
            self.randomBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "randomIconOFF.svg")))
        else:
            self.playlist.setPlaybackMode(2)
            self.actionLoopIt.setText("Loop it: OFF")

    def shuffle_playlist(self):
        if self.playlist.mediaCount():
            self.playlist.shuffle()
            self.model.layoutChanged.emit()
        else:
            self.statusbar.showMessage("there are no songs to shuffle", 4000)

    def loop(self):
        if self.playlist.playbackMode() != 3:
            self.playlist.setPlaybackMode(3)

            self.loopBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "loopIconON.svg")))
            self.randomBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "randomIconOFF.svg")))
            self.actionLoopIt.setText("Loop it: OFF")

        else:
            self.playlist.setPlaybackMode(2)
            self.loopBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "loopIconOFF.svg")))

    def random(self):
        if self.playlist.playbackMode() != 4:
            self.playlist.setPlaybackMode(4)

            self.randomBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "randomIconON.svg")))
            self.loopBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "loopIconOFF.svg")))
            self.actionLoopIt.setText("Loop it: OFF")

        else:
            self.playlist.setPlaybackMode(2)
            self.randomBtn.setIcon(
                QIcon(os.path.join(RES_PATH, "randomIconOFF.svg")))

    def auto_next_track(self):

        if self.mediaPlayer.mediaStatus() == QMediaPlayer.EndOfMedia:
            if self.playlist.playbackMode() == 2:
                # index starts from 0       mediacount starts from 1
                if self.playlist.currentIndex(
                ) != self.playlist.mediaCount() - 1:
                    self.playlist.next()
                    self.mediaPlayer.play()
                else:  # if ended song was the last one set the index to the first one and pause
                    self.playlist.setCurrentIndex(0)
                    self.mediaPlayer.pause()

            # loop playlist
            elif self.playlist.playbackMode() == 3:
                self.playlist.next()
                self.mediaPlayer.play()

            # random song
            elif self.playlist.playbackMode() == 4:
                while self.playlist.previousIndex(
                ) == self.playlist.currentIndex(
                ):  # preventing repeating the same song
                    self.playlist.setCurrentIndex(
                        random.randint(0,
                                       self.playlist.mediaCount() - 1))

#=======================================================#

#================== Volume Settings ==================#

    def volume_icon(self, volume):

        self.volumeLabel.setText(f"{volume}%")

        if volume:
            volumeIcon = QIcon()
            volumeIcon.addPixmap(
                QPixmap(os.path.join(RES_PATH, "volumeIcon.svg")),
                QIcon.Normal, QIcon.Off)
            self.volumeBtn.setIcon(volumeIcon)
            self.previousVolume = self.volumeSlider.value()
            self.isMuted = False
        else:
            volumeMutedIcon = QIcon()
            volumeMutedIcon.addPixmap(
                QPixmap(os.path.join(RES_PATH, "volumeMutedIcon.svg")),
                QIcon.Normal, QIcon.Off)
            self.volumeBtn.setIcon(volumeMutedIcon)
            self.isMuted = True

    def volume_toggle(self):
        if self.isMuted == False:
            self.volumeSlider.setValue(0)
            self.isMuted = True

        elif self.isMuted == True:
            if self.previousVolume == 0:
                self.volumeSlider.setValue(10)
            else:
                self.volumeSlider.setValue(self.previousVolume)
            self.isMuted = False


#=======================================================#

    def mousePressEvent(self, event):
        ''' remove the border around the buttons created by using tab key '''

        focused_widget = QtWidgets.QApplication.focusWidget()
        try:
            focused_widget.clearFocus()
        except:
            pass
        QMainWindow.mousePressEvent(self, event)

    def player_state(self, event):
        ''' event handler that adjust the play/pause icon '''

        if event == QMediaPlayer.PlayingState:
            pauseIcon = QIcon()
            pauseIcon.addPixmap(
                QPixmap(os.path.join(RES_PATH, "pauseIcon.svg")), QIcon.Normal,
                QIcon.Off)
            self.playBtn.setIcon(pauseIcon)
        elif event == QMediaPlayer.PausedState:
            playIcon = QIcon()
            playIcon.addPixmap(QPixmap(os.path.join(RES_PATH, "playIcon.svg")),
                               QIcon.Normal, QIcon.Off)
            self.playBtn.setIcon(playIcon)

    def closeEvent(self, event):
        ''' event handler that take window information and save it in config before the window close '''

        # retrieve position
        xAxis = self.geometry().x()
        yAxis = self.geometry().y()

        self.data['last_position']['xPos'] = xAxis
        self.data['last_position']['yPos'] = yAxis

        # retrieve size
        width = self.width()
        height = self.height()

        self.data['last_window_size']['width'] = width
        self.data['last_window_size']['height'] = height

        # retrieve volume
        self.data['volume'] = self.mediaPlayer.volume()

        # retrieve user
        user = os.getlogin()
        self.data[
            'default_folder'] = f"C:\\Users\\{user}\\Desktop\\sputofy_songs"

        yaml_dump(self.data)

    def info_handle(self):

        info = "Sputofy\n1.0.0\n©2020 "+\
        "Sputofy is a free audio player based on the converted youtube songs made by a_str0\n\n"+\
        "Sputofy is written using python 3.x and PyQt5 modules"

        msg = QMessageBox.about(self, "About", info)
class AudioPlayerPage(QWidget):
    about_play_audio = pyqtSignal(str)

    def __init__(self):
        super().__init__()

        self.audio_list_widget = QListWidget()
        self.audio_list_widget.installEventFilter(self)
        self.audio_list_widget.itemDoubleClicked.connect(self.play)

        # TODO: playlist объединить с audio_list_widget (см примеры работы с QMediaPlayer)
        self.playlist = QMediaPlaylist()
        self.playlist.currentIndexChanged.connect(
            lambda row: self.audio_list_widget.setCurrentRow(row))

        # TODO: обрабатывать сигналы плеера: http://doc.qt.io/qt-5/qmediaplayer.html#signals
        self.player = QMediaPlayer()
        self.player.setPlaylist(self.playlist)
        self.player.currentMediaChanged.connect(
            lambda media: self.about_play_audio.emit(self.audio_list_widget.
                                                     currentItem().text()))

        if not self.player.isAvailable():
            # TODO: перевод
            text = "The QMediaPlayer object does not have a valid service.\n" \
                   "Please check the media service plugins are installed."

            log.warning(text)
            QMessageBox.warning(self, "Service not available", text)

            quit()

        self.controls = PlayerControls(self.player)
        self.controls.set_state(self.player.state())
        self.controls.set_volume(self.player.volume())
        self.controls.set_muted(self.controls.is_muted())

        self.controls.play_signal.connect(self.play)
        self.controls.pause_signal.connect(self.player.pause)
        self.controls.stop_signal.connect(self.player.stop)
        self.controls.next_signal.connect(self.playlist.next)
        self.controls.previous_signal.connect(self.playlist.previous)
        self.controls.change_volume_signal.connect(self.player.setVolume)
        self.controls.change_muting_signal.connect(self.player.setMuted)

        self.progress = QProgressBar()
        self.progress.hide()

        layout = QVBoxLayout()
        layout.addWidget(self.controls)
        layout.addWidget(self.audio_list_widget)
        layout.addWidget(self.progress)

        self.setLayout(layout)

        self.thread = LoadAudioListThread()
        self.thread.about_add_audio.connect(self._add_audio)
        self.thread.about_progress.connect(self.progress.setValue)
        self.thread.about_range_progress.connect(self.progress.setRange)
        self.thread.started.connect(self._start)
        self.thread.finished.connect(self._finished)

    def _add_audio(self, title, url):
        item = QListWidgetItem(title)
        item.setData(Qt.UserRole, url)
        self.audio_list_widget.addItem(item)
        self.playlist.addMedia(QMediaContent(QUrl(url)))

        # При добавлении первой аудизаписи, вызываем воспроизведение
        if self.audio_list_widget.count() == 1:
            self.audio_list_widget.setCurrentRow(0)
            self.playlist.setCurrentIndex(0)
            self.play()

    def _start(self):
        self.audio_list_widget.clear()
        self.playlist.clear()

        self.progress.show()

    def _finished(self):
        self.progress.hide()

    def fill(self, vk):
        self.thread.vk = vk

        # Если поток запущен, останавливаем его, иначе -- запускаем
        if self.thread.isRunning():
            self.thread.exit()
        else:
            self.thread.start()

    def play(self):
        if self.playlist.currentIndex() != self.audio_list_widget.currentRow():
            self.playlist.setCurrentIndex(self.audio_list_widget.currentRow())

        self.player.play()

    def eventFilter(self, obj, event):
        # Воспроизведение видео при клике на кнопки Enter/Return в плейлисте
        if obj == self.audio_list_widget and event.type(
        ) == QKeyEvent.KeyPress:
            if self.audio_list_widget.hasFocus() and event.key(
            ) == Qt.Key_Return or event.key() == Qt.Key_Enter:
                item = self.audio_list_widget.currentItem()
                if item is not None:
                    self.play()

        return super().eventFilter(obj, event)
Beispiel #33
0
class VideoPlayer(QWidget):
    def __init__(self, aPath, parent=None):
        super(VideoPlayer, self).__init__(parent)

        #self.setAttribute(Qt.WA_NoSystemBackground, True)

        self.colorDialog = None

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVolume(80)
        self.videoWidget = QVideoWidget(self)

        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setEnabled(False)
        self.lbl.setFixedWidth(60)
        self.lbl.setUpdatesEnabled(True)
        #self.lbl.setStyleSheet(stylesheet(self))

        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setEnabled(False)
        self.elbl.setFixedWidth(60)
        self.elbl.setUpdatesEnabled(True)
        #self.elbl.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        #self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        ### pointA button
        self.apointButton = QPushButton()
        self.apointButton.setEnabled(False)
        self.apointButton.setFixedWidth(32)
        #self.apointButton.setStyleSheet("background-color: black")
        self.apointButton.setIcon(self.style().standardIcon(
            QStyle.SP_MediaSeekForward))
        self.apointButton.clicked.connect(self.setPointA)

        ### pointB button
        self.bpointButton = QPushButton()
        self.bpointButton.setEnabled(False)
        self.bpointButton.setFixedWidth(32)
        #self.bpointButton.setStyleSheet("background-color: black")
        self.bpointButton.setIcon(self.style().standardIcon(
            QStyle.SP_MediaSeekBackward))
        self.bpointButton.clicked.connect(self.setPointB)

        ### cut button
        self.cutButton = QPushButton()
        self.cutButton.setEnabled(False)
        self.cutButton.setFixedWidth(32)
        self.cutButton.setIcon(self.style().standardIcon(
            QStyle.SP_DriveFDIcon))
        self.cutButton.clicked.connect(self.cut)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet(stylesheet(self))
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handle_label)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        #self.positionSlider.setAttribute(Qt.WA_NoSystemBackground, True)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(5, 0, 5, 0)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.apointButton)
        controlLayout.addWidget(self.bpointButton)
        controlLayout.addWidget(self.cutButton)
        controlLayout.addWidget(self.lbl)
        controlLayout.addWidget(self.positionSlider)
        controlLayout.addWidget(self.elbl)

        layout0 = QVBoxLayout()
        layout0.setContentsMargins(0, 0, 0, 0)
        layout0.addWidget(self.videoWidget)
        layout0.addLayout(controlLayout)

        self.setLayout(layout0)

        self.widescreen = True

        self.setAcceptDrops(True)
        self.setWindowTitle("QT5 Player")
        #self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
        self.setGeometry(300, 200, 400, 290)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested[QtCore.QPoint].connect(
            self.contextMenuRequested)
        #self.hideSlider()
        self.show()
        #self.playFromURL()

        ### shortcuts ###
        self.shortcut = QShortcut(QKeySequence('q'), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence('o'), self)
        self.shortcut.activated.connect(self.openFile)
        self.shortcut = QShortcut(QKeySequence(' '), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence('s'), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence('v'), self)
        self.shortcut.activated.connect(self.setPointA)
        self.shortcut = QShortcut(QKeySequence('b'), self)
        self.shortcut.activated.connect(self.setPointB)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self)
        self.shortcut.activated.connect(self.volumeUp)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self)
        self.shortcut.activated.connect(self.volumeDown)
        self.shortcut = QShortcut(
            QKeySequence(Qt.ShiftModifier + Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider10)
        self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left),
                                  self)
        self.shortcut.activated.connect(self.backSlider10)

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

        self.apoint = 0
        self.bpoint = 0
        self.inputfile = pathlib.Path()
        # self.outputfile = pathlib.Path()

    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(
            self, 'Open Movie',
            QDir.homePath() + '/Desktop',
            'Videos (*.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v)')
        if fileName != '':
            self.load_film(fileName)
            print("File loaded")
            print(fileName)
            self.inputfile = pathlib.Path(fileName)

    def getclipFileName(self):
        clipFileName = QFileDialog.getSaveFileName(
            self, 'Save Clip',
            QDir.homePath() + '/Desktop', 'all files(*.*)')
        return clipFileName

    #def playFromURL(self):

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

    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)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

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

    # cut point A function
    def setPointA(self):
        self.apoint = self.time.toString()
        print('A Point ' + self.apoint)

    # cut point B function
    def setPointB(self):
        self.play()
        self.bpoint = self.time.toString()
        print('B Point ' + self.bpoint)

    # cut
    def cut(self):
        print("Input: ", self.inputfile.resolve())
        length = self.lengthCalculation(self.apoint, self.bpoint)
        output_file = os.path.splitext(str(
            self.inputfile.resolve()))[0] + '__' + re.sub(
                ':', '_', self.apoint) + '__' + re.sub(
                    ':', '_', self.bpoint
                ) + self.inputfile.suffix  # no ':' allowed in a windows path.
        print("Output:", output_file)
        command = "ffmpeg -i " + "\"" + str(
            self.inputfile.resolve()
        ) + "\"" + " -ss " + self.apoint + " -t " + length + " -c:v copy -c:a copy " + "\"" + output_file + "\""
        print("Executing:\n", command, "\n")
        run(command, shell=True)

    # cut length calculation
    def twodigi(self, str0):
        if len(str0) == 1:
            str0 = '0' + str0
        return str0

    def lengthCalculation(self, start, end):
        start_s = int(start[:2]) * 3600 + int(start[3:5]) * 60 + int(start[6:])
        # print(start_s)
        end_s = int(end[:2]) * 3600 + int(end[3:5]) * 60 + int(end[6:])
        # print(end_s)
        length_s = end_s - start_s
        # print(length_s)
        hr = self.twodigi(str(length_s // 3600))
        mn = self.twodigi(str((length_s % 3600) // 60))
        sc = self.twodigi(str(length_s % 60))
        length = hr + ':' + mn + ':' + sc
        print(length)
        return length

    def handleError(self):
        self.playButton.setEnabled(False)
        self.apointButton.setEnabled(False)
        self.bpointButton.setEnabled(False)
        self.cutButton.setEnabled(False)
        print("Error: " + self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        print('Quit.')
        app.quit()

    def contextMenuRequested(self, point):
        menu = QtWidgets.QMenu()
        actionFile = menu.addAction('Open File (o)')
        actionFile.triggered.connect(self.openFile)

        actionToggle = menu.addAction('show / hide Slider (s)')
        actionToggle.triggered.connect(self.toggleSlider)

        action169 = menu.addAction('16 : 9')
        action169.triggered.connect(self.screen169)

        action43 = menu.addAction('4 : 3')
        action43.triggered.connect(self.screen43)

        actionQuit = menu.addAction('Exit (q)')
        actionQuit.triggered.connect(self.handleQuit)

        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self, event):
        mwidth = self.frameGeometry().width()
        #mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mscale = event.angleDelta().y() / 5
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth + mscale,
                             (mwidth + mscale) / 1.778)
        else:
            self.setGeometry(mleft, mtop, mwidth + mscale,
                             (mwidth + mscale) / 1.33)

    def screen169(self):
        self.widescreen = True
        mwidth = self.frameGeometry().width()
        #mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.778
        self.setGeometry(mleft, mtop, mwidth, mwidth / mratio)

    def screen43(self):
        self.widescreen = False
        mwidth = self.frameGeometry().width()
        #mheight = self.frameGeometry().height()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        mratio = 1.33
        self.setGeometry(mleft, mtop, mwidth, mwidth / mratio)

    def handleFullscreen(self):
        pass

    def handleInfo(self):
        pass

    def toggleSlider(self):
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()

    def hideSlider(self):
        self.playButton.hide()
        self.lbl.hide()
        self.positionSlider.hide()
        self.elbl.hide()
        mwidth = self.frameGeometry().width()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778)
        else:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33)

    def showSlider(self):
        self.playButton.show()
        self.lbl.show()
        self.positionSlider.show()
        self.elbl.show()
        mwidth = self.frameGeometry().width()
        mleft = self.frameGeometry().left()
        mtop = self.frameGeometry().top()
        self.positionSlider.setFocus()
        if self.widescreen == True:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55)
        else:
            self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33)

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 100 * 60)

    def forwardSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 250 * 60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 100 * 60)

    def backSlider10(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 250 * 60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)

    '''
    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            #self.move(event.globalPos() - QPoint(self.frameGeometry().width() / 2, self.frameGeometry().height() / 2))
            self.move(event.globalPos() - QPoint(self.geometry().left(),self.geometry().top()))
            event.accept()
    '''

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasFormat('text/plain'):
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            f = str(event.mimeData().urls()[0].toLocalFile())
            self.load_film(f)
            self.inputfile = pathlib.Path(f)
        elif event.mimeData().hasText():
            f = str(event.mimeData().text())
            self.mediaPlayer.setMedia(QMediaContent(QUrl(f)))
            self.inputfile = pathlib.Path(f)
            self.mediaPlayer.play()

    def load_film(self, f):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.apointButton.setEnabled(True)
        self.bpointButton.setEnabled(True)
        self.cutButton.setEnabled(True)
        self.mediaPlayer.play()

    def open_file_at_start(self, filelist):
        matching = [s for s in filelist if '.myformat' in s]
        if len(matching) > 0:
            self.load_film(matching)

    def handle_label(self):
        self.lbl.clear()
        mtime = QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(self.time.toString())
Beispiel #34
0
class QgsFmvPlayer(QMainWindow, Ui_PlayerWindow):
    """ Video Player Class """
    def __init__(self,
                 iface,
                 path,
                 parent=None,
                 meta_reader=None,
                 pass_time=None,
                 initialPt=None,
                 isStreaming=False):
        """ Constructor """
        super(QgsFmvPlayer, self).__init__(parent)
        self.setupUi(self)
        self.parent = parent
        self.iface = iface
        self.fileName = path
        self.initialPt = initialPt
        self.meta_reader = meta_reader
        self.isStreaming = isStreaming
        self.createingMosaic = False
        self.currentInfo = 0.0
        self.data = None

        # Create Draw Toolbar
        self.DrawToolBar.addAction(self.actionMagnifying_glass)
        self.DrawToolBar.addSeparator()

        # Draw Polygon QToolButton
        self.toolBtn_DPolygon.setDefaultAction(self.actionDraw_Polygon)
        self.DrawToolBar.addWidget(self.toolBtn_DPolygon)

        # Draw Point QToolButton
        self.toolBtn_DPoint.setDefaultAction(self.actionDraw_Pinpoint)
        self.DrawToolBar.addWidget(self.toolBtn_DPoint)

        # Draw Point QToolButton
        self.toolBtn_DLine.setDefaultAction(self.actionDraw_Line)
        self.DrawToolBar.addWidget(self.toolBtn_DLine)

        self.DrawToolBar.addAction(self.actionRuler)
        self.DrawToolBar.addSeparator()

        #         # Censure QToolButton
        #         self.toolBtn_Cesure.setDefaultAction(self.actionCensure)
        #         self.DrawToolBar.addWidget(self.toolBtn_Cesure)
        #         self.DrawToolBar.addSeparator()
        #
        #         # Object Tracking
        #         self.DrawToolBar.addAction(self.actionObject_Tracking)
        self.toolBtn_Cesure.setVisible(False)
        # Hide Color Button
        self.btn_Color.hide()

        self.RecGIF = QMovie(":/imgFMV/images/record.gif")

        self.videoWidget.customContextMenuRequested[QPoint].connect(
            self.contextMenuRequested)

        self.menubarwidget.customContextMenuRequested[QPoint].connect(
            self.contextMenuBarRequested)

        self.duration = 0
        self.playerMuted = False
        self.HasFileAudio = False

        self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.pass_time = pass_time
        self.player.setNotifyInterval(700)  # Metadata Callback Interval
        self.playlist = QMediaPlaylist()

        self.player.setVideoOutput(
            self.videoWidget.videoSurface())  # Abstract Surface

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)

        self.player.stateChanged.connect(self.setCurrentState)

        self.playerState = QMediaPlayer.LoadingMedia
        self.playFile(path)

        self.sliderDuration.setRange(0, self.player.duration() / 1000)

        self.volumeSlider.setValue(self.player.volume())
        self.volumeSlider.enterEvent = self.showVolumeTip

        self.metadataDlg = QgsFmvMetadata(parent=self, player=self)
        self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg)
        self.metadataDlg.setMinimumWidth(500)
        self.metadataDlg.hide()

        self.converter = Converter()
        self.BitratePlot = CreatePlotsBitrate()

    def HasAudio(self, videoPath):
        """ Check if video have Metadata or not """
        try:
            p = _spawn([
                '-i', videoPath, '-show_streams', '-select_streams', 'a',
                '-preset', 'ultrafast', '-loglevel', 'error'
            ],
                       t="probe")

            stdout_data, _ = p.communicate()

            if stdout_data == b'':
                qgsu.showUserAndLogMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "This video doesn't have Audio ! "))
                self.actionAudio.setEnabled(False)
                self.actionSave_Audio.setEnabled(False)
                return False

            return True
        except Exception as e:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Audio check Failed! : "), str(e))
            self.actionAudio.setEnabled(False)
            self.actionSave_Audio.setEnabled(False)

    def get_metadata_from_buffer(self, currentTime):
        """ Metadata CallBack """
        try:

            # There is no way to spawn a thread and call after join() without blocking the video UI thread.
            # callBackMetadata can be as fast as possible, it will always create a small video lag every time meta are read.
            # To get rid of this, we fill a buffer (BufferedMetaReader) in the QManager with some Metadata in advance,
            # and hope they'll be ready to read here in a totaly non-blocking
            # way (increase the buffer size if needed in QManager).

            stdout_data = self.meta_reader.get(currentTime)
            # qgsu.showUserAndLogMessage(
            #    "", "stdout_data: " + str(stdout_data) + " currentTime: " + str(currentTime), onlyLog=True)
            if stdout_data == 'NOT_READY':
                self.metadataDlg.menuSave.setEnabled(False)
                qgsu.showUserAndLogMessage(
                    "",
                    "Buffer value read but is not ready, increase buffer size. : ",
                    onlyLog=True)
                return

            #Values need to be read, pause the video a short while
            elif stdout_data == 'BUFFERING':
                qgsu.showUserAndLogMessage("Buffering metadata...",
                                           "",
                                           duration=4,
                                           level=QGis.Info)
                self.player.pause()
                QTimer.singleShot(2500, lambda: self.player.play())
                return

            elif stdout_data == b'' or len(stdout_data) == 0:
                self.metadataDlg.menuSave.setEnabled(False)
                qgsu.showUserAndLogMessage(
                    "",
                    "Buffer returned empty metadata, check pass_time. : ",
                    onlyLog=True)
                return

            self.packetStreamParser(stdout_data)

        except Exception as inst:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Metadata Buffer Failed! : "),
                str(inst))

    def packetStreamParser(self, stdout_data):
        ''' Common packet process'''
        for packet in StreamParser(stdout_data):
            try:
                if isinstance(packet, UnknownElement):
                    qgsu.showUserAndLogMessage(
                        "Error interpreting klv data, metadata cannot be read.",
                        "the parser did not recognize KLV data",
                        level=QGis.Warning,
                        onlyLog=True)
                    continue
                data = packet.MetadataList()
                self.data = data
                if self.metadataDlg.isVisible(
                ):  # Only add metada to table if this QDockWidget is visible (speed plugin)
                    self.metadataDlg.menuSave.setEnabled(True)
                    self.addMetadata(data)

                UpdateLayers(packet, parent=self, mosaic=self.createingMosaic)
                QApplication.processEvents()
                return
            except Exception:
                None
#                     qgsu.showUserAndLogMessage(QCoreApplication.translate(
#                         "QgsFmvPlayer", "Meta update failed! "), " Packet:" + str(packet) + ", error:" + str(inst), level=QGis.Warning)

    def callBackMetadata(self, currentTime, nextTime):
        """ Metadata CallBack """
        try:
            port = int(self.fileName.split(':')[2])
            t = callBackMetadataThread(cmds=[
                '-i',
                self.fileName.replace(str(port), str(
                    port + 1)), '-ss', currentTime, '-to', nextTime, '-map',
                'data-re', '-preset', 'ultrafast', '-f', 'data', '-'
            ])
            t.start()
            t.join(1)
            if t.is_alive():
                t.p.terminate()
                t.join()

            qgsu.showUserAndLogMessage("",
                                       "callBackMetadataThread self.stdout: " +
                                       str(t.stdout),
                                       onlyLog=True)

            if t.stdout == b'':
                return

            self.packetStreamParser(t.stdout)

        except Exception as e:
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Metadata Callback Failed! : "),
                str(e))

    def GetPacketData(self):
        ''' Return Current Packet data '''
        return self.data

    def addMetadata(self, packet):
        ''' Add Metadata to List '''
        self.clearMetadata()
        row = 0
        for key in sorted(packet.keys()):
            self.metadataDlg.VManager.insertRow(row)
            self.metadataDlg.VManager.setItem(row, 0,
                                              QTableWidgetItem(str(key)))
            self.metadataDlg.VManager.setItem(
                row, 1, QTableWidgetItem(str(packet[key][0])))
            self.metadataDlg.VManager.setItem(
                row, 2, QTableWidgetItem(str(packet[key][1])))
            row += 1
        self.metadataDlg.VManager.setVisible(False)
        self.metadataDlg.VManager.resizeColumnsToContents()
        self.metadataDlg.VManager.setVisible(True)
        self.metadataDlg.VManager.verticalScrollBar().setSliderPosition(
            self.sliderPosition)

    def clearMetadata(self):
        ''' Clear Metadata List '''
        try:
            self.sliderPosition = self.metadataDlg.VManager.verticalScrollBar(
            ).sliderPosition()
            self.metadataDlg.VManager.setRowCount(0)
        except Exception:
            None

    def saveInfoToJson(self):
        """ Save video Info to json """
        out_json, _ = askForFiles(self,
                                  QCoreApplication.translate(
                                      "QgsFmvPlayer", "Save Json"),
                                  isSave=True,
                                  exts="json")

        if not out_json:
            return

        taskSaveInfoToJson = QgsTask.fromFunction(
            'Save Video Info to Json Task',
            self.converter.probeToJson,
            fname=self.fileName,
            output=out_json,
            on_finished=self.finishedTask,
            flags=QgsTask.CanCancel)

        QgsApplication.taskManager().addTask(taskSaveInfoToJson)
        return

    def showVideoInfo(self):
        ''' Show default probe info '''

        taskSaveInfoToJson = QgsTask.fromFunction(
            'Show Video Info Task',
            self.converter.probeShow,
            fname=self.fileName,
            on_finished=self.finishedTask,
            flags=QgsTask.CanCancel)

        QgsApplication.taskManager().addTask(taskSaveInfoToJson)
        return

    def state(self):
        ''' Return Current State '''
        return self.playerState

    def setCurrentState(self, state):
        ''' Set Current State '''
        if state != self.playerState:
            self.playerState = state
            if state == QMediaPlayer.StoppedState:
                self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png"))

        return

    def showColorDialog(self):
        ''' Show Color dialog '''
        self.ColorDialog = ColorDialog(parent=self)
        self.ColorDialog.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint)
        # Fail if not uncheked
        self.actionMagnifying_glass.setChecked(False)
        self.ColorDialog.exec_()
        QApplication.processEvents()
        self.ColorDialog.contrastSlider.setValue(80)
        self.ColorDialog.contrastSlider.triggerAction(
            QAbstractSlider.SliderMove)
        return

    def createMosaic(self, value):
        ''' Function for create Video Mosaic '''
        home = os.path.expanduser("~")

        qgsu.createFolderByName(home, "QGIS_FMV")
        homefmv = os.path.join(home, "QGIS_FMV")
        root, _ = os.path.splitext(os.path.basename(self.fileName))
        qgsu.createFolderByName(homefmv, root)
        self.createingMosaic = value
        # Create Group
        CreateGroupByName()
        return

    def contextMenuBarRequested(self, point):
        ''' Context Menu Menu Bar '''
        menu = QMenu('ToolBars')
        toolbars = self.findChildren(QToolBar)
        for toolbar in toolbars:
            action = menu.addAction(toolbar.windowTitle())
            action.setCheckable(True)
            action.setChecked(toolbar.isVisible())
            action.setObjectName(toolbar.windowTitle())
            action.triggered.connect(lambda _: self.ToggleQToolBar())
        menu.exec_(self.mapToGlobal(point))
        return

    def ToggleQToolBar(self):
        ''' Toggle ToolBar '''
        toolbars = self.findChildren(QToolBar)
        for toolbar in toolbars:
            if self.sender().objectName() == toolbar.windowTitle():
                toolbar.toggleViewAction().trigger()

    def contextMenuRequested(self, point):
        ''' Context Menu Video '''
        menu = QMenu('Video')

        #         actionColors = menu.addAction(
        #             QCoreApplication.translate("QgsFmvPlayer", "Color Options"))
        #         actionColors.setShortcut("Ctrl+May+C")
        #         actionColors.triggered.connect(self.showColorDialog)

        actionMute = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer", "Mute/Unmute"))
        actionMute.setShortcut("Ctrl+Shift+U")
        actionMute.triggered.connect(self.setMuted)

        menu.addSeparator()
        actionAllFrames = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer", "Extract All Frames"))
        actionAllFrames.setShortcut("Ctrl+Shift+A")
        actionAllFrames.triggered.connect(self.ExtractAllFrames)

        actionCurrentFrames = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer",
                                       "Extract Current Frame"))
        actionCurrentFrames.setShortcut("Ctrl+Shift+Q")
        actionCurrentFrames.triggered.connect(self.ExtractCurrentFrame)

        menu.addSeparator()
        actionShowMetadata = menu.addAction(
            QCoreApplication.translate("QgsFmvPlayer", "Show Metadata"))
        actionShowMetadata.setShortcut("Ctrl+Shift+M")
        actionShowMetadata.triggered.connect(self.OpenQgsFmvMetadata)

        menu.exec_(self.mapToGlobal(point))

    # Start Snnipet FILTERS
    def grayFilter(self, value):
        ''' Gray Video Filter '''
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetGray(value)
        self.videoWidget.UpdateSurface()
        return

    def MirrorHorizontalFilter(self, value):
        ''' Mirror Horizontal Video Filter '''
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetMirrorH(value)
        self.videoWidget.UpdateSurface()
        return

    def edgeFilter(self, value):
        ''' Edge Detection Video Filter '''
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetEdgeDetection(value)
        self.videoWidget.UpdateSurface()
        return

    def invertColorFilter(self, value):
        ''' Invert Color Video Filter '''
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetInvertColor(value)
        self.videoWidget.UpdateSurface()
        return

    def autoContrastFilter(self, value):
        ''' Auto Contrast Video Filter '''
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetAutoContrastFilter(value)
        self.videoWidget.UpdateSurface()
        return

    def monoFilter(self, value):
        ''' Filter Mono Video '''
        self.UncheckFilters(self.sender(), value)
        self.videoWidget.SetMonoFilter(value)
        self.videoWidget.UpdateSurface()
        return

    def magnifier(self, value):
        ''' Magnifier Glass Utils '''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetMagnifier(value)
        self.videoWidget.UpdateSurface()
        return

    def pointDrawer(self, value):
        ''' Draw Point '''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetPointDrawer(value)
        self.videoWidget.UpdateSurface()

    def lineDrawer(self, value):
        ''' Draw Line '''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetLineDrawer(value)
        self.videoWidget.UpdateSurface()

    def polygonDrawer(self, value):
        ''' Draw Polygon '''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetPolygonDrawer(value)
        self.videoWidget.UpdateSurface()

    def ojectTracking(self, value):
        ''' Object Tracking '''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetObjectTracking(value)
        self.videoWidget.UpdateSurface()

    def VideoRuler(self, value):
        ''' Video Ruler '''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetRuler(value)
        if value:
            self.player.pause()
            self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png"))
        else:
            self.videoWidget.ResetDrawRuler()
            self.player.play()
            self.btn_play.setIcon(QIcon(":/imgFMV/images/pause.png"))

        self.videoWidget.UpdateSurface()

    def VideoCensure(self, value):
        ''' Censure Video Parts'''
        self.UncheckUtils(self.sender(), value)
        self.videoWidget.SetCensure(value)
        self.videoWidget.UpdateSurface()
        return

    def UncheckUtils(self, sender, value):
        ''' Uncheck Utils Video '''
        self.actionMagnifying_glass.setChecked(False)
        self.actionDraw_Pinpoint.setChecked(False)
        self.actionDraw_Line.setChecked(False)
        self.actionDraw_Polygon.setChecked(False)
        self.actionObject_Tracking.setChecked(False)
        self.actionRuler.setChecked(False)
        self.actionCensure.setChecked(False)

        self.videoWidget.RestoreDrawer()

        sender.setChecked(value)
        return

    def UncheckFilters(self, sender, value):
        ''' Uncheck Filters Video '''
        self.actionGray.setChecked(False)
        self.actionInvert_Color.setChecked(False)
        self.actionMono_Filter.setChecked(False)
        self.actionCanny_edge_detection.setChecked(False)
        self.actionAuto_Contrast_Filter.setChecked(False)
        self.actionMirroredH.setChecked(False)

        self.videoWidget.RestoreFilters()

        sender.setChecked(value)
        return

    # End Snnipet FILTERS

    def isMuted(self):
        ''' Is muted video property'''
        return self.playerMuted

    def setMuted(self):
        ''' Muted video '''
        if self.player.isMuted():
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png"))
            self.player.setMuted(False)
            self.volumeSlider.setEnabled(True)
        else:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png"))
            self.player.setMuted(True)
            self.volumeSlider.setEnabled(False)
        return

    def stop(self):
        ''' Stop video'''
        # Prevent Error in a Video Utils.Disable Magnifier
        if self.actionMagnifying_glass.isChecked():
            self.actionMagnifying_glass.trigger()
        # Stop Video
        self.fakeStop()
        return

    def volume(self):
        ''' Volume Slider '''
        return self.volumeSlider.value()

    def setVolume(self, volume):
        ''' Tooltip and set Volume value and icon '''
        self.player.setVolume(volume)
        self.showVolumeTip(volume)
        if 0 < volume <= 30:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_30.png"))
        elif 30 < volume <= 60:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_60.png"))
        elif 60 < volume <= 100:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png"))
        elif volume == 0:
            self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png"))

    def EndMedia(self):
        ''' Button end video position '''
        if self.player.isVideoAvailable():
            self.player.setPosition(self.player.duration())
            self.videoWidget.update()
        return

    def StartMedia(self):
        ''' Button start video position '''
        if self.player.isVideoAvailable():
            self.player.setPosition(0)
            self.videoWidget.update()
        return

    def forwardMedia(self):
        ''' Button forward Video '''
        forwardTime = int(self.player.position()) + 10 * 1000
        if forwardTime > int(self.player.duration()):
            forwardTime = int(self.player.duration())
        self.player.setPosition(forwardTime)

    def rewindMedia(self):
        ''' Button rewind Video '''
        rewindTime = int(self.player.position()) - 10 * 1000
        if rewindTime < 0:
            rewindTime = 0
        self.player.setPosition(rewindTime)

    def AutoRepeat(self, checked):
        ''' Button AutoRepeat Video '''
        if checked:
            self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
        else:
            self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
        return

    def showVolumeTip(self, _):
        ''' Volume Slider Tooltip Trick '''
        self.style = self.volumeSlider.style()
        self.opt = QStyleOptionSlider()
        self.volumeSlider.initStyleOption(self.opt)
        rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt,
                                               self.style.SC_SliderHandle)
        self.tip_offset = QPoint(5, 15)
        pos_local = rectHandle.topLeft() + self.tip_offset
        pos_global = self.volumeSlider.mapToGlobal(pos_local)
        QToolTip.showText(pos_global,
                          str(self.volumeSlider.value()) + " %", self)

    def showMoveTip(self, currentInfo):
        ''' Player Silder Move Tooptip Trick '''
        self.style = self.sliderDuration.style()
        self.opt = QStyleOptionSlider()
        self.sliderDuration.initStyleOption(self.opt)
        rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt,
                                               self.style.SC_SliderHandle)
        self.tip_offset = QPoint(5, 15)
        pos_local = rectHandle.topLeft() + self.tip_offset
        pos_global = self.sliderDuration.mapToGlobal(pos_local)

        tStr = _seconds_to_time(currentInfo)

        QToolTip.showText(pos_global, tStr, self)

    def durationChanged(self, duration):
        ''' Duration video change signal '''
        duration /= 1000
        self.duration = duration
        self.sliderDuration.setMaximum(duration)

    def positionChanged(self, progress):
        ''' Current Video position change '''
        progress /= 1000

        if not self.sliderDuration.isSliderDown():
            self.sliderDuration.setValue(progress)

        self.updateDurationInfo(progress)

    def updateDurationInfo(self, currentInfo):
        ''' Update labels duration Info and CallBack Metadata '''
        duration = self.duration
        self.currentInfo = currentInfo
        if currentInfo or duration:

            totalTime = _seconds_to_time(duration)
            currentTime = _seconds_to_time(currentInfo)
            tStr = currentTime + " / " + totalTime
            currentTimeInfo = _seconds_to_time_frac(currentInfo)
            # Get Metadata from buffer
            if not self.isStreaming:
                self.get_metadata_from_buffer(currentTimeInfo)
            else:
                qgsu.showUserAndLogMessage("", "Streaming on ", onlyLog=True)
                nextTime = currentInfo + self.pass_time / 1000
                nextTimeInfo = _seconds_to_time_frac(nextTime)
                self.callBackMetadata(currentTimeInfo, nextTimeInfo)

        else:
            tStr = ""

        self.labelDuration.setText(tStr)

    def handleCursor(self, status):
        ''' Change cursor '''
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia,
                      QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def statusChanged(self, status):
        ''' Signal Status video change '''
        self.handleCursor(status)
        if status is QMediaPlayer.LoadingMedia or status is QMediaPlayer.StalledMedia or status is QMediaPlayer.InvalidMedia:
            self.videoAvailableChanged(False)
        elif status == QMediaPlayer.InvalidMedia:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", self.player.errorString()),
                                       level=QGis.Warning)
            self.videoAvailableChanged(False)
        else:
            self.videoAvailableChanged(True)

    def playFile(self, videoPath):
        ''' Play file from path '''
        try:
            RemoveVideoLayers()
            RemoveGroupByName()
            #             if "udp://" in videoPath:
            #                 host, port = videoPath.split("://")[1].split(":")
            #                 receiver = UDPClient(host, int(port), type="udp")
            #                 receiver.show()
            #                 self.close()
            #                 return
            #             if "tcp://" in videoPath:
            #                 host, port = videoPath.split("://")[1].split(":")
            #                 receiver = UDPClient(host, port, type="tcp")
            #                 receiver.show()
            #                 self.close()
            #                 return
            self.fileName = videoPath
            self.playlist = QMediaPlaylist()
            if self.isStreaming:
                url = QUrl(videoPath)
            else:
                url = QUrl.fromLocalFile(videoPath)
            qgsu.showUserAndLogMessage("", "Added: " + str(url), onlyLog=True)
            self.playlist.addMedia(QMediaContent(url))
            self.player.setPlaylist(self.playlist)

            self.setWindowTitle(
                QCoreApplication.translate("QgsFmvPlayer", 'Playing : ') +
                os.path.basename(os.path.normpath(videoPath)))

            CreateVideoLayers()
            self.clearMetadata()

            self.HasFileAudio = True
            if not self.HasAudio(videoPath):
                self.actionAudio.setEnabled(False)
                self.actionSave_Audio.setEnabled(False)
                self.HasFileAudio = False

            # Recenter map on video initial point
            if self.initialPt:
                rect = QgsRectangle(self.initialPt[1], self.initialPt[0],
                                    self.initialPt[1], self.initialPt[0])
                self.iface.mapCanvas().setExtent(rect)
                self.iface.mapCanvas().refresh()

            self.playClicked(True)

        except Exception as e:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", 'Open Video File : '),
                                       str(e),
                                       level=QGis.Warning)

    def ReciconUpdate(self, _):
        ''' Record Button Icon Effect '''
        self.btn_Rec.setIcon(QIcon(self.RecGIF.currentPixmap()))

    def StopRecordAnimation(self):
        '''Stop record gif animation'''
        self.RecGIF.frameChanged.disconnect(self.ReciconUpdate)
        self.RecGIF.stop()
        self.btn_Rec.setIcon(QIcon(":/imgFMV/images/record.png"))

    # TODO: Make in other thread
    def RecordVideo(self, value):
        ''' Cut Video '''
        currentTime = _seconds_to_time(self.currentInfo)

        if value is False:
            self.endRecord = currentTime
            _, file_extension = os.path.splitext(self.fileName)

            out, _ = askForFiles(self,
                                 QCoreApplication.translate(
                                     "QgsFmvPlayer", "Save video record"),
                                 isSave=True,
                                 exts=file_extension[1:])

            if not out:
                self.StopRecordAnimation()
                return

            p = _spawn([
                '-i', self.fileName, '-ss', self.startRecord, '-to',
                self.endRecord, '-preset', 'ultrafast', '-c', 'copy', out
            ])
            p.communicate()
            qgsu.showUserAndLogMessage(
                QCoreApplication.translate("QgsFmvPlayer",
                                           "Save file succesfully!"))

            self.StopRecordAnimation()
        else:
            self.startRecord = currentTime
            self.RecGIF.frameChanged.connect(self.ReciconUpdate)
            self.RecGIF.start()
        return

    def videoAvailableChanged(self, available):
        ''' Buttons for video available '''
        # self.btn_Color.setEnabled(available)
        self.btn_CaptureFrame.setEnabled(available)
        self.gb_PlayerControls.setEnabled(available)
        return

    def toggleGroup(self, state):
        ''' Toggle GroupBox '''
        sender = self.sender()
        if state:
            sender.setFixedHeight(sender.sizeHint().height())
        else:
            sender.setFixedHeight(15)

    def fakeStop(self):
        '''self.player.stop() make a black screen and not reproduce it again'''
        self.player.pause()
        self.StartMedia()
        self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png"))

    def playClicked(self, _):
        ''' Stop and Play video '''
        if self.playerState in (QMediaPlayer.StoppedState,
                                QMediaPlayer.PausedState):
            self.btn_play.setIcon(QIcon(":/imgFMV/images/pause.png"))
            # Uncheck Ruler
            self.videoWidget.ResetDrawRuler()
            self.actionRuler.setChecked(False)
            self.videoWidget.SetRuler(False)
            # Play Video
            self.player.play()
        elif self.playerState == QMediaPlayer.PlayingState:
            self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png"))
            self.player.pause()

    def seek(self, seconds):
        '''Slider Move'''
        self.player.setPosition(seconds * 1000)
        self.showMoveTip(seconds)

    def convertVideo(self):
        '''Convert Video To Other Format '''
        out, _ = askForFiles(self,
                             QCoreApplication.translate(
                                 "QgsFmvPlayer", "Save Video as..."),
                             isSave=True,
                             exts=[
                                 "mp4", "ogg", "avi", "mkv", "webm", "flv",
                                 "mov", "mpg", "mp3"
                             ])

        if not out:
            return

        # TODO : Make Correct format Conversion and embebed metadata
        info = self.converter.probeInfo(self.fileName)
        if info is not None:
            if self.HasFileAudio:
                audio_codec = info.audio.codec
                audio_samplerate = info.audio.audio_samplerate
                audio_channels = info.audio.audio_channels

            video_codec = info.video.codec
            video_width = info.video.video_width
            video_height = info.video.video_height
            video_fps = info.video.video_fps

        _, out_ext = os.path.splitext(out)

        if self.HasFileAudio:
            options = {
                'format': out_ext[1:],
                'audio': {
                    'codec': audio_codec,
                    'samplerate': audio_samplerate,
                    'channels': audio_channels
                },
                'video': {
                    'codec': video_codec,
                    'width': video_width,
                    'height': video_height,
                    'fps': video_fps
                }
            }
        else:
            options = {
                'format': out_ext[1:],
                'video': {
                    'codec': video_codec,
                    'width': video_width,
                    'height': video_height,
                    'fps': video_fps
                }
            }

        taskConvertVideo = QgsTask.fromFunction('Converting Video Task',
                                                self.converter.convert,
                                                infile=self.fileName,
                                                outfile=out,
                                                options=options,
                                                twopass=False,
                                                on_finished=self.finishedTask,
                                                flags=QgsTask.CanCancel)

        QgsApplication.taskManager().addTask(taskConvertVideo)

    def CreateBitratePlot(self):
        ''' Create video Plot Bitrate Thread '''
        sender = self.sender().objectName()

        if sender == "actionAudio":
            taskactionAudio = QgsTask.fromFunction(
                'Show Audio Bitrate',
                self.BitratePlot.CreatePlot,
                fileName=self.fileName,
                output=None,
                t='audio',
                on_finished=self.finishedTask,
                flags=QgsTask.CanCancel)

            QgsApplication.taskManager().addTask(taskactionAudio)

        elif sender == "actionVideo":
            taskactionVideo = QgsTask.fromFunction(
                'Show Video Bitrate',
                self.BitratePlot.CreatePlot,
                fileName=self.fileName,
                output=None,
                t='video',
                on_finished=self.finishedTask,
                flags=QgsTask.CanCancel)

            QgsApplication.taskManager().addTask(taskactionVideo)

        elif sender == "actionSave_Audio":
            fileaudio, _ = askForFiles(self,
                                       QCoreApplication.translate(
                                           "QgsFmvPlayer",
                                           "Save Audio Bitrate Plot"),
                                       isSave=True,
                                       exts=[
                                           "png", "pdf", "pgf", "eps", "ps",
                                           "raw", "rgba", "svg", "svgz"
                                       ])

            if not fileaudio:
                return

            taskactionSave_Audio = QgsTask.fromFunction(
                'Save Action Audio Bitrate',
                self.BitratePlot.CreatePlot,
                fileName=self.fileName,
                output=fileaudio,
                t='audio',
                on_finished=self.finishedTask,
                flags=QgsTask.CanCancel)

            QgsApplication.taskManager().addTask(taskactionSave_Audio)

        elif sender == "actionSave_Video":
            filevideo, _ = askForFiles(self,
                                       QCoreApplication.translate(
                                           "QgsFmvPlayer",
                                           "Save Video Bitrate Plot"),
                                       isSave=True,
                                       exts=[
                                           "png", "pdf", "pgf", "eps", "ps",
                                           "raw", "rgba", "svg", "svgz"
                                       ])

            if not filevideo:
                return

            taskactionSave_Video = QgsTask.fromFunction(
                'Save Action Video Bitrate',
                self.BitratePlot.CreatePlot,
                fileName=self.fileName,
                output=filevideo,
                t='video',
                on_finished=self.finishedTask,
                flags=QgsTask.CanCancel)

            QgsApplication.taskManager().addTask(taskactionSave_Video)

    def finishedTask(self, e, result=None):
        """ Common finish task function """
        if e is None:
            if result is None:
                qgsu.showUserAndLogMessage(QCoreApplication.translate(
                    "QgsFmvPlayer", 'Completed with no exception and no result '\
                    '(probably manually canceled by the user)'), level=QGis.Warning)
            else:
                if "Georeferencing" in result['task']:
                    return
                qgsu.showUserAndLogMessage(
                    QCoreApplication.translate(
                        "QgsFmvPlayer", "Succesfully " + result['task'] + "!"))
                if "Bitrate" in result['task']:
                    self.matplot = ShowPlot(self.BitratePlot.bitrate_data,
                                            self.BitratePlot.frame_count,
                                            self.fileName,
                                            self.BitratePlot.output)
                if result['task'] == 'Show Video Info Task':
                    self.showVideoInfoDialog(self.converter.bytes_value)
        else:
            qgsu.showUserAndLogMessage(QCoreApplication.translate(
                "QgsFmvPlayer", "Failed " + result['task'] + "!"),
                                       level=QGis.Warning)
            raise e

    def ExtractAllFrames(self):
        """ Extract All Video Frames Task """
        directory = askForFolder(
            self,
            QCoreApplication.translate("QgsFmvPlayer", "Save all Frames"),
            options=QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly)

        if directory:
            taskExtractAllFrames = QgsTask.fromFunction(
                'Save All Frames Task',
                self.SaveAllFrames,
                fileName=self.fileName,
                directory=directory,
                on_finished=self.finishedTask,
                flags=QgsTask.CanCancel)

            QgsApplication.taskManager().addTask(taskExtractAllFrames)
        return

    def SaveAllFrames(self, task, fileName, directory):
        vidcap = cv2.VideoCapture(fileName)
        length = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
        count = 0
        while not task.isCanceled():
            _, image = vidcap.read()
            cv2.imwrite(directory + "\\frame_%d.jpg" % count,
                        image)  # save frame as JPEG file
            task.setProgress(count * 100 / length)
            count += 1
        vidcap.release()
        cv2.destroyAllWindows()
        if task.isCanceled():
            return None
        return {'task': task.description()}

    def ExtractCurrentFrame(self):
        """ Extract Current Frame Task """
        image = self.videoWidget.GetCurrentFrame()
        output, _ = askForFiles(self,
                                QCoreApplication.translate(
                                    "QgsFmvPlayer", "Save Current Frame"),
                                isSave=True,
                                exts=["png", "jpg", "bmp", "tiff"])

        if not output:
            return

        taskCurrentFrame = QgsTask.fromFunction('Save Current Frame Task',
                                                self.SaveCapture,
                                                image=image,
                                                output=output,
                                                on_finished=self.finishedTask,
                                                flags=QgsTask.CanCancel)

        QgsApplication.taskManager().addTask(taskCurrentFrame)
        return

    def SaveCapture(self, task, image, output):
        ''' Save Current Frame '''
        image.save(output)
        if task.isCanceled():
            return None
        return {'task': task.description()}

    def OpenQgsFmvMetadata(self):
        """ Open Metadata Dock """
        if self.metadataDlg is None:
            self.metadataDlg = QgsFmvMetadata(parent=self, player=self)
            self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg)
            self.metadataDlg.show()
        else:
            self.metadataDlg.show()
        return

    def showVideoInfoDialog(self, outjson):
        """ Show Video Information Dialog """
        view = QTreeView()
        model = QJsonModel()
        view.setModel(model)
        model.loadJsonFromConsole(outjson)

        self.VideoInfoDialog = QDialog(self)
        self.VideoInfoDialog.setWindowTitle(
            QCoreApplication.translate("QgsFmvPlayer", "Video Information : ")
            + self.fileName)
        self.VideoInfoDialog.setWindowIcon(
            QIcon(":/imgFMV/images/video-info.png"))

        self.verticalLayout = QVBoxLayout(self.VideoInfoDialog)
        self.verticalLayout.addWidget(view)
        view.expandAll()
        view.header().setSectionResizeMode(QHeaderView.ResizeToContents)

        self.VideoInfoDialog.setWindowFlags(Qt.Window
                                            | Qt.WindowCloseButtonHint)
        self.VideoInfoDialog.setObjectName("VideoInfoDialog")
        self.VideoInfoDialog.resize(500, 400)
        self.VideoInfoDialog.show()

    def closeEvent(self, _):
        """ Close Event """
        self.stop()
        self.parent._PlayerDlg = None
        self.parent.ToggleActiveFromTitle()
        RemoveVideoLayers()
        RemoveGroupByName()
        ResetData()

        try:
            self.metadataDlg.hide()
        except Exception:
            None
        try:
            self.matplot.close()
        except Exception:
            None
        # Restore Filters State
        self.videoWidget.RestoreFilters()
class Music_App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'Music Player'
        self.left = 20
        self.top = 30
        self.width = 600
        self.height = 400
        self.root_Gui()
        self.song_path = ""
        self.q_path = ""
        #initializing playlist and player

        self.Playlist = QMediaPlaylist()
        self.Player = QMediaPlayer()

        self.button_stat = -1
        #self.sp_st_cam= -1

    def root_Gui(self):
        #base of GUI

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.menu()
        self.main_buttons()
        self.status_bar()
        self.show()

    def menu(self):
        #menu of GUI

        main_menu = self.menuBar()
        file_menu = main_menu.addMenu('File')
        tools_menu = main_menu.addMenu('Tools')
        help__menu = main_menu.addMenu('Help')
        exit_ = main_menu.addMenu('Exit')

        file_menu.addAction(self.open_file())
        file_menu.addAction(self.exit_button())
        exit_.addAction(self.exit_button())

    def main_buttons(self):
        #different button available in GUI

        play_button = QPushButton('Play', self)
        play_button.setToolTip("To play the song click it.")
        play_button.move(100, 80)
        play_button.clicked.connect(self.play_button)

        pause_button = QPushButton('Pause', self)
        pause_button.setToolTip("To pause the song click it.")
        pause_button.move(200, 80)
        pause_button.clicked.connect(self.pause_button)

        next_button = QPushButton('Next', self)
        next_button.setToolTip('Play Next Song')
        next_button.move(300, 80)
        next_button.clicked.connect(self.next_button)

        prev_button = QPushButton('Prev', self)
        prev_button.setToolTip('Play Previous Song')
        prev_button.move(400, 80)
        prev_button.clicked.connect(self.prev_button)

        plusV_button = QPushButton('+ Vol', self)
        plusV_button.setToolTip('Increase Volume')
        plusV_button.move(100, 110)
        plusV_button.clicked.connect(self.plusV_button)

        minsV_button = QPushButton('- Vol', self)
        minsV_button.setToolTip('Decrease Volume')
        minsV_button.move(200, 110)
        minsV_button.clicked.connect(self.minsV_button)

        stop_button = QPushButton('Stop', self)
        stop_button.setToolTip('Stop Song')
        stop_button.move(300, 110)
        stop_button.clicked.connect(self.stop_button)

        info_button = QPushButton('Song Details', self)
        info_button.setToolTip('Get Song Details')
        info_button.move(400, 110)
        info_button.clicked.connect(self.info_button)

    #play button handler
    def play_button(self):
        print("Playing Music")
        if self.Playlist.mediaCount() == 0:
            self.file_dialog()
        elif self.Playlist.mediaCount() != 0:
            self.button_stat = 1
            self.Player.play()

    #pause button handler
    def pause_button(self):
        print("Pause Music")
        self.button_stat = 2
        self.Player.pause()

    #prev button handler
    def prev_button(self):
        print("Next Song")
        if self.Playlist.mediaCount() == 0:
            self.file_dialog()
        elif self.Playlist.mediaCount != 0:
            self.Player.playlist().previous()

    #next button handler
    def next_button(self):
        print("Prev Song")
        if self.Playlist.mediaCount() == 0:
            self.file_dialog()
        elif self.Playlist.mediaCount() != 0:
            self.Player.playlist().next()

    #info button handler

    def info_button(self):
        print("\n  info button")
        song = eyed3.load(self.song_path)
        artist = song.tag.artist
        album = song.tag.album
        title = song.tag.title

        s_detail = 'Artist : ' + artist + '\n\tAlbum : ' + album + '\n\tTitle : ' + title

        song_det = QMessageBox(self)
        song_det.setWindowTitle('Song Details')
        song_det.setText(s_detail)
        song_det.show()

    #volume button handler
    def plusV_button(self):
        print("Plus Volume")
        vol_ = self.Player.volume()
        vol_ = min(100, vol_ + 5)
        self.Player.setVolume(vol_)

    def minsV_button(self):
        print("Minus Volume")
        vol_ = self.Player.volume()
        vol_ = max(100, vol_ - 5)
        self.Player.setVolume(vol_)

    #stop button handler
    def stop_button(self):
        print("Stopping Music")
        self.button_stat = 3
        self.Player.stop()
        self.Playlist.clear()
        self.statusBar().showMessage("Music Stopped")

    #open file dialog

    def open_file(self):
        fopen_button = QAction('Open File', self)
        #fopen_button.setShortcut('CTRL+O')
        fopen_button.setStatusTip('Open Music File')
        fopen_button.triggered.connect(self.file_dialog)
        return fopen_button

    #EXIT button handler

    def exit_button(self):
        exit_Button = QAction('Exit', self)
        #exit_Button.setShortcut('CTRL+Q')
        exit_Button.setStatusTip('Exit Application')
        exit_Button.triggered.connect(self.close_msg)
        return exit_Button

    def show_qoute(self, q_path):

        q_img = Image.open(q_path)
        q_img.show()

    def song_play(self, song_path):
        self.button_stat = 1
        self.Playlist.addMedia(
            QMediaContent(QUrl.fromLocalFile(self.song_path)))
        self.Player.setPlaylist(self.Playlist)
        self.Player.setVolume(50)
        self.Player.play()

    #file dialog handler
    def file_dialog(self):
        fName = QFileDialog.getOpenFileName(
            self, "Select A Song", "~", "All Files (*) ;;  Mp3 Files(*.mp3)")

        if fName[0] == '':
            print("No file Selected")

        elif self.Playlist.mediaCount() == 0:
            #print(QUrl(fName[0]))

            self.song_path = fName[0]
            self.button_stat = 1
            self.Playlist.addMedia(QMediaContent(QUrl.fromLocalFile(fName[0])))
            self.Player.setPlaylist(self.Playlist)
            self.Player.setVolume(50)
            self.Player.play()

        else:

            self.Playlist.addMedia(QMediaContent(QUrl(fName[0])))

    #close/exit handler
    def close_msg(self):
        msg = QMessageBox.question(self, 'Close Msg', 'Click Yes to Close',
                                   QMessageBox.Yes, QMessageBox.No)

        if msg == QMessageBox.Yes:
            self._obj.change_f(1)
            self.close()
            print('Closing App')
        else:
            print('Not Closing')

    #status  handler
    def status_bar(self):
        self.statusBar().showMessage('ViAna Music Player')
Beispiel #36
-1
class Player(QWidget):

    fullScreenChanged = pyqtSignal(bool)

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

        self.colorDialog = None
        self.trackInfo = ""
        self.statusInfo = ""
        self.duration = 0

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)

        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.metaDataChanged.connect(self.metaDataChanged)
        self.playlist.currentIndexChanged.connect(self.playlistPositionChanged)
        self.player.mediaStatusChanged.connect(self.statusChanged)
        self.player.bufferStatusChanged.connect(self.bufferingProgress)
        self.player.videoAvailableChanged.connect(self.videoAvailableChanged)
        self.player.error.connect(self.displayErrorMessage)

        self.videoWidget = VideoWidget()
        self.player.setVideoOutput(self.videoWidget)

        self.playlistModel = PlaylistModel()
        self.playlistModel.setPlaylist(self.playlist)

        self.playlistView = QListView()
        self.playlistView.setModel(self.playlistModel)
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(self.playlist.currentIndex(), 0))

        self.playlistView.activated.connect(self.jump)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, self.player.duration() / 1000)

        self.labelDuration = QLabel()
        self.slider.sliderMoved.connect(self.seek)

        self.labelHistogram = QLabel()
        self.labelHistogram.setText("Histogram:")
        self.histogram = HistogramWidget()
        histogramLayout = QHBoxLayout()
        histogramLayout.addWidget(self.labelHistogram)
        histogramLayout.addWidget(self.histogram, 1)

        self.probe = QVideoProbe()
        self.probe.videoFrameProbed.connect(self.histogram.processFrame)
        self.probe.setSource(self.player)

        openButton = QPushButton("Open", clicked=self.open)

        controls = PlayerControls()
        controls.setState(self.player.state())
        controls.setVolume(self.player.volume())
        controls.setMuted(controls.isMuted())

        controls.play.connect(self.player.play)
        controls.pause.connect(self.player.pause)
        controls.stop.connect(self.player.stop)
        controls.next.connect(self.playlist.next)
        controls.previous.connect(self.previousClicked)
        controls.changeVolume.connect(self.player.setVolume)
        controls.changeMuting.connect(self.player.setMuted)
        controls.changeRate.connect(self.player.setPlaybackRate)
        controls.stop.connect(self.videoWidget.update)

        self.player.stateChanged.connect(controls.setState)
        self.player.volumeChanged.connect(controls.setVolume)
        self.player.mutedChanged.connect(controls.setMuted)

        self.fullScreenButton = QPushButton("FullScreen")
        self.fullScreenButton.setCheckable(True)

        self.colorButton = QPushButton("Color Options...")
        self.colorButton.setEnabled(False)
        self.colorButton.clicked.connect(self.showColorDialog)

        displayLayout = QHBoxLayout()
        displayLayout.addWidget(self.videoWidget, 2)
        displayLayout.addWidget(self.playlistView)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(openButton)
        controlLayout.addStretch(1)
        controlLayout.addWidget(controls)
        controlLayout.addStretch(1)
        controlLayout.addWidget(self.fullScreenButton)
        controlLayout.addWidget(self.colorButton)

        layout = QVBoxLayout()
        layout.addLayout(displayLayout)
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.slider)
        hLayout.addWidget(self.labelDuration)
        layout.addLayout(hLayout)
        layout.addLayout(controlLayout)
        layout.addLayout(histogramLayout)

        self.setLayout(layout)

        if not self.player.isAvailable():
            QMessageBox.warning(self, "Service not available",
                    "The QMediaPlayer object does not have a valid service.\n"
                    "Please check the media service plugins are installed.")

            controls.setEnabled(False)
            self.playlistView.setEnabled(False)
            openButton.setEnabled(False)
            self.colorButton.setEnabled(False)
            self.fullScreenButton.setEnabled(False)

        self.metaDataChanged()

        self.addToPlaylist(playlist)

    def open(self):
        fileNames, _ = QFileDialog.getOpenFileNames(self, "Open Files")
        self.addToPlaylist(fileNames)

    def addToPlaylist(self, fileNames):
        for name in fileNames:
            fileInfo = QFileInfo(name)
            if fileInfo.exists():
                url = QUrl.fromLocalFile(fileInfo.absoluteFilePath())
                if fileInfo.suffix().lower() == 'm3u':
                    self.playlist.load(url)
                else:
                    self.playlist.addMedia(QMediaContent(url))
            else:
                url = QUrl(name)
                if url.isValid():
                    self.playlist.addMedia(QMediaContent(url))

    def durationChanged(self, duration):
        duration /= 1000

        self.duration = duration
        self.slider.setMaximum(duration)

    def positionChanged(self, progress):
        progress /= 1000

        if not self.slider.isSliderDown():
            self.slider.setValue(progress)

        self.updateDurationInfo(progress)

    def metaDataChanged(self):
        if self.player.isMetaDataAvailable():
            self.setTrackInfo("%s - %s" % (
                    self.player.metaData(QMediaMetaData.AlbumArtist),
                    self.player.metaData(QMediaMetaData.Title)))

    def previousClicked(self):
        # Go to the previous track if we are within the first 5 seconds of
        # playback.  Otherwise, seek to the beginning.
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)

    def jump(self, index):
        if index.isValid():
            self.playlist.setCurrentIndex(index.row())
            self.player.play()

    def playlistPositionChanged(self, position):
        self.playlistView.setCurrentIndex(
                self.playlistModel.index(position, 0))

    def seek(self, seconds):
        self.player.setPosition(seconds * 1000)

    def statusChanged(self, status):
        self.handleCursor(status)

        if status == QMediaPlayer.LoadingMedia:
            self.setStatusInfo("Loading...")
        elif status == QMediaPlayer.StalledMedia:
            self.setStatusInfo("Media Stalled")
        elif status == QMediaPlayer.EndOfMedia:
            QApplication.alert(self)
        elif status == QMediaPlayer.InvalidMedia:
            self.displayErrorMessage()
        else:
            self.setStatusInfo("")

    def handleCursor(self, status):
        if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia):
            self.setCursor(Qt.BusyCursor)
        else:
            self.unsetCursor()

    def bufferingProgress(self, progress):
        self.setStatusInfo("Buffering %d%" % progress)

    def videoAvailableChanged(self, available):
        if available:
            self.fullScreenButton.clicked.connect(
                    self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.connect(
                    self.fullScreenButton.setChecked)

            if self.fullScreenButton.isChecked():
                self.videoWidget.setFullScreen(True)
        else:
            self.fullScreenButton.clicked.disconnect(
                    self.videoWidget.setFullScreen)
            self.videoWidget.fullScreenChanged.disconnect(
                    self.fullScreenButton.setChecked)

            self.videoWidget.setFullScreen(False)

        self.colorButton.setEnabled(available)

    def setTrackInfo(self, info):
        self.trackInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def setStatusInfo(self, info):
        self.statusInfo = info

        if self.statusInfo != "":
            self.setWindowTitle("%s | %s" % (self.trackInfo, self.statusInfo))
        else:
            self.setWindowTitle(self.trackInfo)

    def displayErrorMessage(self):
        self.setStatusInfo(self.player.errorString())

    def updateDurationInfo(self, currentInfo):
        duration = self.duration
        if currentInfo or duration:
            currentTime = QTime((currentInfo/3600)%60, (currentInfo/60)%60,
                    currentInfo%60, (currentInfo*1000)%1000)
            totalTime = QTime((duration/3600)%60, (duration/60)%60,
                    duration%60, (duration*1000)%1000);

            format = 'hh:mm:ss' if duration > 3600 else 'mm:ss'
            tStr = currentTime.toString(format) + " / " + totalTime.toString(format)
        else:
            tStr = ""

        self.labelDuration.setText(tStr)

    def showColorDialog(self):
        if self.colorDialog is None:
            brightnessSlider = QSlider(Qt.Horizontal)
            brightnessSlider.setRange(-100, 100)
            brightnessSlider.setValue(self.videoWidget.brightness())
            brightnessSlider.sliderMoved.connect(
                    self.videoWidget.setBrightness)
            self.videoWidget.brightnessChanged.connect(
                    brightnessSlider.setValue)

            contrastSlider = QSlider(Qt.Horizontal)
            contrastSlider.setRange(-100, 100)
            contrastSlider.setValue(self.videoWidget.contrast())
            contrastSlider.sliderMoved.connect(self.videoWidget.setContrast)
            self.videoWidget.contrastChanged.connect(contrastSlider.setValue)

            hueSlider = QSlider(Qt.Horizontal)
            hueSlider.setRange(-100, 100)
            hueSlider.setValue(self.videoWidget.hue())
            hueSlider.sliderMoved.connect(self.videoWidget.setHue)
            self.videoWidget.hueChanged.connect(hueSlider.setValue)

            saturationSlider = QSlider(Qt.Horizontal)
            saturationSlider.setRange(-100, 100)
            saturationSlider.setValue(self.videoWidget.saturation())
            saturationSlider.sliderMoved.connect(
                    self.videoWidget.setSaturation)
            self.videoWidget.saturationChanged.connect(
                    saturationSlider.setValue)

            layout = QFormLayout()
            layout.addRow("Brightness", brightnessSlider)
            layout.addRow("Contrast", contrastSlider)
            layout.addRow("Hue", hueSlider)
            layout.addRow("Saturation", saturationSlider)

            button = QPushButton("Close")
            layout.addRow(button)

            self.colorDialog = QDialog(self)
            self.colorDialog.setWindowTitle("Color Options")
            self.colorDialog.setLayout(layout)

            button.clicked.connect(self.colorDialog.close)

        self.colorDialog.show()