Ejemplo n.º 1
0
class ExampleApp(QtWidgets.QMainWindow, untitled.Ui_MainWindow):
    def __init__(self):  # Main Processor ui class...
        super().__init__()

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

        self.mediaPlayer.positionChanged.connect(self.position_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)
        self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
        self.horizontalSlider.sliderMoved.connect(self.set_position)
        self.horizontalSlider_2.sliderMoved.connect(self.set_volume)

        self.mediaPlayer.setVideoOutput(self.widget)
        self.pushButton.clicked.connect(self.open_file)
        self.pushButton_2.clicked.connect(self.play_video)
        self.pushButton_2.setIcon(self.style().standardIcon(
            QStyle.SP_MediaPlay))
        self.horizontalSlider.setSliderPosition(0)

        self.mediaPlayer.setVolume(50)

    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open Video")

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

    def play_video(self):

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

        else:
            self.mediaPlayer.play()

    def mediastate_changed(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.pushButton_2.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))

        else:
            self.pushButton_2.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))

    def position_changed(self, position):
        self.horizontalSlider.setValue(position)

    def duration_changed(self, duration):
        self.horizontalSlider.setRange(0, duration)

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

    def set_volume(self, position):
        value = self.horizontalSlider_2.value()
        self.mediaPlayer.setVolume(value)
        self.statusBar.showMessage("Громкость " + str(value) + " %")
Ejemplo n.º 2
0
class VideoPlayer(QWidget):
    def __init__(self, parent=None):
        super(VideoPlayer, self).__init__(parent)

        self.playButton = QPushButton()
        self.playButton.setEnabled(True)
        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)

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

        videoWidget = QVideoWidget()

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

        self.setLayout(layout)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)

    def play(self):
        self.mediaPlayer = QMediaPlayer.setMedia(
            QUrl("rtsp://xxx.xxx.xx.xx:554/live.sdp"))
        videoWidget = QVideoWidget()
        self.mediaPlayer.setVidioOutput(videoWidget)
        #self.mediaPlayer.play

        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)

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)
Ejemplo n.º 3
0
class SoundPlayerWorker(QObject):
    def __init__(self, args=(), kwargs=None):
        super().__init__()
        self.media_player = QMediaPlayer(flags=QMediaPlayer.LowLatency)
        self.playlist = QMediaPlaylist()
        self.media_player.setPlaylist(self.playlist)
        self._priority = 0

    def play_sound(self, file="", priority=0, override=False):
        """
        Method to add a new sound to play
        :param file: str
        :param override:
        :return:
        """

        # logging.info(f"file: {file}, priority: {priority}, self._priority: {self._priority}")

        if priority > self._priority:
            self.media_player.stop()
            self.playlist.clear()
            self._priority = priority

        # if override:
        #     self.media_player.stop()
        #     self.playlist.clear()

        # logging.info(f"request to play: {file}, override set to: {override}, mediaCount: {self.playlist.mediaCount()}")

        self.playlist.addMedia(QMediaContent(QUrl(file)))

        # logging.info(f"request to play, after adding file: {file}, override set to: {override}, mediaCount: {self.playlist.mediaCount()}")

        if self.media_player.state() == 0:
            self.media_player.play()

    def state_changed(self):
        """
        Method called when the media_player state is changed
        :return: 
        """
        if self.media_player.state() == 0:
            self._priority = 0

    def check_playlist_index(self):
        """
        Method to check to see if we've reached the end of the playlist or not
        :return:
        """
        if self.playlist.currentIndex() == -1:
            self.playlist.clear()

    def stop(self):
        """
        Method to stop the sound from playing any further
        :return:
        """
        self.media_player.stop()
Ejemplo n.º 4
0
class Video:
    def __init__(self, mainWindow):

        self.mainWindow = mainWindow

        self.fileName = ''

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

        self.videoWidget = QVideoWidget()

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

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

        if fileName != '':
            self.fileName = fileName

    def setMediaPlayer(self, fileName):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))
        self.mainWindow.playButton.setEnabled(True)

    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.mainWindow.playButton.setIcon(
                self.mainWindow.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.mainWindow.playButton.setIcon(
                self.mainWindow.style().standardIcon(QStyle.SP_MediaPlay))

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

    def handleError(self):
        self.mainWindow.playButton.setEnabled(False)
        self.mainWindow.errorLabel.setText("Error: " +
                                           self.mediaPlayer.errorString())
Ejemplo n.º 5
0
class QMediaPlayerAdapter(Player):
    def __init__(self, interval=1):
        self.__callback = None
        self.__player = QMediaPlayer()
        self.setNotifyInterval(interval)

    def setNotifyInterval(self, interval):
        self.__player.setNotifyInterval(interval)

    def setMusicPath(self, filePath):
        qUrl = QUrl(filePath)
        self.__player.setMedia(QMediaContent(qUrl))

    def getState(self):
        return self.__player.state()

    def getStatus(self):
        return self.__player.mediaStatus()

    def getPosition(self):
        return self.__player.position()

    def getDuration(self):
        return self.__player.duration()

    def start(self):
        if self.__player.state() != QMediaPlayer.NoMedia:
            self.__player.play()
            # self.__player.setPosition(self.__player.duration() - 2000)
        else:
            raise ValueError(
                "The media of the player should be set before the player get started."
            )

    def pause(self):
        self.__player.pause()

    def stop(self):
        self.__player.stop()

    def setCallback(self, callback):
        '''if not isinstance(callback, PlayerCallback):
            raise TypeError("The callback should be instance of PlayerCallback.")'''

        self.__callback = callback
        self.__player.mediaStatusChanged.connect(
            self.__callback.onMediaStatusChanged)
        self.__player.stateChanged.connect(self.__callback.onStateChanged)
        self.__player.positionChanged.connect(
            self.__callback.onPlayerPositionChanged)
Ejemplo n.º 6
0
class PlayerDialog(QDialog):
    def __init__(self, video, dimensions, parent=None):
        QDialog.__init__(self,
                         parent=parent,
                         flags=QtCore.Qt.WindowSystemMenuHint
                         | QtCore.Qt.WindowTitleHint
                         | QtCore.Qt.WindowCloseButtonHint)
        uic.loadUi('resources/videoplay.ui', self)
        self.videoWidget = QVideoWidget()
        self.stageLayout.addWidget(self.videoWidget)
        self.stage.setMinimumSize(QtCore.QSize(dimensions[0], dimensions[1]))
        self.playbtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.seekslider.mousePressEvent = self.__direct_slider_click
        self.seekslider.sliderMoved.connect(self.set_position)
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.__media_state_changed)
        self.mediaPlayer.positionChanged.connect(self.__position_changed)
        self.mediaPlayer.durationChanged.connect(self.__duration_changed)
        self.mediaPlayer.error.connect(self.handle_error)
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(video)))

    def __media_state_changed(self, state):
        if state == QMediaPlayer.PlayingState:
            self.playbtn.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))
        else:
            self.playbtn.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))
        if state == QMediaPlayer.StoppedState:
            self.play()

    def __direct_slider_click(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            calc_value = self.seekslider.minimum() + (
                (self.seekslider.maximum() - self.seekslider.minimum()) *
                event.x()) / self.seekslider.width()
            self.seekslider.setValue(calc_value)
            self.set_position(calc_value)
            event.accept()
        QSlider.mousePressEvent(self.seekslider, event)

    def __position_changed(self, position):
        self.seekslider.setValue(position)

    def __duration_changed(self, duration):
        self.seekslider.setRange(0, duration)
        self.play()

    def handle_error(self):
        logger.error(self.mediaPlayer.errorString())

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

    def set_position(self, position):
        self.mediaPlayer.setPosition(position)
Ejemplo n.º 7
0
class VideoPlayerWidget(QWidget):
    def __init__(self, parent=None):
        super(VideoPlayerWidget, self).__init__(parent)

        self.scene = QGraphicsScene(self)
        self.scene.setBackgroundBrush(QBrush(QColor(0, 0, 0, 255)))
        self.graphics_view = QGraphicsView(self.scene)
        self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.graphics_view.setFrameStyle(0)
        self.graphics_view.setStyleSheet(
            "QGraphicsView {background: transparent; border: 3px; outline: none;}"
        )
        self.video_item = QGraphicsVideoItem()
        self.scene.addItem(self.video_item)

        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.graphics_view)

        self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.media_player.setVideoOutput(self.video_item)

        self.video_need_replay = False
        self.video_seek_durcation = 3000  # in milliseconds

    def resizeEvent(self, event):
        self.video_item.setSize(
            QSizeF(event.size().width(),
                   event.size().height()))
        QWidget.resizeEvent(self, event)

    def play(self, url):
        self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(url)))
        self.media_player.play()

    def seek_forward(self):
        video_position = self.media_player.position()
        self.media_player.setPosition(video_position +
                                      self.video_seek_durcation)

    def seek_backward(self):
        video_position = self.media_player.position()
        self.media_player.setPosition(
            max(video_position - self.video_seek_durcation, 0))

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Space:
            if self.media_player.state() == QMediaPlayer.PlayingState:
                self.media_player.pause()
                self.video_need_replay = False
            else:
                self.media_player.play()
                self.video_need_replay = True
        elif event.key() == Qt.Key_H:
            self.seek_backward()
        elif event.key() == Qt.Key_L:
            self.seek_forward()
Ejemplo n.º 8
0
class MediaPlayer(QWidget):
    def __init__(self, media_video_url, parent=None):
        super(MediaPlayer, self).__init__(parent)
        self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.video_widget = QVideoWidget()
        self.media_player.setMedia(QMediaContent(QUrl(media_video_url)))
        self.media_player.setVideoOutput(self.video_widget)
        self.media_player.pause()
        self.mouseReleaseEvent = self.on_media_state_changed
        self.layout = QVBoxLayout()
        self.layout.addWidget(QLabel("video/gif"))
        self.layout.addWidget(self.video_widget)
        self.setLayout(self.layout)

    def on_media_state_changed(self, event):
        if self.media_player.state(
        ) == QMediaPlayer.PausedState or self.media_player.state(
        ) == QMediaPlayer.StoppedState:
            self.media_player.play()
        else:
            self.media_player.pause()
Ejemplo n.º 9
0
class VideoPlayerWidget(QWidget):

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

        self.scene = QGraphicsScene(self)
        self.scene.setBackgroundBrush(QBrush(QColor(0, 0, 0, 255)))
        self.graphics_view = QGraphicsView(self.scene)
        self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.graphics_view.setFrameStyle(0)
        self.graphics_view.setStyleSheet("QGraphicsView {background: transparent; border: 3px; outline: none;}")
        self.video_item = QGraphicsVideoItem()
        self.scene.addItem(self.video_item)

        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.graphics_view)

        self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.media_player.setVideoOutput(self.video_item)

        self.video_need_replay = False
        self.video_seek_durcation = 3000 # in milliseconds

    def resizeEvent(self, event):
        self.video_item.setSize(QSizeF(event.size().width(), event.size().height()))
        QWidget.resizeEvent(self, event)

    def play(self, url):
        self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(url)))
        self.media_player.play()

    def seek_forward(self):
        video_position = self.media_player.position()
        self.media_player.setPosition(video_position + self.video_seek_durcation)

    def seek_backward(self):
        video_position = self.media_player.position()
        self.media_player.setPosition(max(video_position - self.video_seek_durcation, 0))

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Space:
            if self.media_player.state() == QMediaPlayer.PlayingState:
                self.media_player.pause()
                self.video_need_replay = False
            else:
                self.media_player.play()
                self.video_need_replay = True
        elif event.key() == Qt.Key_H:
            self.seek_backward()
        elif event.key() == Qt.Key_L:
            self.seek_forward()
Ejemplo n.º 10
0
class video_playbackwindow(QtWidgets.QMainWindow, Ui_video_playback):
    def __init__(self):
        super().__init__()

        self.setupUi(self)
        self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        self.player.setVideoOutput(self.widget)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.durationChanged.connect(self.durationChanged)

        self.play_button.clicked.connect(self.play)

        self.duration = 0
        self.horizontalSlider.setRange(0, 0)
        self.horizontalSlider.sliderMoved.connect(self.setPosition)

    def start(self, path):
        self.player.setMedia(
            QMediaContent(QUrl.fromLocalFile(os.path.abspath(path))))
        self.player.play()
        #print(self.player.duration()+'/'+self.player.durationChanged())

    def play(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
            self.play_button.setText('Play')
        else:
            self.player.play()
            self.play_button.setText('Pause')

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

    def positionChanged(self, position):
        self.time_status.setText(
            str(datetime.timedelta(seconds=int(position / 1000))) + '/' +
            str(datetime.timedelta(seconds=int(self.duration / 1000))))
        self.horizontalSlider.setValue(position)

    def durationChanged(self, duration):
        self.duration = duration
        self.horizontalSlider.setRange(0, duration)


#
# app = QApplication(sys.argv)
# video_playback=video_playbackwindow()
# video_playback.show()
# video_playback.start('/home/pi/Documents/6/C.mp4')
#
# sys.exit(app.exec_())
Ejemplo n.º 11
0
class AudioPlayBack():
    def __init__(self):
        self.__audioPlayback = QMediaPlayer()
        self.__audioPlayback.setVolume(50)
        self.__audioPlayback.positionChanged.connect(self.onTick)

        pass

    def onTick(self, e=None):
        print(self.__audioPlayback.position(), self.__audioPlayback.state())
        Event.dis(AudioPlaybackEvent.TICK, self.__audioPlayback.position())
        pass

    def load(self, path):
        content = QMediaContent(QUrl(path))
        self.__audioPlayback.setMedia(content)
        self.__audioPlayback.play()
        pass

    def seek(self, position):
        self.__audioPlayback.setPosition(position)
        pass

    def play(self):
        if self.__audioPlayback.state() == QMediaPlayer.PausedState:
            self.__audioPlayback.play()
            pass
        pass

    def pause(self):
        if self.__audioPlayback.state() == QMediaPlayer.PlayingState:
            self.__audioPlayback.pause()
            pass
        pass

    # 0~100
    def setVolume(self, vol):
        self.__audioPlayback.setVolume(vol)
        pass
Ejemplo n.º 12
0
class VideoPlayer(QVideoWidget):
    onVideoStop = FuncDescriptor()
    onVideoStart = FuncDescriptor()
    onVideoPause = FuncDescriptor()

    def __init__(self, parent: QWidget):
        super().__init__(parent=parent)
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setVideoOutput(self)
        self.mediaPlayer.stateChanged.connect(self.onStateChanged)
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self._video_path = None

    @property
    def video_path(self):
        return self._video_path

    @video_path.setter
    def video_path(self, value):
        log.debug(" _video_path set to {}".format(value))
        self._video_path = value
        self.q_url = QUrl.fromLocalFile(self._video_path)
        self.mediaPlayer.setMedia(QMediaContent(self.q_url))

    def showEvent(self, event: QtGui.QShowEvent):
        super().showEvent(event)
        exp_logger.info(f"Playing video: {self.video_path}")
        self.mediaPlayer.play()

    def onStateChanged(self):
        """
        0 - StoppedState
        1 - PlayingState
        2 - PausedState
        """
        state = self.mediaPlayer.state()
        if state == 0:
            self.onVideoStop()
        elif state == 1:
            self.onVideoStart()
        elif state == 2:
            self.onVideoPause()
        else:
            raise ValueError("Unknown state {}".format(state))

    def closeEvent(self, QCloseEvent):
        super().closeEvent(QCloseEvent)
        log.debug("Close {}".format(self))
Ejemplo n.º 13
0
class VideoPlayer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt5 Video Player")

        self.mediaPlayer = QMediaPlayer()
        videoWidget = QVideoWidget()

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

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

        widget = QWidget(self)
        self.setCentralWidget(widget)

        layout = QVBoxLayout()
        layout.addWidget(videoWidget)
        layout.addWidget(self.openButton)
        layout.addWidget(self.playButton)

        widget.setLayout(layout)
        self.mediaPlayer.setVideoOutput(videoWidget)
        print("Done")

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

    def play(self):
        print("Play")
        self.mediaPlayer.play()
        return
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            print("Do")
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()
Ejemplo n.º 14
0
class SoundPlayer:
    def __init__(self, parent):
        self.parent = parent

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

    def play(self, playlists, startRow=0, option=QMediaPlaylist.Sequential):
        if self.player.state() == QMediaPlayer.PausedState:
            self.player.play()
        else:
            self.createPlaylist(playlists, startRow, option)
            self.player.setPlaylist(self.playlist)
            self.playlist.setCurrentIndex(startRow)
            self.player.play()

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

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

    def createPlaylist(self,
                       playlists,
                       startRow=0,
                       option=QMediaPlaylist.Sequential):
        self.playlist.clear()

        for path in playlists:
            url = QUrl.fromLocalFile(path)
            self.playlist.addMedia(QMediaContent(url))

        self.playlist.setPlaybackMode(option)

    def upateVolume(self, vol):
        self.player.setVolume(vol)
Ejemplo n.º 15
0
class MainWindow(QMainWindow):
    directory_path = ""
    video_paths = []
    video_infos = []
    main_width = 1500
    main_height = 800
    key_frame_dir = ""

    def __init__(self):
        super().__init__()
        self.tabs = []
        self.tab_names = []

        self.__initUI()

    def __initUI(self):
        # Create a widget for window contents
        self.central_widget = QWidget(self)
        self.setCentralWidget(self.central_widget)

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

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

        # Create menu bar and add action
        menu_bar = self.menuBar()
        menu = menu_bar.addMenu('&메뉴')
        menu.addAction(open_action)
        menu.addAction(exit_action)

        self.statusBar()
        self.setFrameViewWidget()
        self.setVideoWidget()
        self.setVideoControlWidget()
        self.setTabWidget()
        self.setMainLayout()
        # Set widget to contain window contents
        self.central_widget.setLayout(self.main_layout)
        self.setGeometry(300, 300, self.main_width, self.main_height)
        self.setWindowTitle('Video Previewer')
        self.show()

    def setFrameViewWidget(self):
        self.frame = QLabel(self)
        self.frame.setFrameShape(QFrame.Panel)
        self.frame.setFixedHeight(self.main_height / 2)
        self.frame.setFixedWidth(self.main_width / 3)
        self.frame.setStyleSheet("background: white; border:1px solid gray;")
        self.frame.setAlignment(Qt.AlignCenter)

    def setVideoWidget(self):
        self.videoWidget = QVideoWidget()
        self.videoWidget.setStyleSheet("background: white; border:1px solid rgb(0, 0, 0);")
        self.videoWidget.setFixedWidth(self.main_width / 3)
        self.videoWidget.setFixedHeight(self.main_height / 2)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        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)

    def setVideoControlWidget(self):
        self.play_button = QPushButton()
        self.play_button.setEnabled(False)
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.play_button.clicked.connect(self.play)
        self.play_button.setFixedWidth(50)

        self.position_slider = QSlider(Qt.Horizontal)
        self.position_slider.setRange(0, 0)
        self.position_slider.sliderMoved.connect(self.setPosition)
        self.position_slider.setFixedWidth(self.main_width / 3 - 55)

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

        self.controlLayout = QGridLayout()
        self.controlLayout.setAlignment(Qt.AlignLeft)
        self.controlLayout.setAlignment(Qt.AlignTop)
        self.controlLayout.addWidget(self.videoWidget, 0, 0, 1, 2)
        self.controlLayout.addWidget(self.play_button, 1, 0)
        self.controlLayout.addWidget(self.position_slider, 1, 1)

    def setMainLayout(self):
        self.main_layout = QGridLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.addLayout(self.controlLayout, 1, 0)
        self.main_layout.addWidget(self.frame, 2, 0)
        self.main_layout.addWidget(self.tabWidget, 0, 1, 3, 3)
        # self.main_layout.addWidget(self.errorLabel)

    def setVideoTab(self, row_count):
        column_headers = ['Thumbnail', 'Name', 'Size', 'Created Date', 'Modified Date']
        self.tab_videos = QTableWidget()
        self.tab_videos.resize(290, 290)
        self.tab_videos.setRowCount(row_count)
        self.tab_videos.setColumnCount(5)
        self.tab_videos.setHorizontalHeaderLabels(column_headers)
        self.tabWidget.addTab(self.tab_videos, "Videos")

    def setVideoTabItems(self, videos):
        for video in videos:
            video_info = os.path.join(self.directory_path, video)
            self.video_paths.append(video_info)
            self.video_infos.append([
                "",
                video,
                "%.2f MB" % (os.path.getsize(video_info) / (1024.0 * 1024.0)),
                time.ctime(os.path.getctime(video_info)),
                time.ctime(os.path.getmtime(video_info))
            ])

        for row, video_infos in enumerate(self.video_infos):
            for col, video_info in enumerate(video_infos):
                self.tab_videos.setItem(row, col, QTableWidgetItem(str(video_infos[col])))

        self.tab_videos.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tab_videos.cellClicked.connect(self.videoCellClicked)
        self.tab_videos.cellDoubleClicked.connect(self.videoCellDoubleClicked)

        header = self.tab_videos.horizontalHeader()
        for idx in range(len(videos)):
            header.setSectionResizeMode(idx, QtWidgets.QHeaderView.ResizeToContents)

    @pyqtSlot(int, int)
    def videoCellClicked(self, row, col):
        self.tab_videos.selectRow(row)
        cell = self.tab_videos.item(row, 1)

    @pyqtSlot(int, int)
    def videoCellDoubleClicked(self, row, col):
        self.openFile(self.video_paths[row])
        self.tab_videos.selectRow(row)

    def setFrameTab(self):
        self.tab_keyframes = QListWidget()
        self.tab_keyframes.setViewMode(QListWidget.IconMode)
        self.tab_keyframes.setIconSize(QSize(225, 225))
        self.tab_keyframes.itemDoubleClicked.connect(self.frameCellDoubleClicked)
        self.tabWidget.addTab(self.tab_keyframes, "Key frames")

    def frameCellDoubleClicked(self, item=None):
        self.frame.setStyleSheet("background: black")
        pixmap = QPixmap(os.path.join(self.key_frame_dir, item.text()))
        self.frame.setPixmap(pixmap)

    def setTabWidget(self):
        self.tabWidget = QTabWidget()



    def __openDownloadDirectory(self):
        directory_path = str(QFileDialog.getExistingDirectory(self, "Select Directory"))
        if directory_path:
            self.directory_path = directory_path
            videos = os.listdir(self.directory_path)
            self.setVideoTab(len(videos))
            self.setFrameTab()
            self.setVideoTabItems(videos)

        else :
            print("Info: You didn't select directory. current directory path is \"{}\"".format(self.directory_path))

    def openFile(self, fileName):
        if fileName != '':
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))
            self.play_button.setEnabled(True)

            ffmpeg = FFmpegWrapper()
            ffmpeg.setOptions(video_path=fileName)
            if not os.path.isdir(ffmpeg.getOutputDir()):
                ffmpeg.runFFmpeg()

            keyframelist_file = ffmpeg.getKeyframesPathFile()

            detector = darknetDetectorWrapper()
            detector.setInputPath(input_paths=keyframelist_file)
            detector.setOutputPath(ffmpeg.getOutputDir())
            detector.runDarknetDetector()

            frame_names = self.readFrames(keyframelist_file)

            self.tab_keyframes.clear()
            self.key_frame_dir = frame_names[0].replace(frame_names[0].split("\\")[-1],"")
            for frame_name in frame_names:
                item = QListWidgetItem(QIcon(frame_name), frame_name.split("\\")[-1])
                self.tab_keyframes.addItem(item)

    def readFrames(self, keyframelist_file):
        frame_names = []
        with open(keyframelist_file, 'r') as file:
            for frame in file:
                frame_names.append(frame.split("\n")[0])

        return frame_names

    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.play_button.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.play_button.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPlay))

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

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

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

    def handleError(self):
        self.play_button.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
Ejemplo n.º 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)

        #        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()
Ejemplo n.º 17
0
class VideoPlayerWindow(QMainWindow):
    def __init__(self, input_user):
        super().__init__()
        self.title = input_user + '\'s Work Window'
        self.top = 100
        self.left = 100
        self.width = 500
        self.height = 400
        global result_list1
        result_list1 = list()
        result_list1.append(('user', input_user))
        self.second_window_interface()

    def second_window_interface(self):
        wid = QWidget(self)
        self.setCentralWidget(wid)

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

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

        self.save_result_Button = QPushButton('save result')
        self.save_result_Button.clicked.connect(self.save_result)

        self.positionSlider = QSlider(Qt.Horizontal)

        self.positionSlider.setRange(0, 0)
        self.positionSlider.sliderMoved.connect(self.setPosition)

        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.height, self.width)

        # Create menu bar and add action
        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu('&File')

        new_action = QAction('&Open a video', self)
        new_action.triggered.connect(self.open_file)

        # fileMenu.addAction(newAction)
        file_menu.addAction(new_action)

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

        layout = QVBoxLayout()
        videoWidget = QVideoWidget()
        layout.addWidget(videoWidget)
        layout.addLayout(controlLayout)

        # Set widget to contain window contents
        wid.setLayout(layout)
        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)

        self.show()

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

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

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
            print(self.mediaPlayer.position())
            result_list1.append(self.mediaPlayer.position())

        else:
            self.mediaPlayer.play()

    def save_result(self):
        # print('list: ', result_list1)

        print(result_list1)
        pickle.dump(
            result_list1,
            open(pickle_file_path + str(result_list1[0][1]) + ".p", "wb"))

    def setPosition(self, position):
        self.mediaPlayer.setPosition(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)
        # print(position)

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)
Ejemplo n.º 18
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())
Ejemplo n.º 19
0
class Window(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Kanishka Jain")
        self.setGeometry(350, 100, 700, 500)

        p = self.palette()
        p.setColor(QPalette.Window, Qt.black)
        self.setPalette(p)

        self.init_ui()

        self.show()

    def init_ui(self):

        #create media player object
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        #create videowidget object

        videowidget = QVideoWidget()

        #create open button
        openBtn = QPushButton('Open Video')
        openBtn.clicked.connect(self.open_file)

        #create button for playing
        self.playBtn = QPushButton()
        self.playBtn.setEnabled(False)
        self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playBtn.clicked.connect(self.play_video)

        #create slider
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0, 0)
        self.slider.sliderMoved.connect(self.set_position)

        #create label
        self.label = QLabel()
        self.label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)

        #create hbox layout
        hboxLayout = QHBoxLayout()
        hboxLayout.setContentsMargins(0, 0, 0, 0)

        #set widgets to the hbox layout
        hboxLayout.addWidget(openBtn)
        hboxLayout.addWidget(self.playBtn)
        hboxLayout.addWidget(self.slider)

        #create vbox layout
        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(videowidget)
        vboxLayout.addLayout(hboxLayout)
        vboxLayout.addWidget(self.label)

        self.setLayout(vboxLayout)

        self.mediaPlayer.setVideoOutput(videowidget)

        #media player signals

        self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
        self.mediaPlayer.positionChanged.connect(self.position_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)

    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open Video")

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

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

        else:
            self.mediaPlayer.play()

    def mediastate_changed(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playBtn.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPause))

        else:
            self.playBtn.setIcon(self.style().standardIcon(
                QStyle.SP_MediaPlay))

    def position_changed(self, position):
        self.slider.setValue(position)

    def duration_changed(self, duration):
        self.slider.setRange(0, duration)

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

    def handle_errors(self):
        self.playBtn.setEnabled(False)
        self.label.setText("Error: " + self.mediaPlayer.errorString())
Ejemplo n.º 20
0
class VideoWindow(QMainWindow):
    def __init__(self, parent=None):
        super(VideoWindow, self).__init__(parent)
        self.setWindowTitle("RSL Player")

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

        videoWidget = QVideoWidget()

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        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.errorLabel = QLabel()
        self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Maximum)

        openAction = QAction(QIcon("open.png"), "&Open", self)
        openAction.setShortcut("Ctrl+O")
        openAction.setStatusTip("Open movie")
        openAction.triggered.connect(self.openFile)

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

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu("&File")
        fileMenu.addAction(openAction)
        fileMenu.addAction(exitAction)

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

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

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

        wid.setLayout(layout)

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

        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

    def openFile(self):
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie",
                                                  QDir.homePath())
        fileName = os.path.basename(os.path.realpath(fileName))
        command = "python func.py " + fileName
        ret = os.system(command)
        path = os.path.abspath("data/test_rsl/ds0/result/")
        fileName = path + "/" + fileName + ".avi"
        print(fileName)
        if fileName != "":
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(fileName)))
            self.playButton.setEnabled(True)

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

    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)

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

    def handleError(self):
        self.playButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
Ejemplo n.º 21
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)
Ejemplo n.º 22
0
class Main(QWidget):
    """主窗口。"""
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)
        # 信息。
        self.result = {'uid': 0}
        # 歌单歌曲id。
        self.playurl = {}
        # 搜索歌曲id。
        self.ids = {}
        # 本地音乐地址。
        self.local_url = {}
        # 歌曲图片。
        self.pictures = {}
        # 歌曲列表id们。
        self.playids = {}

        self.setObjectName('Main')
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowTitle('NetEase')
        self.setWindowIcon(QIcon('icons/format.ico'))
        # 功能。
        self.function = api.WebApi()
        # 主页及其他功能。
        self.index = Index(self)
        self.current_list = SongsWindow(self)
        # -------
        # 待改进。
        self.resize(1000, 650)
        # 按钮start.
        self.btn_exit = QPushButton(self)
        self.btn_min = QPushButton(self)
        self.btn_max = QPushButton(self)
        self.btn_login = QPushButton("Unlogin", self)
        self.btn_search = QPushButton(self)
        self.find_music = QPushButton(self)
        self.locale_music = QPushButton(self)
        self.select_path = QPushButton(self)
        self.play = QPushButton(self)
        self.stop = QPushButton(self)
        self.nextSong = QPushButton(self)
        self.beforeSong = QPushButton(self)
        self.pause = QPushButton(self)
        self.btn_list = QPushButton(self)
        self.add_all_song = QPushButton(self)
        self.single = QPushButton(self)
        self.cycle = QPushButton(self)
        self.loop_flags = True
        # 按钮end.
        # -------
        # 标签start.
        self.lbe_pic = QLabel(self)
        self.header_hr = QLabel(self)
        self.header_icon = QLabel(self)
        self.header_text = QLabel(self)
        self.spacing = QLabel(self)
        self.spacing2 = QLabel(self)
        self.spacing3 = QFrame()
        self.spacing4 = QFrame()
        self.songs_list = QLabel(self)
        self.song_pic = QLabel(self)
        self.time1 = QLabel(self)
        self.time2 = QLabel(self)
        self.song_name = QLabel(self)
        # 歌单内的信息。
        self.detail_pic = QLabel(self)
        self.detail_pic.hide()
        self.detail_author = QLabel(self)
        self.detail_author.hide()
        self.detail_tag = QLabel(self)
        self.detail_tag.hide()
        self.detail_name = QLabel(self)
        self.detail_name.hide()
        self.detail_description = QLabel(self)
        self.detail_description.hide()
        # 标签end.
        # -------
        # 输入框start.
        self.search_line = QLineEdit(self)
        # 输入框end.
        # -------
        # 列表框start.
        self.playlist = PlayList(self)
        # 列表框end.
        # -------
        # 表格start.
        self.table = QTableWidget(self)
        self.table.setObjectName("tablelist")
        #   表格连接信号.
        self.table.itemDoubleClicked.connect(self.add_song)
        self.table.itemDoubleClicked.connect(self.play_song)
        self.table.hide()
        # 表格end.
        # -------
        # 滚动条start。
        self.slider = QSlider(self)
        # 滚动条end.
        # -------
        # 播放功能。
        self.player = QMediaPlayer()
        # -------
        # 布局与属性设置。
        self.mainLayout = QGridLayout()
        self.topLayout = QHBoxLayout()
        self.leftLayout = QVBoxLayout()
        self.centerLayout = QHBoxLayout()
        self.rightLayout = QVBoxLayout()
        self.rightLayout1 = QHBoxLayout()
        self.rightLayout2 = QVBoxLayout()
        self.rightLayout21 = QHBoxLayout()
        self.bottomLayout = QHBoxLayout()
        self.bottomLayout1 = QVBoxLayout()
        self.playLayout = QHBoxLayout()
        self.set_buttons()
        self.set_labels()
        self.set_lines()
        self.set_sliders()
        self.set_medias()
        # -------
        # 其他功能。
        self.load_login()
        self.manager = QNetworkAccessManager()
        self.setLayout(self.set_layouts())

    # 登陆部分start.
    def lwindow(self):
        """
            登陆框。
        """
        login = LoginWindow(self)
        login.exec_()

    def load_login(self):
        """
            查看是否已经登陆。
        """
        os.chdir('.' + '/data' + '/cookies')
        filedir = os.listdir('.')
        if filedir:
            try:
                with open(filedir[0], 'r') as f:
                    content = f.readlines()
                    self.result['uid'] = content[1][:-1]
                    # 读入当前用户uid.
                    self.btn_login.setText(content[0][:-1])
                    # 加载昵称。
                    self.btn_login.disconnect()
                    self.btn_login.clicked.connect(self.quit_login)
                    # 改变登陆按钮连接到退出功能。
                    with open(filedir[-1], 'rb') as fi:
                        p3 = QPixmap()
                        p3.loadFromData(QByteArray(fi.read()))
                        self.lbe_pic.setStyleSheet("border: 0px;")
                        # 发现圆角只是边框,图片并不变化。
                        self.lbe_pic.setPixmap(p3.scaled(40, 40))
                    # 加载头像。
                self.btn_login.setToolTip("登出")
            except:
                pass
        else:
            pass
        os.chdir('..')
        os.chdir('..')
        try:
            self.playlist.set_list()
        except:
            pass

    def quit_login(self):
        """
            退出登陆。
        """
        self.set_labels()
        self.lbe_pic.setStyleSheet("")
        self.btn_login.setText("Unlogin")
        self.btn_login.disconnect()
        self.btn_login.clicked.connect(self.lwindow)
        self.playlist.disconnect()
        self.playlist.clear()
        shutil.rmtree('data/cookies')
        os.makedirs('.' + '/data' + '/cookies')
    # 登陆部分end.

    # 内置组件部分start.

    def set_buttons(self):
        """
            全部的按钮组件。
        """
        # 退出。
        self.btn_exit.setObjectName('exit')
        self.btn_exit.setText('×')
        self.btn_exit.clicked.connect(self.close)
        self.btn_exit.setToolTip('退出')
        # 最小化。
        self.btn_min.setObjectName('mini')
        self.btn_min.setText('-')
        self.btn_min.clicked.connect(self.showMinimized)
        self.btn_min.setToolTip('最小化')
        # 最大化。
        self.btn_max.setObjectName('maxi')
        self.btn_max.setText('□')
        self.btn_max.setToolTip('^_^此功能已上火星')
        # 登陆。
        self.btn_login.setObjectName('login')
        self.btn_login.clicked.connect(self.lwindow)
        self.btn_login.setToolTip('登陆')
        # 搜索。
        self.btn_search.setObjectName('searchBtn')
        self.btn_search.resize(48, 48)
        self.btn_search.clicked.connect(self.song_search)
        # 发现音乐。
        self.find_music.setObjectName('find')
        self.find_music.setIcon(QIcon('icons/music.png'))
        self.find_music.setText("发现音乐")
        self.find_music.clicked.connect(self.show_index)
        # 本地音乐。
        self.locale_music.setObjectName('locale')
        self.locale_music.setIcon(QIcon('icons/music.png'))
        self.locale_music.setText("本地音乐")
        self.locale_music.clicked.connect(self.looking_music)
        self.select_path.setObjectName('selection')
        self.select_path.clicked.connect(self.set_path)
        self.select_path.setText("选择目录")
        self.select_path.hide()
        # 播放页。
        self.play.setObjectName('play')
        self.play.setToolTip("播放歌曲")
        self.play.clicked.connect(self.play_song)
        self.stop.setObjectName('stop')
        self.stop.setToolTip("停止播放")
        self.stop.clicked.connect(self.stop_song)
        self.nextSong.setObjectName('next')
        self.nextSong.setToolTip("下一首歌曲")
        self.nextSong.clicked.connect(self.next_song)
        self.beforeSong.setObjectName('before')
        self.beforeSong.setToolTip("上一首歌曲")
        self.beforeSong.clicked.connect(self.before_song)
        self.pause.setObjectName("pause")
        self.pause.setToolTip("暂停播放")
        self.pause.hide()
        self.pause.clicked.connect(self.pause_song)
        self.single.setObjectName('single')
        self.single.setToolTip('单曲循环')
        self.single.clicked.connect(self.set_modles)
        self.single.hide()
        self.cycle.setObjectName('cycle')
        self.cycle.setToolTip('循环播放')
        self.cycle.clicked.connect(self.set_modles)
        # 歌曲列表。
        self.btn_list.setObjectName('songslist')
        self.btn_list.clicked.connect(self.songs_lists)
        # 歌单内功能。
        self.add_all_song.setObjectName("addbutton")
        self.add_all_song.setText("播放全部")
        self.add_all_song.clicked.connect(self.add_all)
        self.add_all_song.hide()

    def set_labels(self):
        """
            全部的标签组件。
        """
        p = QPixmap()
        p.load('icons/unlogin.png')
        p2 = QPixmap()
        p2.load('icons/format_2.png')
        # 头部装饰start。
        self.lbe_pic.setObjectName("headpic")
        self.lbe_pic.setPixmap(p.scaled(40, 40))
        self.header_hr.setObjectName('Headerhr')
        self.header_hr.setText("推荐")
        self.header_icon.setObjectName('HIcon')
        self.header_icon.setPixmap(p2.scaled(50, 50))
        self.header_text.setObjectName('HText')
        self.header_text.setText(" Music")
        # 头部装饰end。
        # 头部竖线装饰start。
        self.spacing.setObjectName('spacing1')
        self.spacing.resize(50, 50)
        self.spacing2.setObjectName('spacing2')
        self.spacing2.resize(50, 50)
        # 头部竖线装饰end。
        self.songs_list.setObjectName("songlist")
        self.songs_list.setText("我的音乐")
        # 歌单标签设置start。
        self.detail_pic.setObjectName("pic")
        self.detail_author.setObjectName("author")
        self.detail_tag.setObjectName("tag")
        self.detail_name.setObjectName("name")
        self.detail_description.setObjectName("description")
        # 歌单标签设置end。
        # 歌曲图片。
        self.song_pic.setObjectName("songpic")
        p3 = QPixmap()
        p3.load('icons/nosong.png')
        self.song_pic.setPixmap(p3)
        # 时间显示组件。
        self.time1.setObjectName("time1")
        self.time1.setText('00:00')
        self.time1.setAlignment(Qt.AlignCenter | Qt.AlignRight | Qt.AlignBottom)
        self.time2.setObjectName("time2")
        self.time2.setText('00:00')
        self.time2.setAlignment(Qt.AlignBottom)
        # 间隔装饰。
        self.spacing3.setFrameShape(QFrame.VLine)
        self.spacing3.setFrameShadow(QFrame.Plain)
        self.spacing3.setLineWidth(2)
        self.spacing4.setFrameShape(QFrame.HLine)
        self.spacing3.setFrameShadow(QFrame.Plain)
        self.spacing3.setLineWidth(2)
        # 歌曲名字。
        self.song_name.setObjectName("songname")
        self.song_name.setAlignment(Qt.AlignCenter)
        self.song_name.setText("~~~还没有歌曲呦~~~")

    def set_lines(self):
        """
            输入框。
        """
        self.search_line.setObjectName('SearchLine')
        self.search_line.setPlaceholderText('搜索音乐。')

    def set_sliders(self):
        """
            滚动组件。
        """
        self.slider.setObjectName("slider")
        self.slider.setOrientation(Qt.Horizontal)
        self.slider.sliderMoved.connect(self.slider_media)
        self.slider.sliderReleased.connect(self.slider_setdone)
    # 内置组件备份end.

    # 歌曲部分start.

    #  框架,播放器及功能的处理。
    def set_tables(self):
        """
            表格呈现歌单详细信息。
        """
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels([' ', '操作', '音乐', '歌手', '专辑', '时长'])
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 设置列宽。
        self.table.setColumnWidth(0, 40)
        self.table.setColumnWidth(1, 40)
        self.table.setColumnWidth(2, 360)
        self.table.setColumnWidth(3, 140)
        self.table.setColumnWidth(4, 140)
        self.table.setColumnWidth(5, 60)
        # 设置充满表宽。
        self.table.horizontalHeader().setStretchLastSection(True)
        # 设置表头亮度。
        self.table.horizontalHeader().setHighlightSections(False)
        # 设置每次选择为一行。
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 设置垂直表头不显示。
        self.table.verticalHeader().setVisible(False)

    def set_medias(self):
        """
            设置播放器。
        """
        self.player.setVolume(100)
        self.player.stateChanged.connect(self.loop)
        self.player.positionChanged.connect(self.set_time)

    def song_search(self):
        """
            搜索功能。
            name: 歌曲名称。
            id: 歌曲id。
            artists: [0][1]['name']歌曲作者可能不止一人,['img1v1Url']作者头像。
            album: ['name']专辑名称。
        """ 
        # 暂时只做一页。翻页属后续功能。
        text = self.search_line.text()
        if text:
            self.set_tables()
            self.hide_index()
            details = self.function.search(text)
            try:
                # 搜到没有的情况。
                songs = details['songs']
            except KeyError:
                self.table.hide()
                self.detail_description.setText('〖很抱歉,木有此歌曲〗')
                return
            songcount = details['songCount']
            if songcount > 100:
                count = 100
            else:
                count = songcount
            self.table.setRowCount(count)
            for i in range(count):
                self.ids[str(i)] = songs[i]['id']
                self.table.setItem(i, 0, QTableWidgetItem(str(i)))

                self.table.setItem(i, 1, QTableWidgetItem(QIcon('icons/playlist.png'), ''))

                self.table.setItem(i, 2, QTableWidgetItem(songs[i]['name']))

                people = ','.join([c['name'] for c in songs[i]['artists']])
                self.table.setItem(i, 3, QTableWidgetItem(people))

                self.table.setItem(i, 4, QTableWidgetItem(songs[i]['album']['name']))

                minuties = songs[i]['duration'] // 60000
                seconds = songs[i]['duration'] // 1000 % 60
                time = QTime(0, minuties, seconds)
                self.table.setItem(i, 5, QTableWidgetItem(time.toString("mm:ss")))
        else:
            return

        # 加载图片。
        pic = QPixmap()
        pic.load('icons/search2.jpg')
        self.detail_pic.setPixmap(pic.scaled(200, 200))
        self.detail_name.setText('遨游在音乐的天空。')
        self.detail_author.setText("It's my sky!")
        self.detail_tag.setText('『Music, music』')
        self.detail_description.setText('〖Search Result〗')

    def show_playlist(self, name):
        """
            显示歌单详细信息。
            trackCount: 总数。
            name: 歌单名称。
            tags: 歌单标签。
            coverImgUrl: 歌单图片。
            creator: ['nickname'] 创建者名字。
            description: 歌单简介。
            tracks: 歌曲总列表[]
            ,['bMusic']['id']歌曲id,['name']歌曲名称
            , ['mp3Url']歌曲地址
            , ['artists'][0]['name']歌曲作者,['id']作者id
            , ['album']['name']专辑名称,['blurPicUrl']图片。
        """
        self.set_tables()
        self.hide_index()
        details = self.function.details_playlist(self.result[name.replace('\n', '')])
        self.table.setRowCount(details['trackCount'])
        # 加载在表格里。
        for i in range(len(details['tracks'])):
            if not details['tracks'][i]['bMusic']['name']:
                self.playurl[str(i)] = details['tracks'][i]['id']
                self.pictures[str(i)] = details['tracks'][i]['album']['blurPicUrl']
            else:
                self.playurl[details['tracks'][i]['bMusic']['name']] = details['tracks'][i]['id']
                self.pictures[details['tracks'][i]['bMusic']['name']] = details['tracks'][i]['album']['blurPicUrl']
            # 设置序号。
            self.table.setItem(i, 0, QTableWidgetItem(str(i)))

            self.table.setItem(i, 1, QTableWidgetItem(QIcon('icons/playlist.png'), ''))

            if not details['tracks'][i]['bMusic']['name']:
                self.table.setItem(i, 2, QTableWidgetItem(str(i)))
            else:
                self.table.setItem(i, 2, QTableWidgetItem(details['tracks'][i]['bMusic']['name']))

            people = ','.join([t['name'] for t in details['tracks'][i]['artists']])
            self.table.setItem(i, 3, QTableWidgetItem(people))

            self.table.setItem(i, 4, QTableWidgetItem(details['tracks'][i]['album']['name']))

            minuties = details['tracks'][i]['bMusic']['playTime'] // 60000
            seconds = details['tracks'][i]['bMusic']['playTime'] // 1000 % 60
            time = QTime(0, minuties, seconds)
            self.table.setItem(i, 5, QTableWidgetItem(time.toString("mm:ss")))
        # 加载歌单图片。
        self.manager.clearAccessCache()
        pic = self.manager.get(QNetworkRequest(QUrl(details['coverImgUrl'])))
        self.manager.finished.connect(lambda: load_pic(pic))

        def load_pic(picture):
            p4 = QPixmap()
            p4.loadFromData(picture.readAll())
            self.detail_pic.setPixmap(p4.scaled(200, 200))
        # 加载歌单名称,创建者,标签,简介。
        self.detail_name.setText('::======>>歌单: ' + details['name'])
        self.detail_author.setText('Creator: ' + details['creator']['nickname'])
        self.detail_tag.setText('『' + str(details['tags'])[1:-1] + '』')
        try:
            self.detail_description.setText('〖' + details['description'] + '〗')
            self.detail_description.setWordWrap(True)
        except TypeError:
            self.detail_description.setText('〖〗')

    #    歌曲组件start。

    def set_song(self, name, author):
        """
            设置歌曲链接连接。
        """
        try:
            self.manager.disconnect()
        except TypeError:
            pass
        self.manager.clearAccessCache()
        try:
            self.player.setMedia(QMediaContent(QUrl(self.function.details_search(self.playids[name][author]))))
            data = self.manager.get(QNetworkRequest(QUrl(self.pictures[name])))
            self.manager.finished.connect(lambda: self.load(data))
        except KeyError:
            self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.playids[name][author])))

    def add_song(self):
        """
            将歌曲加入到播放列表。
        """
        name = self.table.item(self.table.currentRow(), 2).text()
        author = self.table.item(self.table.currentRow(), 3).text()
        times = self.table.item(self.table.currentRow(), 5).text()
        content = author + ' - ' + name + ' - ' + times
        for i in range(self.current_list.count()):
            if self.current_list.item(i).text() == content:
                if self.current_list.currentItem().text() == content:
                    break
                else:
                    self.current_list.setCurrentRow(i)
                    self.set_song(name, author)
                    break
        else:
            self.current_list.addItem(content)
            self.current_list.setCurrentRow(self.current_list.count()-1)
            try:
                self.playids[name]
            except KeyError:
                self.playids[name] = {}
                try:
                    self.playids[name][author] = self.playurl[name]
                except KeyError:
                    self.playids[name][author] = self.ids[str(self.table.currentRow())]
            self.set_song(name, author)
        # 将列表保存到文件夹下。
        with open('data/music/' + content.replace(':', '.'), 'w') as f:
            try:
                f.write(self.pictures[name])
            except KeyError:
                pass

    def add_all(self):
        """
            将表格中所有的歌曲添加到播放列表。
        """
        for i in reversed(range(self.table.rowCount())):
            name = self.table.item(i, 2).text()
            author = self.table.item(i, 3).text()
            times = self.table.item(i, 5).text()
            content = name + ' - ' + author + ' - ' + times
            temp = [self.current_list.item(j).text() for j in range(self.current_list.count())]
            if content in temp:
                pass
            else:
                self.current_list.addItem(content)
                self.playids[name] = {}
                try:
                    self.playids[name][author] = self.playurl[name]
                except KeyError:
                    self.playids[name][author] = self.ids[str(self.table.currentRow())]
            with open('data/music/' + content.replace(':', '.'), 'w') as f:
                try:
                    f.write(self.pictures[name])
                except KeyError:
                    pass
        self.set_song(name, author)
        self.play_song()

    def play_song(self):
        """
            播放组件。
        """
        # BUG: 用isAudio判断是否为有效音频是特么的双击居然显示无效。
        try:
            self.song_name.setText(self.current_list.currentItem().text().split(' - ')[1])
            self.time2.setText(self.current_list.currentItem().text().split(' - ')[2])
            self.player.play()
            self.play.hide()
            self.pause.show()
        except AttributeError:
            return

    def pause_song(self):
        """
            暂停组件。
        """
        self.player.pause()
        self.pause.hide()
        self.play.show()

    def stop_song(self):
        """
            停止组件。
        """
        self.player.stop()
        self.pause.hide()
        self.play.show()

    def next_song(self):
        """
            下一首,若到头了则播放当前。
        """
        try:
            self.manager.disconnect()
        except TypeError:
            pass
        self.manager.clearAccessCache()
        try:
            content = self.current_list.item(self.current_list.currentRow()+1).text().split(' - ')
            self.song_name.setText(content[1])
            self.time2.setText(content[2])
            self.player.setMedia(QMediaContent(QUrl(self.function.details_search(self.playids[content[1]][content[0]]))))
            data = self.manager.get(QNetworkRequest(QUrl(self.pictures[content[1]])))
            self.manager.finished.connect(lambda: self.load(data))
            self.current_list.setCurrentRow(self.current_list.currentRow()+1)
            self.player.play()
        except AttributeError:
            self.player.play()

    def before_song(self):
        """
            前一首,若到头则播放当前。
        """
        try:
            self.manager.disconnect()
        except TypeError:
            pass
        self.manager.clearAccessCache()
        try:
            content = self.current_list.item(self.current_list.currentRow()-1).text().split(' - ')
            self.song_name.setText(content[1])
            self.time2.setText(content[2])
            self.player.setMedia(QMediaContent(QUrl(self.function.details_search(self.playids[content[1]][content[0]]))))
            data = self.manager.get(QNetworkRequest(QUrl(self.pictures[content[1]])))
            self.manager.finished.connect(lambda: self.load(data))
            self.current_list.setCurrentRow(self.current_list.currentRow()-1)
            self.player.play()
        except AttributeError:
            self.player.play()

    #      本地音乐查找start.
    def looking_music(self):
        """本地音乐查找组件。"""
        p = QPixmap()
        p.load('icons/local.jpg')
        self.detail_pic.setPixmap(p.scaled(200, 200))
        self.detail_name.setText("本地音乐")
        self.detail_author.setText("You, You, You")
        self.detail_tag.setText("Your Collection Music")
        self.hide_index()
        self.select_path.show()
        self.set_tables()
        self.locale_show_on_table(os.getcwd() + r"\myMusic")

    def set_path(self):
        file_path = QFileDialog.getExistingDirectory(self, 'Select Folder')
        self.locale_show_on_table(file_path)

    def locale_show_on_table(self, path):
        songs_list = [i for i in os.listdir(path) if i[-3:] == 'mp3']
        print(songs_list)
        self.table.setRowCount(len(songs_list))
        for i in range(len(songs_list)):
            temp = songs_list[i][:-4]
            temp2 = temp.split(' - ')
            self.table.setItem(i, 0, QTableWidgetItem(str(i)))
            self.table.setItem(i, 1, QTableWidgetItem(QIcon('icons/playlist.png'), ''))
            try:
                self.table.setItem(i, 2, QTableWidgetItem(temp2[1]))
                self.table.setItem(i, 3, QTableWidgetItem(temp2[0]))
            except IndexError:
                self.table.setItem(i, 2, QTableWidgetItem(temp))
                self.table.setItem(i, 3, QTableWidgetItem("暂时无法获取"))
                self.table.setItem(i, 4, QTableWidgetItem("暂时无法获取"))
                self.table.setItem(i, 5, QTableWidgetItem("暂时无法获取"))
                self.playids[temp] = {}
                self.playids[temp]["暂时无法获取"] = path + '\\' + songs_list[i]
                continue
            self.table.setItem(i, 4, QTableWidgetItem("暂时无法获取"))
            self.table.setItem(i, 5, QTableWidgetItem("暂时无法获取"))

            self.playids[temp2[1]] = {}
            self.playids[temp2[1]][temp2[0]] = path + '\\' + songs_list[i]
    #     本地音乐查找end.
    #    歌曲组件end.

    #    歌曲图片,时间和滚动条的设置。
    def load(self, data):
        """用于加载选中歌曲的图片。"""
        data = data.readAll()
        p = QPixmap()
        if data:
            p.loadFromData(data)
            self.song_pic.setPixmap(p.scaled(64, 64))
        else:
            p.load('icons/nosong.png')
            self.song_pic.setPixmap(p.scaled(64, 64))

    def set_time(self):
        """
            设置当前时间。
        """
        times = self.player.position() / 1000
        minutes = times // 60
        seconds = times % 60
        time = QTime(0, minutes, seconds)
        self.time1.setText(time.toString("mm:ss"))
        try:
            alltime = float(self.current_list.item(\
                self.current_list.currentRow()).text().split(' - ')[2].replace(':', '.'))
        except (AttributeError, ValueError):
            return
        curtime = float(time.toString('mm.ss'))
        self.slider.setValue((curtime / alltime) * 100)

    def slider_media(self):
        """
            拖动滚动条时时间的改变。基于时间的变化,若无法获取到时间是不变的,且会报ValueError的错误。当然可以随便写个2:00冒充。- -。
        """
        try:
            self.player.positionChanged.disconnect()
        except TypeError:
            pass
        content = self.current_list.item(self.current_list.currentRow()).text().split(' - ')
        alltime = float(content[2].replace(':', '.'))
        trans_alltime = int(alltime) * 60 + (alltime - int(alltime)) * 100
        currentTime = trans_alltime * self.slider.value()
        minuties = currentTime / 100 // 60
        seconds = currentTime / 100 % 60
        time = QTime(0, minuties, seconds)
        self.time1.setText(time.toString("mm:ss"))

    def slider_setdone(self):
        """
            鼠标放开后播放位置。待改进。
        """
        self.player.positionChanged.connect(self.set_time)
        content = self.current_list.item(self.current_list.currentRow()).text().split(' - ')
        alltime = float(content[2].replace(':', '.'))
        trans_alltime = int(alltime) * 60 + (alltime - int(alltime)) * 100
        currentTime = trans_alltime * self.slider.value()
        self.player.setPosition(currentTime * 10)

    #    设置歌曲播放模式。
    def set_modles(self):
        """
            切换图标及将循环标志变false。
        """
        if self.loop_flags:
            self.cycle.hide()
            self.single.show()
            self.loop_flags = False
        else:
            self.single.hide()
            self.cycle.show()
            self.loop_flags = True

    def loop(self):
        """
            设置为循环播放。默认。
        """
        if self.player.position() > 0 and self.player.state() == 0 and self.loop_flags:
            try:
                self.manager.disconnect()
            except TypeError:
                pass
            self.manager.clearAccessCache()
            content = self.current_list.item(self.current_list.currentRow()+1).text().split(' - ')
            self.current_list.setCurrentRow(self.current_list.currentRow()+1)
            try:
                self.player.setMedia(\
                    QMediaContent(QUrl(self.function.details_search(self.playids[content[1]][content[0]]))))
                data = self.manager.get(QNetworkRequest(QUrl(self.pictures[content[1]])))
                self.manager.finished.connect(lambda: self.load(data))
            except KeyError:
                self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.playids[content[1]][content[0]])))

            self.play_song()
        elif self.player.state() == 0:
            self.solo()

    def solo(self):
        """
            设置为单曲。
        """
        self.player.setPosition(0)
        self.play_song()
    # 歌曲部分end.
    # -------
    # 切换页面start。

    def songs_lists(self):
        """
            歌曲列表。
        """
        if self.current_list.flag:
            self.current_list.show()
            self.current_list.flag = False
        else:
            self.current_list.hide()
            self.current_list.flag = True

    def hide_index(self):
        """
            隐藏主页, 显示歌单详细信息。
        """
        self.centerLayout.setStretch(0, 160)
        self.centerLayout.setStretch(1, 1)
        self.centerLayout.setStretch(2, 850)
        self.centerLayout.setStretch(3, 0)
        self.centerLayout.setStretch(4, 0)
        self.index.hide()
        self.select_path.hide()
        self.current_list.hide()
        self.detail_pic.show()
        self.detail_name.show()
        self.detail_author.show()
        self.add_all_song.show()
        self.detail_tag.show()
        self.detail_description.show()
        self.table.show()

    def show_index(self):
        """
            显示主页。
        """
        self.centerLayout.setStretch(0, 160)
        self.centerLayout.setStretch(1, 1)
        self.centerLayout.setStretch(2, 0)
        self.centerLayout.setStretch(3, 850)
        self.centerLayout.setStretch(4, 0)
        self.current_list.hide()
        self.detail_pic.hide()
        self.detail_name.hide()
        self.select_path.hide()
        self.detail_author.hide()
        self.add_all_song.hide()
        self.detail_tag.hide()
        self.detail_description.hide()
        self.table.hide()
        self.index.show()
    # 切换页面end.

    # 设置布局。
    def set_layouts(self):
        """
            布局。
        """
        # 头布局start.
        self.topLayout.setObjectName('Headerhbox')
        self.topLayout.addWidget(self.header_icon)
        self.topLayout.addWidget(self.header_text)
        self.topLayout.addWidget(self.spacing2)
        self.topLayout.addWidget(self.search_line)
        self.topLayout.addWidget(self.btn_search)
        self.topLayout.addStretch(1)
        self.topLayout.addWidget(self.lbe_pic)
        self.topLayout.addWidget(self.btn_login)
        self.topLayout.addWidget(self.spacing)
        self.topLayout.addWidget(self.btn_min)
        self.topLayout.addWidget(self.btn_max)
        self.topLayout.addWidget(self.btn_exit)
        self.topLayout.setSpacing(7)
        # -------
        self.mainLayout.addLayout(self.topLayout, 0, 0, Qt.AlignTop)
        self.mainLayout.addWidget(self.header_hr, 1, 0, Qt.AlignTop)
        # 头布局end.
        # --------
        # 中心布局start.
        #  左部分start.
        self.leftLayout.addWidget(self.find_music)
        self.leftLayout.addWidget(self.locale_music)
        self.leftLayout.addWidget(self.songs_list)
        self.leftLayout.addWidget(self.playlist)
        self.leftLayout.setSpacing(10)
        #  左部分end。
        # -------
        #  右部分start.
        self.rightLayout.addLayout(self.rightLayout1)
        self.rightLayout1.addWidget(self.detail_pic)
        self.rightLayout1.addLayout(self.rightLayout2)
        self.rightLayout1.setStretch(0, 1)
        self.rightLayout1.setStretch(1, 5)
        self.rightLayout21.addWidget(self.detail_name)
        self.rightLayout21.addWidget(self.select_path)
        self.rightLayout21.addStretch(1)
        self.rightLayout2.addLayout(self.rightLayout21)
        self.rightLayout2.addWidget(self.detail_author)
        self.playLayout.addWidget(self.add_all_song)
        self.playLayout.addStretch(1)
        self.rightLayout2.addLayout(self.playLayout)
        self.rightLayout2.addWidget(self.detail_tag)
        self.rightLayout2.addWidget(self.detail_description)
        self.rightLayout.addWidget(self.table)
        self.rightLayout.setStretch(0, 1)
        self.rightLayout.setStretch(1, 2)
        #  右部分end.
        # -------
        self.centerLayout.addLayout(self.leftLayout)
        self.centerLayout.addWidget(self.spacing3)
        self.centerLayout.addLayout(self.rightLayout)
        self.centerLayout.addWidget(self.index)
        self.centerLayout.addWidget(self.current_list)
        self.centerLayout.setStretch(0, 180)
        self.centerLayout.setStretch(1, 1)
        self.centerLayout.setStretch(2, 0)
        self.centerLayout.setStretch(3, 830)
        self.centerLayout.setStretch(4, 0)
        self.mainLayout.addLayout(self.centerLayout, 2, 0, Qt.AlignTop | Qt.AlignLeft)
        # 中心布局end.
        # -------
        # 下部分start.
        self.bottomLayout.addWidget(self.stop)
        self.bottomLayout.addWidget(self.beforeSong)
        self.bottomLayout.addWidget(self.play)
        self.bottomLayout.addWidget(self.pause)
        self.bottomLayout.addWidget(self.nextSong)
        self.bottomLayout.addWidget(self.song_pic)
        self.bottomLayout.addWidget(self.time1)
        self.bottomLayout1.addWidget(self.song_name)
        self.bottomLayout1.addWidget(self.slider)
        self.bottomLayout.addLayout(self.bottomLayout1)
        self.bottomLayout.addWidget(self.time2)
        self.bottomLayout.addWidget(self.cycle)
        self.bottomLayout.addWidget(self.single)
        self.bottomLayout.addWidget(self.btn_list)
        self.bottomLayout.setStretch(6, 1)
        self.bottomLayout.setStretch(7, 6)
        self.bottomLayout.setStretch(8, 1)
        self.mainLayout.addWidget(self.spacing4, 3, 0, Qt.AlignTop)
        self.mainLayout.addLayout(self.bottomLayout, 3, 0, Qt.AlignBottom)
        # self.mainLayout.addWidget(self.current_list, 2, 0, Qt.AlignBottom | Qt.AlignRight)
        # 下部分end.
        self.mainLayout.setRowStretch(1, 1)
        self.mainLayout.setRowStretch(2, 20)
        self.mainLayout.setRowStretch(3, 3)
        return self.mainLayout

    """重写鼠标事件,实现窗口拖动。"""
    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.m_drag = True
            self.m_DragPosition = event.globalPos()-self.pos()
            event.accept()

    def mouseMoveEvent(self, event):
        try:
            if event.buttons() and Qt.LeftButton:
                self.move(event.globalPos()-self.m_DragPosition)
                event.accept()
        except AttributeError:
            pass

    def mouseReleaseEvent(self, event):
        self.m_drag = False

    """按键绑定。。"""
    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Enter-1:
            self.song_search()

    """退出窗口时做的一些事。"""
    def closeEvent(self, event):
        # 退出时保存歌曲列表缓存。
        try:
            with open('data/music/load/playids.pkl', 'wb') as f:
                pickle.dump(self.playids, f)
        except FileNotFoundError:
            pass

    """界面开始前的一些事。"""
    def showEvent(self, event):
        # 查看是否有歌曲缓存。
        try:
            with open('data/music/load/playids.pkl', 'rb') as r:
                self.playids = pickle.load(r)
        # 没有就算了。
        except FileNotFoundError:
            pass
        # 没有也不会报错。
        for i in os.listdir('.' + '/data/music/'):
            if os.path.isfile('.' + '/data/music/' + i):
                self.current_list.addItem(i.replace('.', ':'))
                with open('.' + '/data/music/' + i, 'r') as f:
                    self.pictures[i.split(' - ')[1]] = f.read()
        # 有的话设置为0,防止其他功能报错。
        self.current_list.setCurrentRow(0)
Ejemplo n.º 23
0
class GameWindow(QWidget):
    def __init__(self, parent=None):
        super(GameWindow,self).__init__(parent)

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

        self.mediaPlayer.setVideoOutput(self.videoWidget)

        self.stringLabel = QLabel()
        self.stringLabel.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Maximum)
        self.stringLabel.setTextFormat(Qt.RichText)
        self.stringLabel.setAlignment(Qt.AlignHCenter)

        layout = QVBoxLayout()
        layout.addWidget(self.videoWidget)
        layout.addWidget(self.stringLabel)

        self.setLayout(layout)

        self.mediaPlayer.positionChanged.connect(self.positionChanged)

    def openFile(self, fileName):
        if fileName != '':
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(fileName)))

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

    def playV(self, file, rate, visibility, labelString):
        self.position = 0
        self.startPos = 0
        self.duration = 0
        self.durChanged = False
        self.stopPos = False
        self.openFile(file)
        self.mediaPlayer.setPlaybackRate(rate)
        if visibility:
            self.videoWidget.show()
            self.stringLabel.show()
            self.stringLabel.setText(labelString)
        else:
            self.videoWidget.hide()
            self.stringLabel.show()
            self.stringLabel.setText(labelString)
        self.play()

    def closeEvent(self, event):
        event.ignore()
        self.mediaPlayer.stop()
        super(GameWindow, self).closeEvent(event)

    def positionChanged(self, pos):
        self.position = pos
        if not self.durChanged and self.position > 0:
            self.durationChanged(self.mediaPlayer.duration())
            self.durChanged = True
        if self.startPos > 0 and not self.stopPos and not self.videoWidget.isVisible():
            if self.position > self.startPos + 20000:
                self.play()
                self.stopPos = True

    def durationChanged(self, dur):
        self.duration = dur
        if self.duration > 40000 and not self.videoWidget.isVisible():
            self.startPos = random.randint(5000, self.duration - 25000)
            self.mediaPlayer.setPosition(self.startPos)

    def showPoints(self, pointsString):
        self.videoWidget.hide()
        self.stringLabel.show()
        self.stringLabel.setText(pointsString)
Ejemplo n.º 24
0
class jaabaGUI(QMainWindow):
    """ controller for the blob labeling GUI"""

    def __init__(self,parent=None):
        self.debugMode = True
        self.debugVideoPath = '/Users/071cht/Desktop/Lab/jaabagui/testt.mjpeg.avi'

        QMainWindow.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.installEventFilter(self)
        self.setFocusPolicy(Qt.StrongFocus)
        #add new slider
        # self.positionSlider=QSlider(Qt.Horizontal)
        # self.positionSlider.setGeometry (800,800,100,30)
        # self.positionSlider.setRange(0, 0)
        # self.positionSlider.sliderMoved.connect(self.setPosition)

        #setup Video
        #video player
        self.mediaPlayer1 = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer2 = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer2.setNotifyInterval(10)
        #self.mediaPlayer.metaDataChanged.connect(self.metaDataChanged)
        self.mediaPlayer1.durationChanged.connect(self.durationChanged)
        self.mediaPlayer1.positionChanged.connect(self.positionChanged)
        self.mediaPlayer2.positionChanged.connect(self.positionChanged)
        #self.mediaPlayer2.positionChanged.connect(self.paintEvent)
        

        #visualizetion
        self.scene = QGraphicsScene()
        self.ui.graphicsView.setScene(self.scene)
        #self.scene.setBackgroundBrush(Qt.black)
        self.videoItem1 = QGraphicsVideoItem()
        self.videoItem2 = Video()
        self.scene.addItem(self.videoItem1)
        self.scene.addItem(self.videoItem2)
        self.mediaPlayer1.setVideoOutput(self.videoItem1)
        self.mediaPlayer2.setVideoOutput(self.videoItem2)

       

        #slider bar
        self.ui.horizontalSlider.setRange(0, 0)
        self.ui.horizontalSlider.sliderMoved.connect(self.setPosition)
        # self.ui.horizontalSlider.sliderPressed.connect(self.sliderPressed)

        #draw on video
        self.flyCanvas= TargetView()
        self.scene.addItem(self.flyCanvas)
        #give reference to target view
        self.flyCanvas.setWindowReference(self)

        #lineEdit signals:
        self.ui.lineEdit.returnPressed.connect(self.lineEditChanged)



        #callbacks
        self.ui.actionQuit.triggered.connect(self.quit)
        self.ui.actionLoad_Project.triggered.connect(self.loadVideo)
        self.ui.actionImport_Labels.triggered.connect(self.loadLabels)
        #self.ui.buttonPlay.clicked[bool].connect(self.setToggleText)
        self.ui.buttonPlay.clicked.connect(self.play)
        self.ui.actionSave.triggered.connect(self.saveLabels)
        ## print self.ui.graphicsView.sizeHint()

        #behavior Button
        self.ui.buttonBehavior.clicked.connect(self.behaviorButtonClick)
        self.ui.buttonNone.clicked.connect(self.noneButtonClick)

        #initialization
        self.loaded = False
        self.videoFilename = None
        self.frame_count=None
        self.width=None
        self.height=None
        self.frame_trans=None
        self.previous_frame=0
        self.current_frame=0
        self.behaviorButtonStart = False
        self.noneButtonStart = False
        self.currentFly=1

        #initialize flyInfo
        #self.setCurrentFly(self.currentFly)

        # register flyid changed callback
        self.flyCanvas.onCurrentFlyIdChanged(self.currentFlyIdChangedCallback)
        self.flyCanvas.setCurrentFlyId(self.currentFly)

        # when double click on video, change fly id in target view
        self.videoItem2.onDoubleClick(self.flyCanvas.setCurrentFlyIdByXY)

        ########################
        # DEBUG PART HERE!!!!! #
        ########################
        if (self.debugMode):
            self.debugLoadVideo()

    # add label UI related when load video   
    def showEvent(self, evt):
        super(jaabaGUI, self).showEvent(evt)
        ##### HERE THE WINDOW IS LOADED!!!!!!!!
        # self.loadLabelUI()

    def loadLabelUI(self):
         #labels
        self.labelScene = QGraphicsScene()

        self.ui.graphLabels.setScene(self.labelScene)
        # the size is only accurate after the window fully displayed
        labelUIWidth = self.ui.graphLabels.width()
        labelUIHeight = self.ui.graphLabels.height()-1

        self.labelScene.setSceneRect(0,0,labelUIWidth,labelUIHeight)

        
        self.labelUI = LabelUI()
        # visiableWidth = 850
        # height = 30
        # visiableFrameNum = 850

        self.labelUI.setWidthPerFrame(850.0/850.0)
        # print '850/500',850.0/850.0b
        # print 'length_perframe is ', self.labelUI.widthPerFrame 
        # 850 is the original length of graphLabel
        total_length= self.labelUI.widthPerFrame * self.frame_count
        self.labelUI.setVisiableSize(total_length,30)

        # set start position
        self.labelUI.setPos(labelUIWidth/2,0)


        print 'frame_count is ', self.frame_count
        print 'total length is', total_length
        
        self.labelScene.addItem(self.labelUI)

        # middle line ui
        self.labelUIMiddleLine = LabelUIMiddleLine()
        self.labelScene.addItem(self.labelUIMiddleLine)
        self.labelUIMiddleLine.setPos(labelUIWidth/2,0)
       


        # self.labelUI.setPos(QPointF(-100,0))
        self.writeLog('Label UI loaded')

    def eventFilter(self, obj, event):
  
    	if (event.type() == PyQt5.QtCore.QEvent.KeyPress):
    		# http://qt-project.org/doc/qt-4.8/qt.html#Key-enum
    		key = event.key()
    		
    		if (key == Qt.Key_Up) :
    			curr_frame= int(float(self.ui.lineEdit.text()))
    			curr_frame= curr_frame-30
    			media_position= int(round(curr_frame*self.frame_trans))

    			# print curr_frame, media_position
    			self.mediaPlayer1.setPosition(media_position) 
    			self.mediaPlayer2.setPosition(media_position)

    			# print 'down -30'
    		elif (key == Qt.Key_Right):
    			curr_frame= int(float(self.ui.lineEdit.text()))
    			# print 'right +1'
    			# print curr_frame
    			curr_frame= curr_frame+1
    			media_position= int(round(curr_frame*self.frame_trans))
    			# print 'curr_frame',curr_frame
    			# print 'frame_trans',self.frame_trans
    			# print ' curr_frame*self.frame_trans',curr_frame*self.frame_trans
    			# print 'media_position',media_position

    			# print curr_frame, media_position
    			self.mediaPlayer1.setPosition(media_position) 
    			self.mediaPlayer2.setPosition(media_position)
    			# self.mediaPlayerPositionChanged(media_position)
    		elif (key == Qt.Key_Left):
    			curr_frame= int(float(self.ui.lineEdit.text()))
    			curr_frame= curr_frame-1
    			media_position= int(round(curr_frame*self.frame_trans))
    			self.mediaPlayer1.setPosition(media_position) 
    			self.mediaPlayer2.setPosition(media_position)
    			# print 'left -1'
    		elif (key == Qt.Key_Down):
    			curr_frame= int(float(self.ui.lineEdit.text()))
    			curr_frame= curr_frame+30
    			media_position= int(round(curr_frame*self.frame_trans))
    			self.mediaPlayer1.setPosition(media_position) 
    			self.mediaPlayer2.setPosition(media_position)
    			# print 'up +30'
    		return True

    		

    	return False


    # ###actions starts from here###
    def quit(self):
        QApplication.quit()

    def loadVideo(self):
        
        # print QMediaPlayer.supportedMimeTypes()

        self.writeLog("Loading video...")

        self.videoFilename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0]
        if not self.videoFilename:
            self.writeLog("User cancelled - no video loaded")
            return
        else:
       		cap=cv2.VideoCapture(self.videoFilename)
	    	self.frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT)
	    	self.width=cap.get(3)
	    	self.height=cap.get(4)

	        self.mediaPlayer2.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename )))
	        self.mediaPlayer1.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename )))
	        self.ui.buttonPlay.setEnabled(True)
            # self.mediaPlayer2.setVideoOutput(self.videoItem2)
            # self.mediaPlayer1.setVideoOutput(self.videoItem1)
            # size= self.videoItem2.nativeSize()
            # # print size
            ## print self.mediaPlayer.duration()
          
            ## print self.mediaPlayer.metaData()
        self.writeLog("Video loaded!")

        # init label related ui
        self.loadLabelUI()


    def debugLoadVideo(self):

        self.videoFilename = self.debugVideoPath

        cap=cv2.VideoCapture(self.videoFilename)
        self.frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT)
        self.width=cap.get(3)
        self.height=cap.get(4)

        self.mediaPlayer2.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename )))
        self.mediaPlayer1.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename )))
        self.ui.buttonPlay.setEnabled(True)
        self.writeLog("Video loaded!")

        QTimer.singleShot(1000, self.loadLabelUI)

    def play(self):
    	
        self.videoItem1.setAspectRatioMode(0)
        self.videoItem2.setAspectRatioMode(0)
        self.scene.setSceneRect(0,0,self.ui.graphicsView.width(),self.ui.graphicsView.height())
        self.videoItem1.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height()))
        self.videoItem2.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height()))
        self.videoItem1.setPos(QPointF(0,0))
        self.videoItem2.setPos(QPointF(self.ui.graphicsView.width()/2,0))
        self.flyCanvas.setPos(QPointF(self.ui.graphicsView.width()/2,0))

        # custom function setXYScale
        self.videoItem2.setXYScale(self.width,self.height,self.ui.graphicsView.width()/2,self.ui.graphicsView.height())
        self.flyCanvas.setXYScale(self.width,self.height,self.ui.graphicsView.width()/2,self.ui.graphicsView.height())




        if self.mediaPlayer1.state() == QMediaPlayer.PlayingState:
        	self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPlay))
        	self.ui.buttonPlay.setText("Play")
        	self.mediaPlayer1.pause()
        	self.writeLog("Video paused")
        else: 
        	self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPause))
	        self.ui.buttonPlay.setText("Stop")
	        
	        self.mediaPlayer1.play()
	        self.writeLog("Playing video")

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

    def loadLabels(self):

        self.writeLog("Loading labels from file...")
        self.labelFilename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0]
        self.labelUI.labelData = pickle.load(open(self.labelFilename,"rb"))
        self.writeLog("Label loaded from file:" + self.labelFilename)

    def saveLabels(self):
        # Now it can only save to current file. Will add an poput window to choose path later
        pickle.dump( self.labelUI.labelData, open( "newLabels.p", "wb" ) )
  

    def setPosition(self, position):
    	self.mediaPlayer1.setPosition(position) 
    	self.mediaPlayer2.setPosition(position) 

    # when position of media changed, set slider and text box accordingly.
    def positionChanged(self, position):
        #test change labelui position
        # self.labelUI.startLabel();
        # self.labelUI.update()
        previous_frame=  self.previous_frame
        curr_frame= int(round(position/self.frame_trans))
        self.current_frame=curr_frame
        frame_change= previous_frame-curr_frame
        move_width= frame_change * self.labelUI.widthPerFrame
        self.previous_frame= curr_frame

        self.labelUI.moveBy(move_width,0)

        self.labelUI.setCurrentFrame(curr_frame)
        # enforce labelUI paint once
        self.labelUI.update()
       
        # self.labelUI.setPos(self.labelUI.mapToParent(1,0));
        # self.labelUI.update()

    	# # print 'triggered position'
    	# # print position
    	# # print 'cur position'
    	# # print self.mediaPlayer2.position()
    	self.updateLineEdit(position)
    	self.updateSliderAndGraph(position)
    	
       #  self.ui.horizontalSlider.setValue(position)

       #  if isinstance(self.frame_trans,float):
	      #   # # print type(position),position
	      #   # # print type(self.frame_trans),self.frame_trans 
	      #   # # print position/self.frame_trans
	     	# self.ui.lineEdit.setText(str(int(round(position/self.frame_trans))))
	     	# self.flyCanvas.getFrame(int(round(position/self.frame_trans)))
	     	# self.flyCanvas.isManualCalled = True;
	     	# self.flyCanvas.update()

       #  self.writeLog(str(position))    
       # # self.updateMediaControlUI(position)
       # # self.flyCanvas.update()

    def updateSliderAndGraph(self, position):
    	self.ui.horizontalSlider.setValue(position)
    	if isinstance(self.frame_trans,float):
    		self.flyCanvas.getFrame(int(round(position/self.frame_trans)))
    		self.flyCanvas.isManualCalled = True
    		self.flyCanvas.update()

        #self.writeLog(str(position)) 
    def updateLineEdit(self, position): 
        # # print self.width
        # # print self.height
    	if isinstance(self.frame_trans,float):
	        # # print type(position),position
	        # # print type(self.frame_trans),self.frame_trans 
	        # # print position/self.frame_trans
	     	self.ui.lineEdit.setText(str(int(round(position/self.frame_trans))))

    def durationChanged(self, duration):
	    self.ui.horizontalSlider.setRange(0, duration) 
	    self.frame_trans=self.mediaPlayer1.duration()/self.frame_count
	    ## print self.frame_trans

	#def eventFilter(self,source,event):
		#if (event.type()==PyQt5.QtCore.QEvent.MousePress and source is self.videoItem2):
		# 	pos=event.pos()
		# 	# print('mouse position: (%d,%d)' % (pos.x(),pos.y()))
	 #    return PyQt5.QtGui.QWidget.eventFilter(self, source, event)

    def writeLog(self,text):
        self.ui.log.setText(text)

    # def eventFilter (self.ui.lineEdit,event):
    #     if event.type()==PyQt5.QtCore.QEvent

    def lineEditChanged(self):
    	#set position of media
    	curr_frame= int(float(self.ui.lineEdit.text()))
    	media_position= int(round(curr_frame*self.frame_trans))
    	self.mediaPlayer1.setPosition(media_position) 
    	self.mediaPlayer2.setPosition(media_position)
    	# print 'setPosition'
    	# print media_position
    	# print 'after set'
    	# print self.mediaPlayer2.position()
    	# self.updateSliderAndGraph(media_position)


    def behaviorButtonClick(self):
        # flip flag
        self.behaviorButtonStart = not self.behaviorButtonStart

        # check click to start or stop
        if (self.behaviorButtonStart):
            # start labeling
            self.labelUI.startLabel(self.ui.comboBox.currentIndex(),'',self.current_frame)
            self.writeLog('start labeling')


        else:
            # stop lableing
            self.labelUI.stopLabel()
            self.writeLog('stop labeling')

    def noneButtonClick(self):
           # flip flag
        self.noneButtonStart = not self.noneButtonStart

        # check click to start or stop
        if (self.noneButtonStart):
            # start labeling
            self.labelUI.startLabel(self.ui.comboBox.currentIndex(),'_none',self.current_frame)
            self.writeLog('start labeling')
        else:
            # stop lableing
            self.labelUI.stopLabel()
            self.writeLog('stop labeling')


    # set CurrentFly when fly changed! 
    def setCurrentFly(self,fly):
        self.currentFly = fly
        self.ui.flyInfo.setPlainText('FlyID:' + str(self.currentFly))
        self.flyCanvas.currentFly=fly

    def currentFlyIdChangedCallback(self,fly):
        print 'callback!!!!!';
        self.currentFly = fly
        self.ui.flyInfo.setPlainText('FlyID:' + str(self.currentFly))
Ejemplo n.º 25
0
class Controller:
    def __init__(self, view, log):
        self.log = log
        self.view = view
        self._player = QMediaPlayer()
        self._player.mediaStatusChanged.connect(self._player_status_changed)
        self._player.mediaChanged.connect(self._player_media_changed)
        self._player.currentMediaChanged.connect(self._player_current_media_changed)
        self._player.stateChanged.connect(self._player_state_changed)
        self._player.positionChanged.connect(self._player_position_changed)
        self._player.durationChanged.connect(self._player_duration_changed)
        self._searched_tracks = []
        self.playlists = []
        self.playing_playlist = 0
        self.last_colored_item = None

    def _player_status_changed(self, status):
        self.log.debug('_player_status_changed: %s', str(status))
        if status in [QMediaPlayer.EndOfMedia, QMediaPlayer.InvalidMedia]:
            self.next()

        if status in [QMediaPlayer.EndOfMedia, QMediaPlayer.NoMedia, QMediaPlayer.UnknownMediaStatus,
                      QMediaPlayer.InvalidMedia]:
            self.view.set_title()
        else:
            try:
                pos = self.playlists[self.playing_playlist].active_track
                if pos >= 0:
                    track = self.playlists[self.playing_playlist].tracks[pos]
                    self.view.set_title(track.title)
                self.update_list_position(pos)
            except IndexError:
                self.log.error('Index error in _player_status_changed')

    def _player_media_changed(self, media):
        self.log.debug('_player_media_changed: %s' % str(media))

    def _player_current_media_changed(self, media):
        self.log.debug('_player_current_media_changed: %s' % str(media))

    def _player_state_changed(self, state):
        self.log.debug('_player_state_changed: %s' % str(state))

    def _player_duration_changed(self, duration):
        self.log.debug('_player_duration_changed: %s' % str(duration))
        self.view.track_position.setMaximum(duration)

    def _player_position_changed(self, pos):
        self.view.track_position.setValue(pos)

    def volume_changed(self, value):
        self._player.setVolume(value)

    def update_status(self):
        total_duration = 0
        playlist_index = self.view.tabs.currentIndex()
        for track in self.playlists[playlist_index].tracks:
            total_duration += track.duration
        self.view.playlist_status.setText("%i tracks. Total duration %i:%02i:%02i:%02i" %
                                          (self.playlists[playlist_index].count(), total_duration // 86400,
                                           total_duration // 3600 % 24,
                                           total_duration // 60 % 60, total_duration % 60))

    def add_track(self, track, playlist_index=None):
        if playlist_index is None:
            playlist_index = self.view.tabs.currentIndex()
        self.playlists[playlist_index].add(track)
        self.view.tabs.widget(playlist_index).addItem(track.title)

    def remove_track(self, track_pos=None):
        if track_pos is None:
            track_pos = self.view.tabs.currentWidget().currentRow()
        if track_pos != -1:
            self.view.tabs.currentWidget().takeItem(track_pos)
            playlist_index = self.view.tabs.currentIndex()
            self.playlists[playlist_index].remove(track_pos)
            self.update_status()

    def remove_all_tracks(self):
        playlist_index = self.view.tabs.currentIndex()
        self.playlists[playlist_index].clear()
        self.view.tabs.currentWidget().clear()
        self.update_status()

    def next(self):
        self.log.debug('next')
        # if we close last tab with current track, after it ended, we stop playing
        # todo: need check, that if we close not last tab with current song, we also need stop after song ended
        if self.playing_playlist >= len(self.playlists):
            return
        next_pos = self.playlists[self.playing_playlist].get_next_track(shuffle=bool(self.view.shuffle.checkState()))
        if next_pos is not None:
            self.playlists[self.playing_playlist].active_track = next_pos
            url = self.playlists[self.playing_playlist].tracks[next_pos].stream_url()
            self._player.setMedia(QMediaContent(QUrl(url)))
            self.play()

    def previous(self):
        self.log.debug('previous')
        prev_pos = self.playlists[self.playing_playlist].get_prev_track(shuffle=bool(self.view.shuffle.checkState()))
        if prev_pos is not None:
            self.playlists[self.playing_playlist].active_track = prev_pos
            url = self.playlists[self.playing_playlist].tracks[prev_pos].stream_url()
            self._player.setMedia(QMediaContent(QUrl(url)))
            self.play()

    def play(self):
        self.log.debug('play')
        self._player.play()

    def pause(self):
        self.log.debug('pause')
        self._player.pause()

    def update_list_position(self, position):
        showed_list = self.view.tabs.currentWidget()
        if self.last_colored_item:
            self.last_colored_item.setBackground(QBrush())
        if (position >= 0) and (position <= showed_list.count()):
            self.last_colored_item = showed_list.item(position)
            self.last_colored_item.setBackground(QBrush(QColor('red')))

    def change_track(self):
        self.log.debug('change_track')
        playlist_index = self.view.tabs.currentIndex()
        self.playing_playlist = playlist_index
        position = self.view.tabs.currentWidget().currentRow()
        self.playlists[self.playing_playlist].active_track = position
        self.log.debug('position: %i' % position)
        url = self.playlists[self.playing_playlist].tracks[position].stream_url()
        self._player.setMedia(QMediaContent(QUrl(url)))
        if self._player.state() in [QMediaPlayer.StoppedState, QMediaPlayer.PausedState]:
            self.play()

    def change_track_position(self):
        self._player.setPosition(self.view.track_position.value())

    def remove_dublicates(self):
        selected_playlist = self.view.tabs.currentIndex()
        playlist = self.playlists[selected_playlist]
        processed_ids = []
        position_for_removing = []
        for index in range(len(playlist.tracks)):
            if playlist.tracks[index].id in processed_ids:
                position_for_removing.append(index)
            else:
                processed_ids.append(playlist.tracks[index].id)

        self.log.debug('tracks count: %i' % len(playlist.tracks))
        counter = 0
        for index in reversed(position_for_removing):
            self.log.debug('track index for removing: %i' % index)
            self.remove_track(track_pos=index)
            counter += 1
        self.log.info('Removed %i tracks.' % counter)

    def save_track(self, playlist_pos=None, track_pos=None):
        if track_pos is None:
            track_pos = self.view.tabs.currentWidget().currentRow()
        if playlist_pos is None:
            playlist_pos = self.view.tabs.currentIndex()
        playlist = self.playlists[playlist_pos]
        track = playlist.tracks[track_pos]
        track.save()

    def download_playlist(self):
        selected_playlist = self.view.tabs.currentIndex()
        playlist = self.playlists[selected_playlist]
        for track_pos in range(playlist.count()):
            self.log.info('Saving %i/%s track...' % (track_pos+1, playlist.count()))
            self.save_track(playlist_pos=selected_playlist, track_pos=track_pos)
        self.log.info('Saving done.')

    def load_playlist(self):
        playlist_index = self.view.tabs.currentIndex()
        playlist = self.playlists[playlist_index]
        loaded_playlist = sc_load_playlist(playlist.name)
        if not loaded_playlist:
            self.log.error('Playlist not exists.')
            return
        self.remove_all_tracks()
        for track in loaded_playlist:
            self.add_track(track)
        self.update_status()

    def save_playlist(self):
        playlist_index = self.view.tabs.currentIndex()
        playlist = self.playlists[playlist_index]
        sc_save_playlist(playlist.name, playlist)

    def add_playlist(self, name):
        self.playlists.append(Playlist(name))

    def remove_playlist(self, index):
        self.log.debug('remove playlist with index = %i' % index)
        del (self.playlists[index])

    def search_tracks(self):
        self.view.search_list.clear()
        tracks = sc_search_tracks(self.view.input.text())
        self._searched_tracks = tracks
        total_duration = 0
        for track in self._searched_tracks:
            self.view.search_list.addItem(track.title)
            total_duration += track.duration
        self.view.search_status.setText("Founded %i tracks. Total duration %i:%02i:%02i:%02i" %
                                        (len(self._searched_tracks),
                                         total_duration // 86400000, total_duration // 3600000 % 24,
                                         total_duration // 60000 % 60, total_duration // 1000 % 60))

    def search_similar(self):
        self.view.search_list.clear()
        position = self.view.tabs.currentWidget().currentRow()
        playlist_index = self.view.tabs.currentIndex()
        track = self.playlists[playlist_index].tracks[position]

        related_tracks = track.search_related()
        self._searched_tracks = related_tracks
        total_duration = 0
        for track in self._searched_tracks:
            self.view.search_list.addItem(track.title)
            total_duration += track.duration
        self.view.search_status.setText("Founded %i tracks. Total duration %i:%02i:%02i:%02i" %
                                        (len(self._searched_tracks),
                                         total_duration // 86400000, total_duration // 3600000 % 24,
                                         total_duration // 60000 % 60, total_duration // 1000 % 60))

    def clicked_add_track(self):
        position = self.view.search_list.currentRow()
        self.add_track(self._searched_tracks[position])

    def clicked_add_all_tracks(self):
        for row in range(self.view.search_list.count()):
            self.add_track(self._searched_tracks[row])

    def load_current_state(self):
        if not os.path.isfile('state.pickle'):
            return
        f = open('state.pickle', 'rb')
        state = pickle.load(f)
        f.close()
        loaded_playlists = state['playlists']
        self.log.debug('loaded %i playlists.' % len(loaded_playlists))
        for i in range(len(loaded_playlists) - len(self.playlists)):
            self.view.tab_add()
        self.playlists.clear()
        index = 0
        for playlist in loaded_playlists:
            self.log.debug('playlist: %s, len: %i' % (playlist.name, len(playlist.tracks)))
            self.add_playlist(playlist.name)
            for track in playlist.tracks:
                self.add_track(track, playlist_index=index)
            index += 1
        self.log.debug(len(self.playlists))
        self.log.debug('curent tab: %i' % state['current_playlist'])
        self.view.tabs.setCurrentIndex(state['current_playlist'])
        self.log.debug('volume: %i' % state['volume'])
        self.view.volume.setValue(state['volume'])
        self.view.shuffle.setCheckState(state['shuffle'])

    def save_current_state(self):
        state = dict()
        self.log.debug('playlists count: %i' % len(self.playlists))
        state['playlists'] = self.playlists
        state['current_playlist'] = self.view.tabs.currentIndex()
        state['volume'] = self.view.volume.value()
        state['shuffle'] = self.view.shuffle.checkState()
        f = open('state.pickle', 'wb')
        pickle.dump(state, f)
        f.close()
Ejemplo n.º 26
0
class Window(QtWidgets.QDialog):

    def __init__(self):
        super().__init__()
        self.setGeometry(50, 50, 300, 400)
        self.setWindowTitle("Rolev Player")

# LIBRARY ROOT DIR FOLDER
        self.search_label = QtWidgets.QLabel("Select a music folder:", self)
        self.search_label.setGeometry(10, 5, 205, 10)

        self.btn_root_folder = QtWidgets.QPushButton("Browse", self)
        self.btn_root_folder.setGeometry(215, 20, 75, 25)

        # the text field of the currently selected root directory
        self.dir_text_field = QtWidgets.QLineEdit(self)
        self.dir_text_field.setGeometry(10, 20, 200, 25)

        self.btn_root_folder.clicked.connect(self.on_btn_root_folder)

# CURRENT MEDIA LABEL
        self.current_media_label = QtWidgets.QLabel("Now Playing: ", self)
        self.current_media_label.setGeometry(10, 260, 250, 15)

# CURRENT ALBUM COVER
        self.current_album_cover = QtWidgets.QLabel("Image", self)
        self.current_album_cover.setGeometry(10, 180, 75, 75)
        self.current_album_cover.setScaledContents(True)

# ARTIST DROP BOX
        self.artist_select_label = QtWidgets.QLabel("Artist", self)
        self.artist_select_label.setGeometry(10, 50, 250, 25)

        self.artist_select = QtWidgets.QComboBox(self)
        self.artist_select.setGeometry(10, 70, 250, 25)
        self.artist_select.activated[str].connect(self.on_artist_selection)

# ALBUMS DROP BOX
        self.album_select_label = QtWidgets.QLabel("Albums", self)
        self.album_select_label.setGeometry(10, 90, 250, 25)

        self.album_select = QtWidgets.QComboBox(self)
        self.album_select.setGeometry(10, 110, 250, 25)
        self.album_select.activated[str].connect(self.on_album_selection)

# SONGS DROP BOX
        self.song_select_label = QtWidgets.QLabel("Current Playlist", self)
        self.song_select_label.setGeometry(10, 130, 250, 25)

        self.song_select = QtWidgets.QComboBox(self)
        self.song_select.setGeometry(10, 150, 250, 25)
        self.song_select.activated[str].connect(self.on_song_selection)

# PLAYLIST
        self.playlist = QMediaPlaylist()
        self.playlist.currentIndexChanged.connect(self.meta_data_changed)

# MEDIA PLAYER
        self.player = QMediaPlayer()
        self.player.setPlaylist(self.playlist)
        self.player.playlist().setPlaybackMode(QMediaPlaylist.Loop)
        self.player.setVolume(50)

        self.player.durationChanged.connect(self.on_dur_change)
        self.player.positionChanged.connect(self.on_pos_change)

# VOLUME SLIDER
        self.slider_volume_label = QtWidgets.QLabel("Volume", self)
        self.slider_volume_label.setGeometry(10, 345, 50, 25)

        self.slider_volume = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.slider_volume.setGeometry(60, 350, 130, 20)
        self.slider_volume.setRange(0, 100)
        self.slider_volume.setValue(50)
        self.slider_volume.valueChanged.connect(self.volume_change)

# PROGRESS SLIDER
        self.slider_progress_label = QtWidgets.QLabel("Progress", self)
        self.slider_progress_label.setGeometry(10, 315, 50, 25)

        self.slider_progress = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.slider_progress.setGeometry(60, 320, 130, 20)
        self.slider_progress.sliderMoved.connect(self.progress_change)

# LYRICS SEARCH
        self.btn_lyrics = QtWidgets.QPushButton("Search\n Lyrics", self)
        self.btn_lyrics.setGeometry(220, 310, 70, 80)
        self.btn_lyrics.clicked.connect(self.on_lyrics)

# ALBUM INFO SEARCH
        self.btn_album_info = QtWidgets.QPushButton(
            "Search\nAlbum\nInfo", self)
        self.btn_album_info.setGeometry(105, 180, 75, 75)
        self.btn_album_info.clicked.connect(self.on_album_info)

# ARTIST INFO SEARCH
        self.btn_artist_info = QtWidgets.QPushButton(
            "Search\nArtist\nInfo", self)
        self.btn_artist_info.setGeometry(200, 180, 75, 75)
        self.btn_artist_info.clicked.connect(self.on_artist_info)

# PREV SONG BUTTON
        self.btn_prev = QtWidgets.QPushButton("Prev", self)
        self.btn_prev.setGeometry(10, 280, 75, 25)
        self.btn_prev.clicked.connect(self.on_btn_prev)

# NEXT SONG BUTTON
        self.btn_next = QtWidgets.QPushButton("Next", self)
        self.btn_next.setGeometry(200, 280, 75, 25)
        self.btn_next.clicked.connect(self.on_btn_next)

# PLAY/PAUSE BUTTON
        self.btn_play_pause = QtWidgets.QPushButton("Play", self)
        self.btn_play_pause.setGeometry(105, 280, 75, 30)
        self.btn_play_pause.clicked.connect(self.on_btn_play_pause)

        self.show()

    def on_btn_root_folder(self):
        self.root_dir = QtWidgets.QFileDialog().getExistingDirectory()
        self.dir_text_field.setText(self.root_dir)
        self.library = LibraryLoader.load_music_from_dir(
            self.dir_text_field.text())

        self.artist_select.clear()
        self.album_select.clear()
        self.song_select.clear()
        self.playlist.clear()

        self.btn_play_pause.setText("Play")
        self.artist_select.addItem("All Artists")
        for artist in self.library:
            self.artist_select.addItem(artist)
            for album in self.library[artist]:
                self.album_select.addItem(album)
        self.load_all_songs()

    def on_artist_selection(self):
        current_artist = self.artist_select.currentText()

        self.album_select.clear()
        self.song_select.clear()
        self.playlist.clear()

        self.btn_play_pause.setText("Play")
        self.album_select.addItem("All Albums")
        if current_artist == "All Artists":
            for artist in self.library:
                for album in self.library[artist]:
                    self.album_select.addItem(album)
            self.load_all_songs()
        else:
            for album in self.library[current_artist]:
                self.album_select.addItem(album)
            self.load_all_from_artist(current_artist)

    def load_all_songs(self):
        for artist in self.library:
            for album in self.library[artist]:
                for song in self.library[artist][album]:
                    self.song_select.addItem(song[0])
                    self.playlist.addMedia(
                        QMediaContent(QtCore.QUrl.fromLocalFile(song[1])))

    def load_all_from_artist(self, artist):
        for album in self.library[artist]:
            for song in self.library[artist][album]:
                self.song_select.addItem(song[0])
                self.playlist.addMedia(
                    QMediaContent(QtCore.QUrl.fromLocalFile(song[1])))

    def on_album_selection(self):
        current_artist = self.artist_select.currentText()
        current_album = self.album_select.currentText()
        self.song_select.clear()
        self.playlist.clear()
        self.btn_play_pause.setText("Play")
        if current_album == "All Albums" and current_artist == "All Artists":
            self.load_all_songs()

        elif current_album == "All Albums":
            self.load_all_from_artist(current_artist)

        elif current_artist == "All Artists":
            for artist in self.library:
                for album in self.library[artist]:
                    if album == self.album_select.currentText():
                        for song in self.library[artist][album]:
                            self.song_select.addItem(song[0])
                            self.playlist.addMedia(
                                QMediaContent(
                                    QtCore.QUrl.fromLocalFile(song[1])))
        else:
            for song in self.library[current_artist][current_album]:
                self.song_select.addItem(song[0])
                self.playlist.addMedia(
                    QMediaContent(QtCore.QUrl.fromLocalFile(song[1])))

    def on_song_selection(self):
        index = self.song_select.currentIndex()
        self.playlist.setCurrentIndex(index)

# GETTING THE CURRENT SONG METADATA
    # Returns a SONG OBJECT and not the current song title
    # For the title of the currently playing song use get_current_title()
    def get_current_song(self):
        curr_url = self.playlist.currentMedia().canonicalUrl().toString()[8:]
        if curr_url:
            return LibraryLoader.create_song(curr_url)

    def get_current_artist(self):
        if self.get_current_song() is not None:
            return self.get_current_song().artist

    def get_current_album(self):
        if self.get_current_song() is not None:
            return self.get_current_song().album

    def get_current_path(self):
        if self.get_current_song() is not None:
            return self.get_current_song().path

    def get_current_album_path(self):
        if self.get_current_path() is not None:
            return self.get_current_path().rsplit("/", 1)[0]

    def get_current_title(self):
        if self.get_current_song() is not None:
            return self.get_current_song().name

    def on_lyrics(self):
        if self.get_current_song() is not None:
            curr_artist = self.get_current_artist()
            curr_song = self.get_current_title()

            found_lyrics = RequestLyrics.search_song_lyrics(
                curr_artist, curr_song)
            choice = QtWidgets.QMessageBox.question(
                self, "Lyrics", found_lyrics[0],
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if choice == QtWidgets.QMessageBox.Yes:
                webbrowser.open(found_lyrics[1])
        else:
            QtWidgets.QMessageBox.information(
                self, "Lyrics", "No lyrics found or no media is loaded!")

    def on_album_info(self):
        album = self.get_current_album()
        artist = self.get_current_artist()
        if (album is None) or (artist is None):
            print("Please, load a song first!")
        else:
            artist_info, album_info = AlbumArtwork.album_artist_info(
                artist, album)
            if album_info is not None:
                webbrowser.open(album_info)

    def on_artist_info(self):
        album = self.get_current_album()
        artist = self.get_current_artist()
        if (album is None) or (artist is None):
            print("Please, load a song first!")
        else:
            artist_info, album_info = AlbumArtwork.album_artist_info(
                artist, album)
            if artist_info is not None:
                webbrowser.open(artist_info)

    def on_btn_play_pause(self):
        if self.player.state() in (0, 2):
            self.player.play()
            if self.player.state() == 1:
                self.btn_play_pause.setText("Pause")
        else:
            self.player.pause()
            self.btn_play_pause.setText("Play")

    def on_btn_next(self):
        self.player.playlist().next()

    def on_btn_prev(self):
        self.player.playlist().previous()

    def on_dur_change(self, length):
        self.slider_progress.setMaximum(length)

    def on_pos_change(self, position):
        self.slider_progress.setValue(position)

    def volume_change(self):
        volume = self.slider_volume.value()
        self.player.setVolume(volume)

    def progress_change(self):
        position = self.slider_progress.value()
        self.player.setPosition(position)

    def meta_data_changed(self):

        now_playing = self.get_current_title()
        self.current_media_label.setText("Now Playing: " + now_playing)

        # Updating the currently playing album cover
        curr_album_path = self.get_current_album_path()
        curr_album = self.get_current_album()
        curr_artist = self.get_current_artist()
        cover_url = AlbumArtwork.album_cover(
            curr_album_path, curr_artist, curr_album)

        self.current_album_cover.setPixmap(QPixmap(cover_url))
        Scrobbler.scrobble(self.get_current_artist(), self.get_current_title())
Ejemplo n.º 27
0
class MusicPlayer(QMainWindow):
    """MusicPlayer houses all of elements that directly interact with the main window."""

    def __init__(self, parent=None):
        """Initialize the QMainWindow widget.

        The window title, window icon, and window size are initialized here as well
        as the following widgets: QMediaPlayer, QMediaPlaylist, QMediaContent, QMenuBar,
        QToolBar, QLabel, QPixmap, QSlider, QDockWidget, QListWidget, QWidget, and
        QVBoxLayout. The connect signals for relavant widgets are also initialized.
        """
        super(MusicPlayer, self).__init__(parent)
        self.setWindowTitle('Mosaic')

        window_icon = utilities.resource_filename('mosaic.images', 'icon.png')
        self.setWindowIcon(QIcon(window_icon))
        self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63)

        # Initiates Qt objects to be used by MusicPlayer
        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.playlist_location = defaults.Settings().playlist_path
        self.content = QMediaContent()
        self.menu = self.menuBar()
        self.toolbar = QToolBar()
        self.art = QLabel()
        self.pixmap = QPixmap()
        self.slider = QSlider(Qt.Horizontal)
        self.duration_label = QLabel()
        self.playlist_dock = QDockWidget('Playlist', self)
        self.library_dock = QDockWidget('Media Library', self)
        self.playlist_view = QListWidget()
        self.library_view = library.MediaLibraryView()
        self.library_model = library.MediaLibraryModel()
        self.preferences = configuration.PreferencesDialog()
        self.widget = QWidget()
        self.layout = QVBoxLayout(self.widget)
        self.duration = 0
        self.playlist_dock_state = None
        self.library_dock_state = None

        # Sets QWidget() as the central widget of the main window
        self.setCentralWidget(self.widget)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.art.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)

        # Initiates the playlist dock widget and the library dock widget
        self.addDockWidget(defaults.Settings().dock_position, self.playlist_dock)
        self.playlist_dock.setWidget(self.playlist_view)
        self.playlist_dock.setVisible(defaults.Settings().playlist_on_start)
        self.playlist_dock.setFeatures(QDockWidget.DockWidgetClosable)

        self.addDockWidget(defaults.Settings().dock_position, self.library_dock)
        self.library_dock.setWidget(self.library_view)
        self.library_dock.setVisible(defaults.Settings().media_library_on_start)
        self.library_dock.setFeatures(QDockWidget.DockWidgetClosable)
        self.tabifyDockWidget(self.playlist_dock, self.library_dock)

        # Sets the range of the playback slider and sets the playback mode as looping
        self.slider.setRange(0, self.player.duration() / 1000)
        self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)

        # OSX system menu bar causes conflicts with PyQt5 menu bar
        if sys.platform == 'darwin':
            self.menu.setNativeMenuBar(False)

        # Initiates Settings in the defaults module to give access to settings.toml
        defaults.Settings()

        # Signals that connect to other methods when they're called
        self.player.metaDataChanged.connect(self.display_meta_data)
        self.slider.sliderMoved.connect(self.seek)
        self.player.durationChanged.connect(self.song_duration)
        self.player.positionChanged.connect(self.song_position)
        self.player.stateChanged.connect(self.set_state)
        self.playlist_view.itemActivated.connect(self.activate_playlist_item)
        self.library_view.activated.connect(self.open_media_library)
        self.playlist.currentIndexChanged.connect(self.change_index)
        self.playlist.mediaInserted.connect(self.initialize_playlist)
        self.playlist_dock.visibilityChanged.connect(self.dock_visiblity_change)
        self.library_dock.visibilityChanged.connect(self.dock_visiblity_change)
        self.preferences.dialog_media_library.media_library_line.textChanged.connect(self.change_media_library_path)
        self.preferences.dialog_view_options.dropdown_box.currentIndexChanged.connect(self.change_window_size)
        self.art.mousePressEvent = self.press_playback

        # Creating the menu controls, media controls, and window size of the music player
        self.menu_controls()
        self.media_controls()
        self.load_saved_playlist()

    def menu_controls(self):
        """Initiate the menu bar and add it to the QMainWindow widget."""
        self.file = self.menu.addMenu('File')
        self.edit = self.menu.addMenu('Edit')
        self.playback = self.menu.addMenu('Playback')
        self.view = self.menu.addMenu('View')
        self.help_ = self.menu.addMenu('Help')

        self.file_menu()
        self.edit_menu()
        self.playback_menu()
        self.view_menu()
        self.help_menu()

    def media_controls(self):
        """Create the bottom toolbar and controls used for media playback."""
        self.addToolBar(Qt.BottomToolBarArea, self.toolbar)
        self.toolbar.setMovable(False)

        play_icon = utilities.resource_filename('mosaic.images', 'md_play.png')
        self.play_action = QAction(QIcon(play_icon), 'Play', self)
        self.play_action.triggered.connect(self.player.play)

        stop_icon = utilities.resource_filename('mosaic.images', 'md_stop.png')
        self.stop_action = QAction(QIcon(stop_icon), 'Stop', self)
        self.stop_action.triggered.connect(self.player.stop)

        previous_icon = utilities.resource_filename('mosaic.images', 'md_previous.png')
        self.previous_action = QAction(QIcon(previous_icon), 'Previous', self)
        self.previous_action.triggered.connect(self.previous)

        next_icon = utilities.resource_filename('mosaic.images', 'md_next.png')
        self.next_action = QAction(QIcon(next_icon), 'Next', self)
        self.next_action.triggered.connect(self.playlist.next)

        repeat_icon = utilities.resource_filename('mosaic.images', 'md_repeat_none.png')
        self.repeat_action = QAction(QIcon(repeat_icon), 'Repeat', self)
        self.repeat_action.setShortcut('R')
        self.repeat_action.triggered.connect(self.repeat_song)

        self.toolbar.addAction(self.play_action)
        self.toolbar.addAction(self.stop_action)
        self.toolbar.addAction(self.previous_action)
        self.toolbar.addAction(self.next_action)
        self.toolbar.addAction(self.repeat_action)
        self.toolbar.addWidget(self.slider)
        self.toolbar.addWidget(self.duration_label)

    def file_menu(self):
        """Add a file menu to the menu bar.

        The file menu houses the Open File, Open Multiple Files, Open Playlist,
        Open Directory, and Exit Application menu items.
        """
        self.open_action = QAction('Open File', self)
        self.open_action.setShortcut('O')
        self.open_action.triggered.connect(self.open_file)

        self.open_multiple_files_action = QAction('Open Multiple Files', self)
        self.open_multiple_files_action.setShortcut('M')
        self.open_multiple_files_action.triggered.connect(self.open_multiple_files)

        self.open_playlist_action = QAction('Open Playlist', self)
        self.open_playlist_action.setShortcut('CTRL+P')
        self.open_playlist_action.triggered.connect(self.open_playlist)

        self.open_directory_action = QAction('Open Directory', self)
        self.open_directory_action.setShortcut('D')
        self.open_directory_action.triggered.connect(self.open_directory)

        self.save_playlist_action = QAction('Save Playlist', self)
        self.save_playlist_action.setShortcut('CTRL+S')
        self.save_playlist_action.triggered.connect(self.save_playlist)

        self.exit_action = QAction('Quit', self)
        self.exit_action.setShortcut('CTRL+Q')
        self.exit_action.triggered.connect(self.closeEvent)

        self.file.addAction(self.open_action)
        self.file.addAction(self.open_multiple_files_action)
        self.file.addAction(self.open_playlist_action)
        self.file.addAction(self.open_directory_action)
        self.file.addSeparator()
        self.file.addAction(self.save_playlist_action)
        self.file.addSeparator()
        self.file.addAction(self.exit_action)

    def edit_menu(self):
        """Add an edit menu to the menu bar.

        The edit menu houses the preferences item that opens a preferences dialog
        that allows the user to customize features of the music player.
        """
        self.preferences_action = QAction('Preferences', self)
        self.preferences_action.setShortcut('CTRL+SHIFT+P')
        self.preferences_action.triggered.connect(lambda: self.preferences.exec_())

        self.edit.addAction(self.preferences_action)

    def playback_menu(self):
        """Add a playback menu to the menu bar.

        The playback menu houses
        """
        self.play_playback_action = QAction('Play', self)
        self.play_playback_action.setShortcut('P')
        self.play_playback_action.triggered.connect(self.player.play)

        self.stop_playback_action = QAction('Stop', self)
        self.stop_playback_action.setShortcut('S')
        self.stop_playback_action.triggered.connect(self.player.stop)

        self.previous_playback_action = QAction('Previous', self)
        self.previous_playback_action.setShortcut('B')
        self.previous_playback_action.triggered.connect(self.previous)

        self.next_playback_action = QAction('Next', self)
        self.next_playback_action.setShortcut('N')
        self.next_playback_action.triggered.connect(self.playlist.next)

        self.playback.addAction(self.play_playback_action)
        self.playback.addAction(self.stop_playback_action)
        self.playback.addAction(self.previous_playback_action)
        self.playback.addAction(self.next_playback_action)

    def view_menu(self):
        """Add a view menu to the menu bar.

        The view menu houses the Playlist, Media Library, Minimalist View, and Media
        Information menu items. The Playlist item toggles the playlist dock into and
        out of view. The Media Library items toggles the media library dock into and
        out of view. The Minimalist View item resizes the window and shows only the
        menu bar and player controls. The Media Information item opens a dialog that
        shows information relevant to the currently playing song.
        """
        self.dock_action = self.playlist_dock.toggleViewAction()
        self.dock_action.setShortcut('CTRL+ALT+P')

        self.library_dock_action = self.library_dock.toggleViewAction()
        self.library_dock_action.setShortcut('CTRL+ALT+L')

        self.minimalist_view_action = QAction('Minimalist View', self)
        self.minimalist_view_action.setShortcut('CTRL+ALT+M')
        self.minimalist_view_action.setCheckable(True)
        self.minimalist_view_action.triggered.connect(self.minimalist_view)

        self.view_media_info_action = QAction('Media Information', self)
        self.view_media_info_action.setShortcut('CTRL+SHIFT+M')
        self.view_media_info_action.triggered.connect(self.media_information_dialog)

        self.view.addAction(self.dock_action)
        self.view.addAction(self.library_dock_action)
        self.view.addSeparator()
        self.view.addAction(self.minimalist_view_action)
        self.view.addSeparator()
        self.view.addAction(self.view_media_info_action)

    def help_menu(self):
        """Add a help menu to the menu bar.

        The help menu houses the about dialog that shows the user information
        related to the application.
        """
        self.about_action = QAction('About', self)
        self.about_action.setShortcut('H')
        self.about_action.triggered.connect(lambda: about.AboutDialog().exec_())

        self.help_.addAction(self.about_action)

    def open_file(self):
        """Open the selected file and add it to a new playlist."""
        filename, success = QFileDialog.getOpenFileName(self, 'Open File', '', 'Audio (*.mp3 *.flac)', '', QFileDialog.ReadOnly)

        if success:
            file_info = QFileInfo(filename).fileName()
            playlist_item = QListWidgetItem(file_info)
            self.playlist.clear()
            self.playlist_view.clear()
            self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(filename)))
            self.player.setPlaylist(self.playlist)
            playlist_item.setToolTip(file_info)
            self.playlist_view.addItem(playlist_item)
            self.playlist_view.setCurrentRow(0)
            self.player.play()

    def open_multiple_files(self):
        """Open the selected files and add them to a new playlist."""
        filenames, success = QFileDialog.getOpenFileNames(self, 'Open Multiple Files', '', 'Audio (*.mp3 *.flac)', '', QFileDialog.ReadOnly)

        if success:
            self.playlist.clear()
            self.playlist_view.clear()
            for file in natsort.natsorted(filenames, alg=natsort.ns.PATH):
                file_info = QFileInfo(file).fileName()
                playlist_item = QListWidgetItem(file_info)
                self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(file)))
                self.player.setPlaylist(self.playlist)
                playlist_item.setToolTip(file_info)
                self.playlist_view.addItem(playlist_item)
                self.playlist_view.setCurrentRow(0)
                self.player.play()

    def open_playlist(self):
        """Load an M3U or PLS file into a new playlist."""
        playlist, success = QFileDialog.getOpenFileName(self, 'Open Playlist', '', 'Playlist (*.m3u *.pls)', '', QFileDialog.ReadOnly)

        if success:
            playlist = QUrl.fromLocalFile(playlist)
            self.playlist.clear()
            self.playlist_view.clear()
            self.playlist.load(playlist)
            self.player.setPlaylist(self.playlist)

            for song_index in range(self.playlist.mediaCount()):
                file_info = self.playlist.media(song_index).canonicalUrl().fileName()
                playlist_item = QListWidgetItem(file_info)
                playlist_item.setToolTip(file_info)
                self.playlist_view.addItem(playlist_item)

            self.playlist_view.setCurrentRow(0)
            self.player.play()

    def save_playlist(self):
        """Save the media in the playlist dock as a new M3U playlist."""
        playlist, success = QFileDialog.getSaveFileName(self, 'Save Playlist', '', 'Playlist (*.m3u)', '')
        if success:
            saved_playlist = "{}.m3u" .format(playlist)
            self.playlist.save(QUrl().fromLocalFile(saved_playlist), "m3u")

    def load_saved_playlist(self):
        """Load the saved playlist if user setting permits."""
        saved_playlist = "{}/.m3u" .format(self.playlist_location)
        if os.path.exists(saved_playlist):
            playlist = QUrl().fromLocalFile(saved_playlist)
            self.playlist.load(playlist)
            self.player.setPlaylist(self.playlist)

            for song_index in range(self.playlist.mediaCount()):
                file_info = self.playlist.media(song_index).canonicalUrl().fileName()
                playlist_item = QListWidgetItem(file_info)
                playlist_item.setToolTip(file_info)
                self.playlist_view.addItem(playlist_item)

            self.playlist_view.setCurrentRow(0)

    def open_directory(self):
        """Open the selected directory and add the files within to an empty playlist."""
        directory = QFileDialog.getExistingDirectory(self, 'Open Directory', '', QFileDialog.ReadOnly)

        if directory:
            self.playlist.clear()
            self.playlist_view.clear()
            for dirpath, __, files in os.walk(directory):
                for filename in natsort.natsorted(files, alg=natsort.ns.PATH):
                    file = os.path.join(dirpath, filename)
                    if filename.endswith(('mp3', 'flac')):
                        self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(file)))
                        playlist_item = QListWidgetItem(filename)
                        playlist_item.setToolTip(filename)
                        self.playlist_view.addItem(playlist_item)

            self.player.setPlaylist(self.playlist)
            self.playlist_view.setCurrentRow(0)
            self.player.play()

    def open_media_library(self, index):
        """Open a directory or file from the media library into an empty playlist."""
        self.playlist.clear()
        self.playlist_view.clear()

        if self.library_model.fileName(index).endswith(('mp3', 'flac')):
            self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(self.library_model.filePath(index))))
            self.playlist_view.addItem(self.library_model.fileName(index))

        elif self.library_model.isDir(index):
            directory = self.library_model.filePath(index)
            for dirpath, __, files in os.walk(directory):
                for filename in natsort.natsorted(files, alg=natsort.ns.PATH):
                    file = os.path.join(dirpath, filename)
                    if filename.endswith(('mp3', 'flac')):
                        self.playlist.addMedia(QMediaContent(QUrl().fromLocalFile(file)))
                        playlist_item = QListWidgetItem(filename)
                        playlist_item.setToolTip(filename)
                        self.playlist_view.addItem(playlist_item)

        self.player.setPlaylist(self.playlist)
        self.player.play()

    def display_meta_data(self):
        """Display the current song's metadata in the main window.

        If the current song contains metadata, its cover art is extracted and shown in
        the main window while the track number, artist, album, and track title are shown
        in the window title.
        """
        if self.player.isMetaDataAvailable():
            file_path = self.player.currentMedia().canonicalUrl().toLocalFile()
            (album, artist, title, track_number, *__, artwork) = metadata.metadata(file_path)

            try:
                self.pixmap.loadFromData(artwork)
            except TypeError:
                self.pixmap = QPixmap(artwork)

            meta_data = '{} - {} - {} - {}' .format(track_number, artist, album, title)

            self.setWindowTitle(meta_data)
            self.art.setScaledContents(True)
            self.art.setPixmap(self.pixmap)
            self.layout.addWidget(self.art)

    def initialize_playlist(self, start):
        """Display playlist and reset playback mode when media inserted into playlist."""
        if start == 0:
            if self.library_dock.isVisible():
                self.playlist_dock.setVisible(True)
                self.playlist_dock.show()
                self.playlist_dock.raise_()

            if self.playlist.playbackMode() != QMediaPlaylist.Sequential:
                self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
                repeat_icon = utilities.resource_filename('mosaic.images', 'md_repeat_none.png')
                self.repeat_action.setIcon(QIcon(repeat_icon))

    def press_playback(self, event):
        """Change the playback of the player on cover art mouse event.

        When the cover art is clicked, the player will play the media if the player is
        either paused or stopped. If the media is playing, the media is set
        to pause.
        """
        if event.button() == 1 and configuration.Playback().cover_art_playback.isChecked():
            if (self.player.state() == QMediaPlayer.StoppedState or
                    self.player.state() == QMediaPlayer.PausedState):
                self.player.play()
            elif self.player.state() == QMediaPlayer.PlayingState:
                self.player.pause()

    def seek(self, seconds):
        """Set the position of the song to the position dragged to by the user."""
        self.player.setPosition(seconds * 1000)

    def song_duration(self, duration):
        """Set the slider to the duration of the currently played media."""
        duration /= 1000
        self.duration = duration
        self.slider.setMaximum(duration)

    def song_position(self, progress):
        """Move the horizontal slider in sync with the duration of the song.

        The progress is relayed to update_duration() in order
        to display the time label next to the slider.
        """
        progress /= 1000

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

        self.update_duration(progress)

    def update_duration(self, current_duration):
        """Calculate the time played and the length of the song.

        Both of these times are sent to duration_label() in order to display the
        times on the toolbar.
        """
        duration = self.duration

        if current_duration or duration:
            time_played = QTime((current_duration / 3600) % 60, (current_duration / 60) % 60,
                                (current_duration % 60), (current_duration * 1000) % 1000)
            song_length = QTime((duration / 3600) % 60, (duration / 60) % 60, (duration % 60),
                                (duration * 1000) % 1000)

            if duration > 3600:
                time_format = "hh:mm:ss"
            else:
                time_format = "mm:ss"

            time_display = "{} / {}" .format(time_played.toString(time_format), song_length.toString(time_format))

        else:
            time_display = ""

        self.duration_label.setText(time_display)

    def set_state(self, state):
        """Change the icon in the toolbar in relation to the state of the player.

        The play icon changes to the pause icon when a song is playing and
        the pause icon changes back to the play icon when either paused or
        stopped.
        """
        if self.player.state() == QMediaPlayer.PlayingState:
            pause_icon = utilities.resource_filename('mosaic.images', 'md_pause.png')
            self.play_action.setIcon(QIcon(pause_icon))
            self.play_action.triggered.connect(self.player.pause)

        elif (self.player.state() == QMediaPlayer.PausedState or self.player.state() == QMediaPlayer.StoppedState):
            self.play_action.triggered.connect(self.player.play)
            play_icon = utilities.resource_filename('mosaic.images', 'md_play.png')
            self.play_action.setIcon(QIcon(play_icon))

    def previous(self):
        """Move to the previous song in the playlist.

        Moves to the previous song in the playlist if the current song is less
        than five seconds in. Otherwise, restarts the current song.
        """
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            self.player.setPosition(0)

    def repeat_song(self):
        """Set the current media to repeat and change the repeat icon accordingly.

        There are four playback modes: repeat none, repeat all, repeat once, and shuffle.
        Clicking the repeat button cycles through each playback mode.
        """
        if self.playlist.playbackMode() == QMediaPlaylist.Sequential:
            self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
            repeat_on_icon = utilities.resource_filename('mosaic.images', 'md_repeat_all.png')
            self.repeat_action.setIcon(QIcon(repeat_on_icon))

        elif self.playlist.playbackMode() == QMediaPlaylist.Loop:
            self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)
            repeat_on_icon = utilities.resource_filename('mosaic.images', 'md_repeat_once.png')
            self.repeat_action.setIcon(QIcon(repeat_on_icon))

        elif self.playlist.playbackMode() == QMediaPlaylist.CurrentItemInLoop:
            self.playlist.setPlaybackMode(QMediaPlaylist.Random)
            repeat_icon = utilities.resource_filename('mosaic.images', 'md_shuffle.png')
            self.repeat_action.setIcon(QIcon(repeat_icon))

        elif self.playlist.playbackMode() == QMediaPlaylist.Random:
            self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
            repeat_icon = utilities.resource_filename('mosaic.images', 'md_repeat_none.png')
            self.repeat_action.setIcon(QIcon(repeat_icon))

    def activate_playlist_item(self, item):
        """Set the active media to the playlist item dobule-clicked on by the user."""
        current_index = self.playlist_view.row(item)
        if self.playlist.currentIndex() != current_index:
            self.playlist.setCurrentIndex(current_index)

        if self.player.state() != QMediaPlayer.PlayingState:
            self.player.play()

    def change_index(self, row):
        """Highlight the row in the playlist of the active media."""
        self.playlist_view.setCurrentRow(row)

    def minimalist_view(self):
        """Resize the window to only show the menu bar and audio controls."""
        if self.minimalist_view_action.isChecked():

            if self.playlist_dock.isVisible():
                self.playlist_dock_state = True
            if self.library_dock.isVisible():
                self.library_dock_state = True

            self.library_dock.close()
            self.playlist_dock.close()

            QTimer.singleShot(10, lambda: self.resize(500, 0))

        else:
            self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63)

            if self.library_dock_state:
                self.library_dock.setVisible(True)

            if self.playlist_dock_state:
                self.playlist_dock.setVisible(True)

    def dock_visiblity_change(self, visible):
        """Change the size of the main window when the docks are toggled."""
        if visible and self.playlist_dock.isVisible() and not self.library_dock.isVisible():
            self.resize(defaults.Settings().window_size + self.playlist_dock.width() + 6,
                        self.height())

        elif visible and not self.playlist_dock.isVisible() and self.library_dock.isVisible():
            self.resize(defaults.Settings().window_size + self.library_dock.width() + 6,
                        self.height())

        elif visible and self.playlist_dock.isVisible() and self.library_dock.isVisible():
            self.resize(defaults.Settings().window_size + self.library_dock.width() + 6,
                        self.height())

        elif (not visible and not self.playlist_dock.isVisible() and not
                self.library_dock.isVisible()):
            self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63)

    def media_information_dialog(self):
        """Show a dialog of the current song's metadata."""
        if self.player.isMetaDataAvailable():
            file_path = self.player.currentMedia().canonicalUrl().toLocalFile()
        else:
            file_path = None
        dialog = information.InformationDialog(file_path)
        dialog.exec_()

    def change_window_size(self):
        """Change the window size of the music player."""
        self.playlist_dock.close()
        self.library_dock.close()
        self.resize(defaults.Settings().window_size, defaults.Settings().window_size + 63)

    def change_media_library_path(self, path):
        """Change the media library path to the new path selected in the preferences dialog."""
        self.library_model.setRootPath(path)
        self.library_view.setModel(self.library_model)
        self.library_view.setRootIndex(self.library_model.index(path))

    def closeEvent(self, event):
        """Override the PyQt close event in order to handle save playlist on close."""
        playlist = "{}/.m3u" .format(self.playlist_location)
        if defaults.Settings().save_playlist_on_close:
            self.playlist.save(QUrl().fromLocalFile(playlist), "m3u")
        else:
            if os.path.exists(playlist):
                os.remove(playlist)
        QApplication.quit()
Ejemplo n.º 28
0
class AudioPlayer(QObject):

    songPositionChanged = pyqtSignal(int)
    songDurationChanged = pyqtSignal(int)
    stateChanged = pyqtSignal(int)
    playlistChanged = pyqtSignal(QMediaPlaylist, int)

    currentSongChanged = pyqtSignal(str, str, bytes)
    currentSelectionChanged = pyqtSignal(UUID, int)

    customPlaylistCreated = pyqtSignal(UUID, str)
    libraryPlaylistCreated = pyqtSignal(UUID)

    addedToLibraryPlaylist = pyqtSignal(UUID, list)
    addedToCustomPlaylist = pyqtSignal(UUID, list)

    updatedLibraryPlaylist = pyqtSignal(UUID, list)

    playlistRemoved = pyqtSignal(UUID)

    def __init__(self, volumeLevel=40, playbackMode=QMediaPlaylist.Sequential,
                 parent=None):
        super(AudioPlayer, self).__init__(parent)

        self.__player = QMediaPlayer()
        self.__player.setVolume(volumeLevel)

        self.__player.currentMediaChanged.connect(self._onMediaChanged)
        self.__player.stateChanged.connect(
            lambda state: self.stateChanged.emit(int(state)))
        self.__player.positionChanged.connect(
            lambda x: self.songPositionChanged.emit(x))
        self.__player.durationChanged.connect(
            lambda x: self.songDurationChanged.emit(x))

        self.__playlistManager = PlaylistManger()

        self.__playlistManager.customPlaylistCreated.connect(
            lambda uuid, name: self.customPlaylistCreated.emit(uuid, name))
        self.__playlistManager.libraryPlaylistCreated.connect(
            lambda p: self.libraryPlaylistCreated.emit(p))
        
        self.__playlistManager.currentPlaylistChanged.connect(
            self._onChangedPlaylist)
        self.__playlistManager.currentPlaylistChanged.connect(
            lambda p, i: self.playlistChanged.emit(p, i))

        self.__playlistManager.playlistRemoved.connect(
            lambda uuid: self.playlistRemoved.emit(uuid))

        self.__playlistManager.addedToLibraryPlaylist.connect(
            lambda uuid, l: self.addedToLibraryPlaylist.emit(uuid, l))
        self.__playlistManager.addedToCustomPlaylist.connect(
            lambda uuid, l: self.addedToCustomPlaylist.emit(uuid, l))

        self.__playlistManager.updatedLibraryPlaylist.connect(
            lambda uuid, l: self.updatedLibraryPlaylist.emit(uuid, l))

    def createCustomPlaylist(self, name=None, urls=None):
        self.__playlistManager.createCustomPlaylist(name, urls)

    def createLibraryPlaylist(self, urls=None):
        self.__playlistManager.createLibraryPlaylist(urls)

    def addToLibraryPlaylist(self, url=None):
        self.__playlistManager.addToLibraryPlaylist(url)

    def updateLibraryPlaylist(self, url=None):
        self.__playlistManager.updateLibraryPlaylist(url)

    def renamePlaylist(self, uuid, newName):
        self.__playlistManager.renamePlaylist(uuid, newName)

    def addSongsToCustomPlaylist(self, uuid, urls=[]):
        self.__playlistManager.addSongsToCustomPlaylist(uuid, urls)

    def removeSong(self, uuid, row):
        self.__playlistManager.removeSong(uuid, row)

    def setPlaylist(self, uuid, index=0):
        if (self.__player.playlist() and
                self.__playlistManager.isCurrentPlaylist(uuid)):
            if index == self.__player.playlist().currentIndex():
                if self.__player.state() == QMediaPlayer.PlayingState:
                    self.__player.pause()
                else:
                    self.__player.play()
            else:
                self.__player.playlist().setCurrentIndex(index)
        else:
            self.__playlistManager.setPlaylist(uuid, index)

    def hasLibraryPlaylist(self):
        return self.__playlistManager.hasLibraryPlaylist()

    def removePlaylist(self, uuid):
        self.__playlistManager.removePlaylist(uuid)

    def getCurrentPlaylist(self):
        self.__playlistManager.getCurrentPlaylist()

    def getCurrentQMediaPlaylist(self):
        self.__player.playlist()

    def isPlayerAvailable(self):
        return self.__player.isAvailable()

    def getDuration(self):
        return self.__player.duration()

    def getPlayer(self):
        return self.__player

    def getState(self):
        return self.__player.state()

    def play(self):
        if self.__player.playlist():
            self.__player.play()

    def pause(self):
        if self.__player.playlist():
            self.__player.pause()

    def stop(self):
        if self.__player.playlist():
            self.__player.stop()

    def previousEnhanced(self, sameSongMillis):
        if self.__player.position() <= sameSongMillis:
            self.previous()
        else:
            self.__player.setPosition(0)

    def previous(self):
        if self.__player.playlist():
            self.__player.playlist().previous()

    def next(self):
        if self.__player.playlist():
            self.__player.playlist().next()

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

    def setPosition(self, milliseconds):
        self.__player.setPosition(milliseconds)

    def playlistCurrentIndex(self):
        if self.__player.playlist():
            return self.__player.playlist().currentIndex()

    def setCurrentPlaylistIndex(self, index):
        if self.__player.playlist():
            self.__player.playlist().setCurrentIndex(index)

    def _onChangedPlaylist(self, playlist, index, playIt=False):
        self.__player.setPlaylist(playlist)
        if playlist:
            playlist.setCurrentIndex(index)
        if playIt:
            self.play()

    def _onMediaChanged(self, media):
        if media.isNull() and self.__player.playlist():
            self.__player.playlist().setCurrentIndex(0)
            media = self.__player.playlist().media(0)
        if media.isNull():
            return

        title, artist, cover = self.__playlistManager.getBasicSongInfo(media)

        self.currentSongChanged.emit(title, artist, cover)

        uuid = self.__playlistManager.getCurrentPlaylistUuid()
        index = self.__playlistManager.getCurrentSongIndex()
        self.currentSelectionChanged.emit(uuid, index)

    # def saveSettings(self):
    #     # settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
    #     #                      QCoreApplication.organizationName(),
    #     #                      QCoreApplication.applicationName())

    #     # settings.beginGroup("music_player")

    #     # # if self.__playlistManager.getLibraryPlaylist():
    #     # #     libraryDirectories = self.__playlistManager.getLibraryPlaylist().getDirectories()
    #     # #     settings.beginWriteArray('library_playlist',
    #     # #                              len(libraryDirectories))
    #     # #     for index, value in enumerate(libraryDirectories):
    #     # #         settings.setArrayIndex(index)
    #     # #         settings.setValue("url", value)
    #     # #     settings.endArray()

    #     # customPlaylists = self.__playlistManager.getCustomPlaylists()
    #     # settings.beginWriteArray('custom_playlists',
    #     #                          len(customPlaylists))
    #     # for index, value in enumerate(customPlaylists):
    #     #     settings.setArrayIndex(index)
    #     #     playlistName = settings.value('name', value.getName())
    #     #     playlistUrls = value.getAddedSongUrls()
    #     #     settings.beginWriteArray(playlistName,
    #     #                              len(playlistUrls))
    #     #     for i, v in enumerate(playlistUrls):
    #     #         settings.setArrayIndex(i)
    #     #         settings.setValue("url", v)
    #     #     settings.endArray()
    #     # settings.endArray()

    #     # settings.endGroup()
    #     # if self.__playlistManager.getLibraryPlaylist():
    #     #     libraryDirectories = self.__playlistManager.getLibraryPlaylist().getDirectories()
    #     #     settings.beginWriteArray('library_playlist',
    #     #                              len(libraryDirectories))
    #     #     for index, value in enumerate(libraryDirectories):
    #     #         settings.setArrayIndex(index)
    #     #         settings.setValue("url", value)
    #     #     settings.endArray()

    #     customPlaylists = self.__playlistManager.getCustomPlaylists()
    #     for playlist in customPlaylists:
    #         playlistName = playlist.getName()
    #         for url in playlist:
    #             pass

    # def restoreSettings(self):
    #     settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
    #                          QCoreApplication.organizationName(),
    #                          QCoreApplication.applicationName())

    #     settings.beginGroup("music_player")

    #     # size = settings.beginReadArray('library_playlist')
    #     # libraryDirectories = []
    #     # for i in range(size):
    #     #     settings.setArrayIndex(i)
    #     #     libraryDirectories.append(settings.value("url"))
    #     # settings.endArray()

    #     customPlaylists = {}
    #     size = settings.beginReadArray('custom_playlists')
    #     for i in range(size):
    #         urls = []
    #         settings.setArrayIndex(i)
    #         playlistName = settings.value('name')
    #         print(playlistName)
    #         size2 = settings.beginReadArray(playlistName)
    #         for j in range(size2):
    #             settings.setArrayIndex(j)
    #             url = settings.value("url")
    #             urls.append(url)
    #         settings.endArray()
    #         customPlaylists[playlistName] = urls
    #     settings.endArray()

    #     settings.endGroup()

    #     print('-------')
    #     print(customPlaylists)





        # settings = QSettings(QCoreApplication.organizationName(),
        #                      QCoreApplication.applicationName())
        # settings.beginGroup("music_player")

        # size = settings.beginReadArray('library_playlist')
        # if not size == 0:
        #     for i in range(0, size):
        #         settings.setArrayIndex(i)
        #         url = settings.value("url")
        # settings.endArray()

        # if url:
        #     from audio.playlist_models import DirectoryPlaylist

        #     playlist = DirectoryPlaylist()
        #     playlist.add_directory(url)
        #     self.addAndSetPlaylist(playlist, 2)

        # settings.endGroup()
        pass
class VideoPlayer(QWidget):
    """
    Arguments
    ---------
    parent: QWidget, the parent widget of VideoPlayer
    display_status: bool, default False, will show the status of the media player in the gui
    """

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

        self.display_status = display_status

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

        self.videoItem = QGraphicsVideoItem()

        scene = QGraphicsScene(self)
        graphicsView = QGraphicsView(scene)

        scene.addItem(self.videoItem)

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        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)
        
        if self.display_status:
            self.status_mapping = {
                QMediaPlayer.UnknownMediaStatus: "UnknownMediaStatus",
                QMediaPlayer.NoMedia: "NoMedia",
                QMediaPlayer.LoadingMedia: "LoadingMedia",
                QMediaPlayer.LoadedMedia: "LoadedMedia",
                QMediaPlayer.StalledMedia: "StalledMedia", 
                QMediaPlayer.BufferingMedia: "BufferingMedia",
                QMediaPlayer.BufferedMedia: "BufferedMedia",
                QMediaPlayer.EndOfMedia: "EndOfMedia",
                QMediaPlayer.InvalidMedia: "InvalidMedia"
            }
            self.statusText = QPlainTextEdit()
            self.statusText.setReadOnly(True)
            self.statusText.setFixedHeight(25)
            self.statusText.setFixedWidth(150)
            self.mediaPlayer.mediaStatusChanged.connect(self.mediaStatusChanged)

        controlLayout = QHBoxLayout()
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.addWidget(self.playButton)
        controlLayout.addWidget(self.positionSlider)
        if self.display_status:
            controlLayout.addWidget(self.statusText)

        layout = QVBoxLayout()
        layout.addWidget(graphicsView)
        layout.addLayout(controlLayout)
        self.setFixedWidth(WIDTH + WIGGLE)

        self.setLayout(layout)

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

    def openFile(self, fileName):
        if fileName != '' or fileName is not None:
            self.mediaPlayer.setMedia(
                    QMediaContent(QUrl.fromLocalFile(fileName)))

            # set resolution
            res_orig = get_video_resolution(fileName)
            self.aspect_ratio = float(res_orig[0]) / res_orig[1]
            self.videoItem.setSize(QSizeF(WIDTH,
                                          WIDTH / self.aspect_ratio))
            self.setFixedHeight(WIDTH / self.aspect_ratio + 2*WIGGLE)

            self.playButton.setEnabled(True)

            # trick to show screenshot of the first frame of video
            self.mediaPlayer.play()
            self.mediaPlayer.pause()

    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 mediaStatusChanged(self, status):
        self.statusText.setPlaceholderText(self.status_mapping[status])

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

        # if position slider has reached the end, let's stop the video
        if self.positionSlider.value() >= self.positionSlider.maximum() - 1:
            self.mediaPlayer.stop()

            # play/pause hack to show the first frame of video
            self.mediaPlayer.play()
            self.mediaPlayer.pause()

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

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)
Ejemplo n.º 30
0
class VideoPlayer(QWidget):
    def __init__(self, parent=None):
        super(VideoPlayer, self).__init__(parent)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        #self.mediaPlayer.setMinmumSize(QtCore.QSize(445, 225))

        btnSize = QSize(16, 16)
        videoWidget = QVideoWidget()
        videoWidget.setMinimumSize(QtCore.QSize(445, 225))

        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.setMinmumSize(QtCore.QSize(445, 225))
        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")

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

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

    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)

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

    def handleError(self):
        self.playButton.setEnabled(False)
        self.statusBar.showMessage("Error: " + self.mediaPlayer.errorString())
class ApplicationWindow(QMainWindow):
    ## Accessing files in Processed Stuff ##
    QDir.setCurrent(QCoreApplication.applicationDirPath())
    processedVideoPath = QDir.currentPath() + "/ProcessedStuff/horses_1_predicted.mp4";
    textFilePath = QDir.currentPath() + "/ProcessedStuff/labels_example.txt";
    
    # Environmental Variable
    # os.environ['PYTHONPATH'] = "$(pwd)/detection:$(pwd)/detection/slim"
    # subprocess.check_call(['sqsub', '-np', sys.argv[1], 'application.py'],
    #                   env=dict(os.environ, SQSUB_VAR="visible in this subprocess"))

    ## Important variables ##
    videoLoaded = False
    fileReceived = False
    playing = False
    fileName = None
    labels = []
    nextLine = 0

    def __init__(self):
        # Create the Qt5 application backend
        super(ApplicationWindow, self).__init__()

        # Load in and display the UI
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        ## CONNECT EVENTS (like button presses) to functions ##
        self.ui.button_play_pause.clicked.connect(self.playPauseButtonClicked)
        self.ui.button_load.clicked.connect(self.loadButtonClicked)
        self.ui.button_track.clicked.connect(self.trackButtonClicked)

        # Configure the original video widget
        self.original_video_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.original_video_player.durationChanged.connect(self.durationChanged)
        self.original_video_player.setVideoOutput(self.ui.original_video_widget)

        # Configure the processed video widget
        self.video_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.video_player.setNotifyInterval(30)
        self.video_player.durationChanged.connect(self.durationChanged)
        self.video_player.positionChanged.connect(self.positionChanged)
        self.video_player.stateChanged.connect(self.stopped)
        self.video_player.setVideoOutput(self.ui.video_widget)

        # Configure the video slider
        self.ui.video_slider.sliderPressed.connect(self.sliderPressed)
        self.ui.video_slider.sliderReleased.connect(self.sliderReleased)

        # Update states
        self.updateStates()

    ##  CALLBACK FUNCTIONS ##
    def playPauseButtonClicked(self):
        if self.playing:
            print("Pause!")
            self.pause()
        else:
            print("Play!")
            self.play()

    def saveButtonClicked(self):
        print("Save!")

    def loadButtonClicked(self):
        print("Load!")
        # fileName, _ = QFileDialog.getOpenFileName(
        #     self,
        #     "Choose a video",
        #     QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation),
        #     "Vide files (*mp4 *mp3)")
        # file = open("ProcessedStuff/labels_example.txt","w") 
        # file.write("labels = []\n")
        # file.close()
        fileName, _ = QFileDialog.getOpenFileName(self, "Open Files")

        if fileName != "":
            self.ui.file_info.setText(fileName)
            print("Video filepath: " + fileName)
            self.fileName = fileName
            self.fileReceived = True
            self.nextLine = 0
            self.updateStates()

    def trackButtonClicked(self):
        print("Track!")

        # Do processing and call following method when completed #
        detection.detection_code(self.fileName)
        self.processingFinished()

    def sliderReleased(self):
        newPosition = self.ui.video_slider.value()
        self.setPosition(newPosition)

    def sliderPressed(self):
        self.pause()

    def durationChanged(self):
        self.videoLoaded = True
        self.updateStates()
        self.ui.video_slider.setMaximum(self.video_player.duration())

    def positionChanged(self):
        if not self.playing:
            return
        position = self.video_player.position()
        # Update video progress bar
        self.ui.video_slider.setValue(position)
        # Update information label
        self.updateLabel(position)

    def stopped(self):
        if self.video_player.state() == QMediaPlayer.StoppedState:
            self.playing = False
            self.ui.label_info.setText("")

    ## Helper Functions ##
    def play(self):
        self.original_video_player.play()
        self.video_player.play()
        self.playing = True

    def pause(self):
        self.playing = False
        self.original_video_player.pause()
        self.video_player.pause()

    def setPosition(self, position):
        self.resetNextLine(position)
        self.updateLabel(position)
        self.original_video_player.setPosition(position)
        self.video_player.setPosition(position)
        self.play()

    def updateStates(self):
        self.ui.button_play_pause.setEnabled(self.videoLoaded)
        self.ui.video_slider.setEnabled(self.videoLoaded)
        self.ui.button_track.setEnabled(self.fileReceived and not self.playing)

    def processingFinished(self):
        print("Text file location: " + self.textFilePath)
        file = open(self.textFilePath, "r")
        self.labels = [line.split(',') for line in file]
        file.close()
        print(self.processedVideoPath)
        self.video_player.setMedia(QMediaContent(QUrl.fromLocalFile(self.processedVideoPath)))
        self.original_video_player.setMedia(QMediaContent(QUrl.fromLocalFile(self.fileName)))
        self.play()

    # When the user changes the slider the next line changes
    def resetNextLine(self, position):
        while (position < int(self.labels[self.nextLine][0])):
            self.nextLine -= 1
            if (self.nextLine <= 0):
                break
        if self.nextLine+1<=len(self.labels)-1:
            while (position >= int(self.labels[self.nextLine+1][0])):
                self.nextLine += 1
                if (self.nextLine >= len(self.labels)-1):
                    break

    def updateLabel(self, position):
        if position >= int(self.labels[self.nextLine][0]):
            label = self.labels[self.nextLine]
            messageStr = "Count: " + label[1]
            for i in range(2,len(label),2):
                messageStr += ("\n%s. %s %s" % (i-int(i/2),label[i],label[i+1]))
            self.ui.label_info.setText(messageStr)
            if self.nextLine < len(self.labels)-1:
                self.nextLine += 1
Ejemplo n.º 32
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))
Ejemplo n.º 33
0
class VideoPlayer(QWidget):

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

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

        self.videoItem = QGraphicsVideoItem()
        self.videoItem.setSize(QSizeF(640, 480))

        scene = QGraphicsScene(self)
        graphicsView = QGraphicsView(scene)

        scene.addItem(self.videoItem)

        rotateSlider = QSlider(Qt.Horizontal)
        rotateSlider.setRange(-180,  180)
        rotateSlider.setValue(0)
        rotateSlider.valueChanged.connect(self.rotateVideo)

        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.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.sliderMoved.connect(self.setPosition)

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

        layout = QVBoxLayout()
        layout.addWidget(graphicsView)
        layout.addWidget(rotateSlider)
        layout.addLayout(controlLayout)

        self.setLayout(layout)

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

    def sizeHint(self):
        return QSize(800, 600)

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

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

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        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)

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

    def rotateVideo(self, angle):
        x = self.videoItem.boundingRect().width() / 2.0
        y = self.videoItem.boundingRect().height() / 2.0

        self.videoItem.setTransform(
                QTransform().translate(x, y).rotate(angle).translate(-x, -y))
Ejemplo n.º 34
0
class PlaybackPanel(SpecialLabel):
    desktop_lyric_state_changed_signal = pyqtSignal(bool)
    playmode_changed_signal = pyqtSignal(int, int)
    media_player_notify_signal = pyqtSignal(int)
    muted_changed_signal = pyqtSignal(int)
    mark_favorite_completed_signal = pyqtSignal()
    current_media_changed_signal = pyqtSignal()
    music_ended_signal = pyqtSignal()
    update_window_lyric_signal = pyqtSignal(str, str)
    show_artist_info_signal = pyqtSignal(str)
    dont_hide_main_window_signal = pyqtSignal()

    def __init__(self, parent=None):
        super(PlaybackPanel, self).__init__(parent)
        self.initial_mediaplayer()
        self.create_actions()
        self.setup_ui()
        self.create_connections()
        self.initial_params()

    def create_connections(self):
        self.artistHeadLabel.clicked.connect(self.show_artist_info)
        self.desktopLyric.hide_desktop_lyric_signal.connect(self.desktop_lyric_closed)
        self.seekSlider.valueChanged.connect(self.slider_value_changed)
        self.seekSlider.sliderPressed.connect(self.slider_pressed)
        self.seekSlider.sliderReleased.connect(self.seek)
        self.mediaPlayer.positionChanged.connect(self.tick)
        self.mediaPlayer.mutedChanged.connect(self.muted_changed_signal.emit)
        self.mediaPlayer.stateChanged.connect(self.state_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)
        self.mediaPlayer.mediaStatusChanged.connect(self.media_status_changed)
        self.mediaPlayer.currentMediaChanged.connect(self.current_media_changed)

    def initial_mediaplayer(self):
        self.mediaPlayer = QMediaPlayer()
        self.mediaPlayer.setNotifyInterval(500)
        self.set_volume(globalSettings.Volume)

    def initial_params(self):
        self.playlist = None
        self.artistName = "Zheng-Yejian"
        self.clickPlayFlag = False  # 用来标志一首歌是否是主动点击选中的
        self.timerFlag = False
        self.timeStart = 0
        self.timeSpan = 0
        self.sourcePath = ""
        self.errorType = Configures.NoError
        self.currentSourceRow = -1
        self.nearPlayedSongs = []
        self.downloadDir = globalSettings.DownloadfilesPath
        self.songinfosManager = SonginfosManager()
        self.totalTime = Configures.ZeroTime
        self.playmode = Configures.PlaymodeRandom  # 播放模式指示器
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistFavorite)
        self.lovedSongs = playlistTemp.get_titles()

    def set_playlist(self, playlist):
        self.playlist = playlist
        self.currentSourceRow = self.playlist.get_current_row()

    def create_actions(self):
        self.nextAction = QAction(QIcon(IconsHub.ControlNext), "下一首", self, enabled=True, triggered=self.next_song)

        self.playAction = QAction(QIcon(IconsHub.ControlPlay), "播放/暂停", self, enabled=True, triggered=self.play_music)

        self.previousAction = QAction(
            QIcon(IconsHub.ControlPrevious), "上一首", self, enabled=True, triggered=self.previous_song
        )

        self.stopAction = QAction(
            QIcon(IconsHub.ControlStop), "停止", self, enabled=True, triggered=self.stop_music_but_timing
        )

    def get_play_button_action(self):
        return self.playAction

    def get_previous_button_action(self):
        return self.previousAction

    def get_next_button_action(self):
        return self.nextAction

    def get_stop_button_action(self):
        return self.stopAction

    def set_download_dir(self, dir):
        self.downloadDir = dir

    def get_loved_songs(self):
        return self.lovedSongs

    def get_songinfos_manager(self):
        return self.songinfosManager

    def setup_ui(self):
        self.setFixedHeight(50)
        # 桌面歌词标签
        self.desktopLyric = desktop_lyric.DesktopLyric()
        self.desktopLyric.set_color(globalSettings.DesktoplyricColors)
        # 3个标签
        self.artistHeadLabel = LabelButton()
        self.artistHeadLabel.setToolTip(self.tr("查看歌手信息"))
        self.artistHeadLabel.setFixedSize(QSize(42, 42))
        self.artistHeadLabel.setScaledContents(True)
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))

        self.musicTitleLabel = NewLabel()
        self.musicTitleLabel.setObjectName("musicTitleLabel")
        self.musicTitleLabel.setFixedSize(QSize(370, 20))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.timeLabel = QLabel("00:00/00:00")
        self.timeLabel.setObjectName("timeLabel")
        self.timeLabel.setFixedHeight(20)
        self.timeLabel.setAlignment(Qt.AlignRight and Qt.AlignVCenter)

        # 五个基本按键
        self.playmodeButton = QToolButton(clicked=self.change_playmode)
        self.playmodeButton.setFocusPolicy(Qt.NoFocus)

        self.playmodeButton.setIcon(QIcon(IconsHub.PlaymodeRandom))
        self.playmodeButton.setIconSize(QSize(25, 25))
        self.playmodeButton.setToolTip("随机播放")

        self.favoriteButton = QToolButton(clicked=self.mark_as_favorite)
        self.favoriteButton.setFocusPolicy(Qt.NoFocus)
        self.favoriteButton.setToolTip("收藏")
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setIconSize(QSize(20, 20))

        self.previousButton = QToolButton()
        self.previousButton.setFocusPolicy(Qt.NoFocus)
        self.previousButton.setIconSize(QSize(40, 40))
        self.previousButton.setShortcut(QKeySequence("Ctrl + Left"))
        self.previousButton.setDefaultAction(self.previousAction)

        self.playButton = QToolButton()
        self.playButton.setFocusPolicy(Qt.NoFocus)
        self.playButton.setIconSize(QSize(40, 40))
        self.playButton.setShortcut(QKeySequence("Ctrl + Down"))
        self.playButton.setDefaultAction(self.playAction)

        self.nextButton = QToolButton()
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setIconSize(QSize(40, 40))
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setShortcut(QKeySequence("Ctrl + Right"))
        self.nextButton.setDefaultAction(self.nextAction)

        self.desktopLyricButton = QToolButton(clicked=self.show_desktop_lyric)
        self.desktopLyricButton.setToolTip(self.tr("桌面歌词"))
        self.desktopLyricButton.setFocusPolicy(Qt.NoFocus)
        self.desktopLyricButton.setIcon(QIcon(IconsHub.DesktopLyric))
        self.desktopLyricButton.setIconSize(QSize(25, 25))

        self.seekSlider = QSlider(Qt.Horizontal)
        self.seekSlider.setObjectName("seekSlider")
        self.seekSlider.setFixedHeight(20)
        self.seekSlider.setFocusPolicy(Qt.NoFocus)
        self.seekSlider.setRange(0, 0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.favoriteButton)
        hbox1.addWidget(self.musicTitleLabel)
        hbox1.addStretch()
        hbox1.addWidget(self.timeLabel)
        vbox1 = QVBoxLayout()
        vbox1.addLayout(hbox1)
        vbox1.setSpacing(5)
        vbox1.addWidget(self.seekSlider)

        mainLayout = QHBoxLayout(self)
        mainLayout.setContentsMargins(2, 0, 0, 0)
        mainLayout.addWidget(self.artistHeadLabel)
        mainLayout.addWidget(self.previousButton)
        mainLayout.addWidget(self.playButton)
        mainLayout.addWidget(self.nextButton)
        mainLayout.addLayout(vbox1)
        mainLayout.addWidget(self.playmodeButton)
        mainLayout.addWidget(self.desktopLyricButton)

    def show_desktop_lyric(self):
        if self.desktopLyric.isHidden():
            beToOff = True
            self.desktopLyric.show()
            self.desktopLyric.original_place()
        else:
            beToOff = False
            self.desktopLyric.hide()
        self.desktop_lyric_state_changed_signal.emit(beToOff)

    def desktop_lyric_closed(self):
        self.desktop_lyric_state_changed_signal.emit(False)

    def change_playmode(self):
        oldPlaymode = self.playmode
        if self.playmode == Configures.PlaymodeRandom:
            self.set_new_playmode(Configures.PlaymodeOrder)
        elif self.playmode == Configures.PlaymodeOrder:
            self.set_new_playmode(Configures.PlaymodeSingle)
        elif self.playmode == Configures.PlaymodeSingle:
            self.set_new_playmode(Configures.PlaymodeRandom)
        self.playmode_changed_signal.emit(oldPlaymode, self.playmode)

    def set_new_playmode(self, playmode):
        self.playmode = playmode
        if playmode == Configures.PlaymodeRandom:
            iconPath = IconsHub.PlaymodeRandom
            toolTip = Configures.PlaymodeRandomText
        elif playmode == Configures.PlaymodeOrder:
            iconPath = IconsHub.PlaymodeOrder
            toolTip = Configures.PlaymodeOrderText
        else:
            iconPath = IconsHub.PlaymodeSingle
            toolTip = Configures.PlaymodeSingleText
        self.playmodeButton.setIcon(QIcon(iconPath))
        self.playmodeButton.setToolTip(toolTip)

    def ui_initial(self):
        self.mediaPlayer.stop()
        self.totalTime = "00:00"
        self.playAction.setIcon(QIcon(IconsHub.ControlPlay))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.artistName = "Zheng-Yejian"
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))
        self.seekSlider.setRange(0, 0)
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setToolTip("收藏")
        self.timeLabel.setText("00:00/00:00")

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

    def set_muted(self, muted):
        self.mediaPlayer.setMuted(muted)

    def tick(self):
        currentTime = self.mediaPlayer.position()
        self.seekSlider.setValue(currentTime)
        cTime = format_position_to_mmss(currentTime // 1000)
        self.timeLabel.setText(cTime + "/" + self.totalTime)
        self.media_player_notify_signal.emit(currentTime)

    def slider_value_changed(self, value):
        cTime = format_position_to_mmss(value // 1000)
        self.timeLabel.setText("%s/%s" % (cTime, self.totalTime))
        self.media_player_notify_signal.emit(value)

    def slider_pressed(self):
        self.mediaPlayer.positionChanged.disconnect(self.tick)

    def seek(self):
        if self.mediaPlayer.state() == QMediaPlayer.StoppedState:
            self.mediaPlayer.play()
            self.mediaPlayer.setPosition(self.seekSlider.value())
        else:
            self.mediaPlayer.setPosition(self.seekSlider.value())
            self.mediaPlayer.play()
        self.mediaPlayer.positionChanged.connect(self.tick)

    def duration_changed(self, duration):
        self.seekSlider.setMaximum(duration)
        exactTotalTime = format_position_to_mmss(self.mediaPlayer.duration() // 1000)
        self.timeLabel.setText("%s/%s" % (Configures.ZeroTime, exactTotalTime))
        if self.totalTime != exactTotalTime:
            self.totalTime = exactTotalTime
            self.playlist.set_music_time_at(self.currentSourceRow, exactTotalTime)

    def check_favorite(self):
        if self.currentSourceRow >= 0:
            if self.playlist.get_music_title_at(self.currentSourceRow) in self.lovedSongs:
                self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
                self.favoriteButton.setToolTip("取消收藏")
            else:
                self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo))
                self.favoriteButton.setToolTip("收藏")
            if self.playlist.get_name() == Configures.PlaylistFavorite:
                self.favoriteButton.setToolTip("收藏")

    def mark_as_favorite(self):
        if (
            self.playlist.get_name() == Configures.PlaylistFavorite
            or not self.playlist.length()
            or self.currentSourceRow < 0
        ):
            return
        path = self.playlist.get_music_path_at(self.currentSourceRow)
        title = self.playlist.get_music_title_at(self.currentSourceRow)
        if self.playlist.get_name() == Configures.PlaylistOnline:
            musicName = get_full_music_name_from_title(title)
            musicPath = os.path.join(self.downloadDir, musicName)
            musicPathO = os.path.join(Configures.MusicsDir, musicName)
            if not os.path.exists(musicPath) and not os.path.exists(musicPathO):
                QMessageBox.information(self, "提示", "请先下载该歌曲再添加喜欢!")
                return
            if os.path.exists(musicPath):
                path = musicPath
            else:
                path = musicPathO
        elif not os.path.exists(path):
            QMessageBox.information(self, "提示", "路径'" + "%s" % path + "'无效,无法标记喜欢!")
            return
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistFavorite)
        if title in self.lovedSongs:
            playlistTemp.remove_item_at(self.lovedSongs.index(title))
            playlistTemp.commit_records()
            self.lovedSongs.remove(title)
            self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo))
            self.favoriteButton.setToolTip("收藏")
        else:
            playlistTemp.add_item_from_path(path)
            playlistTemp.commit_records()
            self.lovedSongs.append(title)
            self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
            self.favoriteButton.setToolTip("取消收藏")
        self.mark_favorite_completed_signal.emit()

    def show_artist_info(self):
        if self.artistName:
            self.show_artist_info_signal.emit(self.artistName)

    def decide_to_play_or_pause(self, row):
        if row != self.currentSourceRow:
            self.set_media_source_at_row(row, clickPlayFlag=True)
        elif self.mediaPlayer.state() in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState):
            self.mediaPlayer.play()
        elif self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()

    def set_media_source_at_row(self, row, clickPlayFlag=False):
        if not self.playlist.length() or row < 0:
            return
        self.stop_music()
        self.clickPlayFlag = clickPlayFlag
        self.playlist.set_current_row(row)
        sourcePath = self.playlist.get_music_path_at(row)
        self.title = self.playlist.get_music_title_at(row)
        self.sourceTrace = "local" if self.playlist.get_music_id_at(row) == Configures.LocalMusicId else "online"
        self.artistName, self.musicName = get_artist_and_musicname_from_title(self.title)
        self.playlistName = self.playlist.get_name()
        self.totalTime = self.playlist.get_music_time_at(row)
        self.album = self.playlist.get_music_album_at(row)
        self.errorType = Configures.NoError
        isAnUrl = False
        if not os.path.exists(sourcePath):
            if self.playlist.get_name() == Configures.PlaylistOnline:
                if sourcePath == Configures.NoLink:
                    musicId = self.playlist.get_music_id_at(row)
                    sourcePath = SearchOnline.get_song_link(musicId)
                    if sourcePath:
                        self.playlist.set_music_path_at(row, sourcePath)
                    else:
                        self.errorType = Configures.UrlError
                isAnUrl = True
            else:
                self.errorType = Configures.PathError
                sourcePath = "/usr/share/sounds/error_happened.ogg"
        if self.errorType == Configures.NoError:
            self.sourcePath = sourcePath
            self.musicFileName = get_base_name_from_path(sourcePath)
            self.playedDate = get_time_of_now()
            self.songinfosManager.update_datas_of_item(
                self.musicFileName,
                self.playedDate,
                self.musicName,
                self.artistName,
                self.totalTime,
                self.album,
                self.playlistName,
            )
            if not self.timerFlag:
                self.timerFlag = True
                self.timeSpan = 0
            if isAnUrl:
                url = QUrl(sourcePath)
            else:
                url = QUrl.fromLocalFile(sourcePath)
            self.play_from_url(url)
        else:
            self.timerFlag = False
            self.dont_hide_main_window_signal.emit()
            if self.errorType == Configures.DisnetError:
                QMessageBox.critical(
                    self, "错误", "联网出错!\n无法联网播放歌曲'%s'!\n您最好在网络畅通时下载该曲目!" % self.playlist.get_music_title_at(row)
                )
            elif self.errorType == Configures.PathError:
                QMessageBox.information(self, "提示", "路径'%s'无效,请尝试重新下载并添加对应歌曲!" % self.playlist.get_music_path_at(row))

    def play_from_url(self, url):
        mediaContent = QMediaContent(url)
        self.mediaPlayer.setMedia(mediaContent)
        self.mediaPlayer.play()

    def state_changed(self, newState):
        if self and newState in [QMediaPlayer.PlayingState, QMediaPlayer.PausedState, QMediaPlayer.StoppedState]:
            if not self.playlist.length():
                return
            iconPath = IconsHub.ControlPause
            if newState in [QMediaPlayer.StoppedState, QMediaPlayer.PausedState]:
                iconPath = IconsHub.ControlPlay
            icon = QIcon(iconPath)
            self.playAction.setIcon(icon)
            if self.timerFlag:
                if newState == QMediaPlayer.PlayingState:
                    self.timeStart = time.time()
                else:
                    self.timeSpan += time.time() - self.timeStart

    def media_status_changed(self, status):
        if status == QMediaPlayer.EndOfMedia:
            self.music_finished()

    def music_finished(self):
        if self.errorType == Configures.NoError:
            self.next_song()

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

    def stop_music_but_timing(self):
        self.mediaPlayer.stop()
        self.seekSlider.setValue(0)
        self.media_player_notify_signal.emit(-0.5)

    def stop_music(self):
        self.stop_music_but_timing()
        if self.timerFlag:
            self.timerFlag = False
            InfosList = [
                self.playedDate,
                self.musicFileName,
                self.musicName,
                self.artistName,
                self.album,
                "%i" % change_mmss_to_seconds(self.totalTime),
                "%.1f" % self.timeSpan,
                self.playlistName,
                self.sourcePath,
                "%i" % (self.title in self.lovedSongs),
                self.sourceTrace,
                Configures.Playmodes[self.playmode],
                "%i" % self.clickPlayFlag,
            ]
            log_playback_history(organized_list_as_str(InfosList))
            self.songinfosManager.update_time_span_relate_of_item(self.musicFileName, self.timeSpan, self.clickPlayFlag)
            self.clickPlayFlag = False

    def get_next_random_row(self):
        listTemp = list(self.playlist.get_ids() - set(self.nearPlayedSongs))
        ran = random.randint(0, len(listTemp) - 1)
        return self.playlist.get_items_queue().index(listTemp[ran])

    def get_next_single_row(self):
        nextRow = self.currentSourceRow
        if nextRow < 0:
            nextRow = 0
        return nextRow

    def get_next_order_row(self, reverse=False):
        if reverse:
            if self.currentSourceRow < 0:
                self.currentSourceRow = 0
            return (self.currentSourceRow - 1) % self.playlist.length()
        return (self.currentSourceRow + 1) % self.playlist.length()

    def previous_song(self):
        self.play_source_on_next_row(reverse=True)

    def next_song(self):
        self.play_source_on_next_row()

    def play_source_on_next_row(self, reverse=False):
        if not self.playlist.length():
            return
        if self.mediaPlayer.position() > 20:
            self.music_ended_signal.emit()
        nextRow = 0
        if self.playmode == Configures.PlaymodeRandom:
            nextRow = self.get_next_random_row()
        elif self.playmode == Configures.PlaymodeOrder:
            nextRow = self.get_next_order_row(reverse)
        elif self.playmode == Configures.PlaymodeSingle:
            nextRow = self.get_next_single_row()
        self.set_media_source_at_row(nextRow)

    def current_media_changed(self):
        if not self.playlist.length():
            return
        self.current_media_changed_signal.emit()
        self.update_parameters()
        self.update_near_played_queue()
        self.check_favorite()

    def update_parameters(self):
        self.currentSourceRow = self.playlist.get_current_row()
        self.musicTitleLabel.setText(self.title)
        self.playAction.setText(self.musicName)
        imagePath = SearchOnline.get_artist_image_path(self.artistName)
        if imagePath:
            pixmap = QPixmap(imagePath)
        else:
            pixmap = QPixmap(IconsHub.Anonymous)
        self.artistHeadLabel.setPixmap(pixmap)
        musicId = self.playlist.get_music_id_at(self.currentSourceRow)
        self.update_window_lyric_signal.emit(self.title, musicId)

    def update_near_played_queue(self):
        self.currentSourceId = self.playlist.get_music_path_at(self.currentSourceRow)
        if self.playlist.get_name() == Configures.PlaylistOnline:
            self.currentSourceId = self.playlist.get_music_id_at(self.currentSourceRow)
        if self.currentSourceId not in self.nearPlayedSongs:
            self.nearPlayedSongs.append(self.currentSourceId)
        while len(self.nearPlayedSongs) >= self.playlist.length() * 4 / 5:
            del self.nearPlayedSongs[0]

    def add_title_into_loved_songs(self, title):
        self.lovedSongs.append(title)
Ejemplo n.º 35
0
class VideoPlayer(QWidget):
    def __init__(self, parent=None):
        super(VideoPlayer, self).__init__(parent)
        self._source = None
        self._total_duration = 0
        self.widget_layout = QVBoxLayout()
        self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.video_player = QVideoWidget()
        self.widget_layout.addWidget(self.video_player)
        self.media_player.setVideoOutput(self.video_player)
        # self.media_player.stateChanged.connect(self.mediaStateChanged)
        self.media_player.positionChanged.connect(self.on_positionChanged)
        self.signals = VideoPlayerWidgetSignals()
        self.media_player.durationChanged.connect(self.on_durationChanged)
        self.setLayout(self.widget_layout)
        print(self.media_player.duration())

    @property
    def total_duration(self):
        return self._total_duration

    @total_duration.setter
    def total_duration(self, val):
        self._total_duration = val

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, value):
        self._source = value
        self._total_duration = math.floor(VideoUtilities.duration(self.source))

    def play(self):
        if self._source:
            self.media_player.setMedia(
                QMediaContent(QUrl.fromLocalFile(self._source)))
            self.media_player.play()

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

    def stop(self):
        if self.media_player.state() == QMediaPlayer.PlayingState:
            self.media_player.stop()

    def go_to(self, second: int):
        if self.media_player:
            self.media_player.setPosition(second * 1000)

    @QtCore.pyqtSlot('qint64')
    def on_positionChanged(self, position):
        self.signals.video_position_changed_signal.emit(
            math.floor(position / 1000), self.total_duration)
        if self.media_player.state() == QMediaPlayer.StoppedState:
            if 0 <= position <= self.total_duration * 1000:
                self.media_player.play()

    @QtCore.pyqtSlot('qint64')
    def on_durationChanged(self, duration):
        self.signals.video_duration_changed_signal.emit(
            math.floor(duration / 1000))
Ejemplo n.º 36
0
class VKwindow(QWidget):

    def __init__(self, vkapi):
        super().__init__()
        self.vk = vkapi
        self.initUI()

    def initUI(self):
        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        vbox = QVBoxLayout()
        hbox = QHBoxLayout()
        self.setGeometry(300, 300, 290, 150)
        self.slider = QSlider(Qt.Horizontal)
        self.playBtn = QPushButton('►')
        self.nextBtn = QPushButton('>')
        self.prevBtn = QPushButton('<')

        self.nextBtn.clicked.connect(self.nextSong)
        self.prevBtn.clicked.connect(self.prevSong)

        self.playBtn.clicked.connect(self.playSong)
        self.setWindowTitle('VK music')
        self.list = QListWidget(self)
        self.list.currentItemChanged.connect(self.selectSong)

        for track in self.vk.method('audio.get').get('items'):
            self.list.addItem(SongWidgetItem(track))
            self.playlist.addMedia(QMediaContent(QUrl(track['url'])))

        hbox.addWidget(self.prevBtn)
        hbox.addWidget(self.playBtn)
        hbox.addWidget(self.nextBtn)
        hbox.addWidget(self.slider)

        self.player.setPlaylist(self.playlist)
        self.player.positionChanged.connect(self.setPosition)
        vbox.addWidget(self.list)
        vbox.addLayout(hbox)
        self.setLayout(vbox)
        self.show()

    def selectSong(self, curr, prev):
        self.currentTrack = curr
        print(curr.getArtist())

    def playSong(self):
        print(self.currentTrack.getArtist())
        print(self.list.currentRow())
        if self.player.state() == QMediaPlayer.PlayingState and self.list.currentRow() == self.playlist.currentIndex():
            self.player.pause()
            return
        elif self.player.state() == QMediaPlayer.PausedState:
            self.player.play()
            return
        self.playlist.setCurrentIndex(self.list.currentRow())
        self.slider.setTickInterval(self.player.duration())
        self.player.play()

    def setPosition(self, pos):
        print(pos)
        self.slider.setTickPosition(pos)

    def nextSong(self):
        tmp = self.list.currentRow()
        size = self.list.count()
        tmp = (tmp + 1) % size
        self.list.setCurrentRow(tmp)
        self.playlist.setCurrentIndex(tmp)
        self.player.play()

    def prevSong(self):
        tmp = self.list.currentRow()
        size = self.list.count()
        tmp = (tmp - 1) % size
        self.list.setCurrentRow(tmp)
        self.playlist.setCurrentIndex(tmp)
        self.player.play()
Ejemplo n.º 37
0
class videoPlayer(QWidget):  # 视频播放类
    def __init__(self, parent=None):  # 构造函数
        super(videoPlayer, self).__init__(parent=parent)  # 类的继承
        self.mainwindow = parent

        self.length = 0  # 视频总时长
        self.position = 0  # 视频当前时长
        self.count = 0
        self.player_status = -1

        # 设置窗口
        self.setGeometry(300, 50, 800, 600)  #大小,与桌面放置位置
        # self.setWindowIcon(QIcon(':/images/video_player_icon.png'))  # 程序图标
        # self.setWindowTitle(titleName)  # 窗口名称
        # self.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint)

        # 设置窗口背景
        self.palette = QPalette()
        self.palette.setColor(QPalette.Background, Qt.black)
        self.setPalette(self.palette)

        self.now_position = QLabel("/  00:00")  # 目前时间进度
        self.all_duration = QLabel('00:00')  # 总的时间进度
        self.all_duration.setStyleSheet('''QLabel{color:#000000}''')
        self.now_position.setStyleSheet('''QLabel{color:#000000}''')

        #视频插件
        self.video_widget = QVideoWidget(self)
        self.video_widget.setGeometry(QRect(0, 0, 1200, 700))  #大小,与桌面放置位置
        #self.video_widget.resize(1200, 700)  # 设置插件宽度与高度
        #self.video_widget.move(0, 30)   # 设置插件放置位置
        self.video_palette = QPalette()
        self.video_palette.setColor(QPalette.Background, Qt.black)  # 设置播放器背景
        self.video_widget.setPalette(self.video_palette)
        video_widget_color = "background-color:#000000"
        self.video_widget.setStyleSheet(video_widget_color)

        #布局容器
        self.verticalLayout = QVBoxLayout()
        self.verticalLayout.setSpacing(0)
        #self.verticalLayout.setContentsMargins(0, 5, 0, 10)
        self.layout = QHBoxLayout()
        self.layout.setSpacing(15)  # 各个插件的间距

        # 设置播放器
        self.player = QMediaPlayer(self)
        self.player.setVideoOutput(self.video_widget)
        #设置播放按钮事件
        self.player.durationChanged.connect(self.get_duration_func)
        # self.player.positionChanged.connect(self.progress)  # 媒体播放时发出信号
        self.player.mediaStatusChanged.connect(self.playerStatusChanged)
        self.player.error.connect(self.player_error)

        # 播放按钮
        self.play_btn = QPushButton(self)
        self.play_btn.setIcon(QIcon(':/images/play_btn_icon.png'))  # 设置按钮图标,下同
        self.play_btn.setIconSize(QSize(35, 35))
        self.play_btn.setStyleSheet(
            '''QPushButton{border:none;}QPushButton:hover{border:none;border-radius:35px;}'''
        )
        self.play_btn.setCursor(QCursor(Qt.PointingHandCursor))
        self.play_btn.setToolTip("播放")
        self.play_btn.setFlat(True)
        #self.play_btn.hide()
        #isHidden()      #判定控件是否隐藏

        #isVisible()     判定控件是否显示
        self.play_btn.clicked.connect(self.start_button)

        #音量条
        self.volume_slider = QSlider(Qt.Horizontal)  # 声音设置
        self.volume_slider.setMinimum(0)  # 音量0到100
        self.volume_slider.setMaximum(100)

        self.volume_slider.valueChanged.connect(self.volumes_change)

        self.volume_slider.setStyleSheet('''QSlider{}
QSlider::sub-page:horizontal:disabled{background: #00009C;  border-color: #999;  }
QSlider::add-page:horizontal:disabled{background: #eee;  border-color: #999; }
QSlider::handle:horizontal:disabled{background: #eee;  border: 1px solid #aaa;  border-radius: 4px;  }
QSlider::add-page:horizontal{background: #575757;  border: 0px solid #777;  height: 10px;border-radius: 2px; }
QSlider::handle:horizontal:hover{background:qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #2A8BDA,   stop:0.778409 rgba(255, 255, 255, 255));  width: 11px;  margin-top: -3px;  margin-bottom: -3px;  border-radius: 5px; }
QSlider::sub-page:horizontal{background: qlineargradient(x1:0, y1:0, x2:0, y2:1,   stop:0 #B1B1B1, stop:1 #c4c4c4);  background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,stop: 0 #5DCCFF, stop: 1 #1874CD);  border: 1px solid #4A708B;  height: 10px;  border-radius: 2px;  }
QSlider::groove:horizontal{border: 1px solid #4A708B;  background: #C0C0C0;  height: 5px;  border-radius: 1px;  padding-left:-1px;  padding-right:-1px;}
QSlider::handle:horizontal{background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5,   stop:0.6 #45ADED, stop:0.778409 rgba(255, 255, 255, 255));  width: 11px;  margin-top: -3px;  margin-bottom: -3px;  border-radius: 5px; }'''
                                         )

        #视频播放进度条
        self.video_slider = QSlider(Qt.Horizontal, self)  # 视频进度拖拖动
        self.video_slider.setMinimum(0)  # 视频进度0到100%
        #self.video_slider.setMaximum(100)
        self.video_slider.setSingleStep(1)
        self.video_slider.setGeometry(QRect(0, 0, 200, 10))
        self.video_slider.sliderReleased.connect(self.video_silder_released)
        self.video_slider.sliderPressed.connect(self.video_silder_pressed)

        self.video_slider.setStyleSheet('''QSlider{}
QSlider::sub-page:horizontal:disabled{background: #00009C;  border-color: #999;  }
QSlider::add-page:horizontal:disabled{background: #eee;  border-color: #999; }
QSlider::handle:horizontal:disabled{background: #eee;  border: 1px solid #aaa;  border-radius: 4px;  }
QSlider::add-page:horizontal{background: #575757;  border: 0px solid #777;  height: 10px;border-radius: 2px; }
QSlider::handle:horizontal:hover{background:qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0.6 #2A8BDA,   stop:0.778409 rgba(255, 255, 255, 255));  width: 11px;  margin-top: -3px;  margin-bottom: -3px;  border-radius: 5px; }
QSlider::sub-page:horizontal{background: qlineargradient(x1:0, y1:0, x2:0, y2:1,   stop:0 #B1B1B1, stop:1 #c4c4c4);  background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,stop: 0 #5DCCFF, stop: 1 #1874CD);  border: 1px solid #4A708B;  height: 10px;  border-radius: 2px;  }
QSlider::groove:horizontal{border: 1px solid #4A708B;  background: #C0C0C0;  height: 5px;  border-radius: 1px;  padding-left:-1px;  padding-right:-1px;}
QSlider::handle:horizontal{background: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5,   stop:0.6 #45ADED, stop:0.778409 rgba(255, 255, 255, 255));  width: 11px;  margin-top: -3px;  margin-bottom: -3px;  border-radius: 5px; }'''
                                        )

        #静音按钮
        self.mute_button = QPushButton('')
        self.mute_button.clicked.connect(self.mute)
        self.mute_button.setIconSize(QSize(30, 30))
        self.mute_button.setStyleSheet(
            '''QPushButton{border:none;}QPushButton:hover{border:none;}''')
        self.mute_button.setCursor(QCursor(Qt.PointingHandCursor))
        self.mute_button.setToolTip("播放")
        self.mute_button.setFlat(True)
        self.mute_button.setIcon(QIcon(':/images/sound_btn_icon.png'))

        #暂停按钮
        self.pause_btn = QPushButton('')
        self.pause_btn.setIcon(QIcon(':/images/stop_btn_icon.png'))
        self.pause_btn.clicked.connect(self.stop_button)
        self.pause_btn.setIconSize(QSize(35, 35))
        self.pause_btn.setStyleSheet(
            '''QPushButton{border:none;}QPushButton:hover{border:none;}''')
        self.pause_btn.setCursor(QCursor(Qt.PointingHandCursor))
        self.pause_btn.setToolTip("播放")
        self.pause_btn.setFlat(True)
        self.pause_btn.hide()

        #音量值和音量显示标签
        self.volume_value = QLabel()
        self.volume_value.setText(' ' * 5)
        self.volume_value.setStyleSheet('''QLabel{color:#000000;}''')

        self.volume_t = QLabel()

        self.volume_t.setStyleSheet('''QLabel{color:#000000;}''')

        #视频文件打开按钮
        self.open_btn = QPushButton('Open')
        self.open_btn.clicked.connect(self.getfile)

        #全屏按钮
        self.screen_btn = QPushButton('')
        self.screen_btn.setIcon(
            QIcon(QPixmap(':/images/fullsrceen_btn_icon.png')))
        self.screen_btn.setIconSize(QSize(38, 38))
        self.screen_btn.setStyleSheet(
            '''QPushButton{border:none;}QPushButton:hover{border:1px solid #F3F3F5;border-radius:35px;}'''
        )
        self.screen_btn.setCursor(QCursor(Qt.PointingHandCursor))
        self.screen_btn.setToolTip("播放")
        self.screen_btn.setFlat(True)
        self.screen_btn.clicked.connect(self.fullscreen)

        #添加按钮组件
        self.verticalLayout.addStretch()
        self.layout.addWidget(self.play_btn, 0,
                              Qt.AlignCenter | Qt.AlignVCenter)
        self.layout.addWidget(self.pause_btn, 0, Qt.AlignCenter
                              | Qt.AlignVCenter)  # 插件,与前一个模块的距离,位置

        self.layout.addWidget(self.all_duration, 0,
                              Qt.AlignCenter | Qt.AlignVCenter)
        self.layout.addWidget(self.now_position, 0,
                              Qt.AlignCenter | Qt.AlignVCenter)
        self.layout.addWidget(self.video_slider, 15,
                              Qt.AlignVCenter | Qt.AlignVCenter)
        self.layout.addWidget(self.mute_button, 0,
                              Qt.AlignCenter | Qt.AlignVCenter)
        self.layout.addWidget(self.volume_slider, 0,
                              Qt.AlignCenter | Qt.AlignVCenter)

        self.layout.addWidget(self.volume_value, 0,
                              Qt.AlignCenter | Qt.AlignVCenter)

        #self.layout.addWidget(self.screen_btn)
        #self.layout.addWidget(self.open_btn)
        self.verticalLayout.addLayout(self.layout)

        #self.verticalLayout.addLayout(self.layout)
        self.setLayout(self.verticalLayout)

    def player_error(self, errorCode):
        print('error = ' + str(errorCode))
        try:
            if errorCode == 0:
                pass
            elif errorCode == 1:
                self.showAlertWindow('errorCode:1 \n\n无效视频源。')
            elif errorCode == 2:
                self.showAlertWindow('errorCode:2 \n\n不支持的媒体格式')
            elif errorCode == 3:
                self.showAlertWindow('errorCode:3 \n\n网络错误')
            elif errorCode == 4:
                self.showAlertWindow('errorCode:4 \n\n没有权限播放该视频')
            elif errorCode == 5:
                self.showAlertWindow('errorCode:5 \n\n视频服务不存在,无法继续播放。')
            else:
                self.showAlertWindow('未知错误')
        except:
            self.showAlertWindow('视频加载异常')

    def video_silder_pressed(self):
        if self.player.state != 0:
            self.player.pause()

    def playerStatusChanged(self, status):
        self.player_status = status
        if status == 7:
            self.play_btn.show()
            self.pause_btn.hide()

        #print('playerStatusChanged =' + str(status) + '...............')

    def resizeEvent(self, e):
        #print(e.size().width(), e.size().height())
        newSize = e.size()
        self.video_widget.setGeometry(0, 0, newSize.width(),
                                      newSize.height() - 50)
        #self.video_widget.setGeometry(0, 0, 0, 0)

    def closeEvent(self, e):
        self.player.stop()

    def get_duration_func(self, d):
        try:
            end_number = int(d / 1000 / 10) + 1
            #print('end_number = ' + str(end_number))
            sum = 0
            for n in range(1, end_number):
                sum = sum + n

            vv = int((100 / (d / 1000)) * (d / 1000))
            self.video_slider.setMaximum(d)
            #self.video_slider.setMaximum(vv + sum)
            #print(100 + sum)

            all_second = int(d / 1000 % 60)  # 视频播放时间
            all_minute = int(d / 1000 / 60)

            if all_minute < 10:

                if all_second < 10:

                    self.all_duration.setText('0' + str(all_minute) + ':0' +
                                              str(all_second))
                else:

                    self.all_duration.setText('0' + str(all_minute) + ':' +
                                              str(all_second))
            else:

                if all_second < 10:

                    self.all_duration.setText(
                        str(all_minute) + ':0' + str(all_second))
                else:

                    self.all_duration.setText(
                        str(all_minute) + ':' + str(all_second))
        except Exception as e:
            pass

    def mouseDoubleClickEvent(self, e):
        try:

            #print('mouseDoubleClickEvent................... = ' + str(self.player.state()))
            if self.player.state() == 2:
                #视频暂停
                self.player.play()
                self.play_btn.hide()
                self.pause_btn.show()

            elif self.player.state() == 1:
                # 正在播放
                self.player.pause()
                self.play_btn.show()
                self.pause_btn.hide()
            else:
                #视频停止
                self.play_btn.hide()
                self.pause_btn.show()
                self.player.setPosition(0)
                self.video_slider.setValue(0)
                self.player.play()
        except Exception as e:
            pass

    def start_button(self):  # 视频播放按钮
        try:

            self.play_btn.hide()
            self.pause_btn.show()

            if self.player_status == 7:
                self.video_slider.setValue(0)
                self.player.setPosition(0)

            self.player.play()
        except Exception as e:
            pass

    def stop_button(self):  # 视频暂停按钮
        self.play_btn.show()
        self.pause_btn.hide()
        self.player.pause()

    def getfile(self, filepath):  # 打开视频文件
        try:

            #print(str(filepath))
            url = QUrl.fromLocalFile(filepath)
            if url.isValid():
                self.player.setMedia(QMediaContent(url))  # 返回该文件地址,并把地址放入播放内容中
                self.player.setVolume(50)  # 设置默认打开音量即为音量条大小
                self.volume_value.setText(str(50))
                self.volume_slider.setValue(50)
            else:
                self.showAlertWindow('视频地址无效')

        except Exception as e:
            self.showAlertWindow()

    def clearVolumeValue():
        self.volume_value.setText(' ' * 5)

    def volumes_change(self):  # 拖动进度条设置声音
        try:
            size = self.volume_slider.value()
            if size:
                # 但进度条的值不为0时,此时音量不为静音,音量值即为进度条值
                self.player.setMuted(False)
                self.player.setVolume(size)
                volume_value = str(size) + ' ' * 4
                self.volume_value.setText(volume_value)
                #print(size)
                self.mute_button.setIcon(QIcon(':/images/sound_btn_icon.png'))
            else:
                self.player.setMuted(True)
                self.mute_button.setIcon(QIcon(':/images/mute_btn_icon.png'))
                self.player.setVolume(0)
                volume_value = '0' + ' ' * 4
                self.volume_value.setText(volume_value)

            if len(str(size)) == 1:
                volume_value = str(size) + ' ' * 4
            elif len(str(size)) == 2:
                volume_value = str(size) + ' ' * 3
            else:
                volume_value = str(size) + ' ' * 2

            self.volume_value.setText(volume_value)
        except Exception as e:
            pass

    def mute(self):
        try:
            if self.player.isMuted():
                self.mute_button.setIcon(QIcon(':/images/sound_btn_icon.png'))
                self.player.setMuted(False)
                self.volume_slider.setValue(50)
                volume_value = '50' + ' ' * 4
                self.volume_value.setText(volume_value)
            else:
                self.mute_button.setIcon(QIcon(':/images/mute_btn_icon.png'))
                self.player.setMuted(True)  # 若不为静音,则设置为静音,音量置为0
                self.volume_slider.setValue(0)
                volume_value = '0' + ' ' * 4
                self.volume_value.setText(volume_value)
        except Exception as e:
            pass

    def progress(self):  # 视频进度条自动释放与播放时间

        try:

            self.length = self.player.duration() + 1
            self.position = self.player.position()
            #print(str(self.length) + ':' + str(self.position))
            self.count += 1

            video_silder_maximum = self.video_slider.maximum()

            #video_silder_value = int(((video_silder_maximum / (self.length / 1000)) * (self.position / 1000)))

            #self.video_slider.setValue(video_silder_value + self.count)

            self.video_slider.setValue(self.position)

            #print('video_slider_value = ' + str(video_silder_value + self.count))

            now_second = int(self.position / 1000 % 60)
            now_minute = int(self.position / 1000 / 60)
            self.mainwindow.resultlist2.addItem("{0:02d} : {1:02d}".format(
                now_minute, now_second))
            #print(str(now_minute) + ':' + str(now_second))
            if now_minute < 10:
                if now_second < 10:

                    self.now_position.setText('/  0' + str(now_minute) + ':0' +
                                              str(now_second))
                else:

                    self.now_position.setText('/  0' + str(now_minute) + ':' +
                                              str(now_second))
            else:

                #print('now_minute < 10' + str(now_minute) + ':' + str(now_second))

                if now_second < 10:
                    #print('now_second < 10' + str(now_minute) + ':' + str(now_second))
                    #self.now_position.setText(str(now_minute) + ':0' + str(now_second))
                    self.now_position.setText('/  ' + str(now_minute) + ':0' +
                                              str(now_second))
                else:
                    #print('now_second > 10' + str(now_minute) + ':' + str(now_second))
                    self.now_position.setText('/  ' + str(now_minute) + ':' +
                                              str(now_second))
        except Exception as e:
            pass

    def video_silder_released(self):  # 释放滑条时,改变视频播放进度
        try:

            #print('video_silder_released......')
            if self.player.state() != 0:
                self.player.setPosition(self.video_slider.value())
                self.player.play()
            else:  #如果视频是停止状态,则拖动进度条无效
                self.video_slider.setValue(0)
        except Exception as e:
            pass

    def fullscreen(self):
        self.showFullScreen()

    def keyPressEvent(self, event):  # 重新改写按键
        if event.key() == Qt.Key_Escape:
            self.winquit()

    def winquit(self):  # 退出窗口
        self.showNormal()

    def showAlertWindow(self, msg='视频加载出错!'):
        reply = QMessageBox.information(self, "消息框标题", msg, QMessageBox.Yes)

    def setWindowTitleName(self, titleName):
        self.setWindowTitle(titleName)  # 窗口名称
Ejemplo n.º 38
0
class jaabaGUI(QMainWindow):
    """ controller for the blob labeling GUI"""
    def __init__(self,parent=None):
        QMainWindow.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        #add new slider
        # self.positionSlider=QSlider(Qt.Horizontal)
        # self.positionSlider.setGeometry (800,800,100,30)
        # self.positionSlider.setRange(0, 0)
        # self.positionSlider.sliderMoved.connect(self.setPosition)

        #setup Video
        #video player
        self.mediaPlayer1 = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer2 = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        #self.mediaPlayer.metaDataChanged.connect(self.metaDataChanged)
        self.mediaPlayer1.durationChanged.connect(self.durationChanged)
        self.mediaPlayer1.positionChanged.connect(self.positionChanged)
        self.mediaPlayer2.positionChanged.connect(self.positionChanged)
        

        #visualizetion
        self.scene = QGraphicsScene()
        self.ui.graphicsView.setScene(self.scene)
        #self.scene.setBackgroundBrush(Qt.black)
        self.videoItem1 = QGraphicsVideoItem()
        self.videoItem2 = QGraphicsVideoItem()
        self.scene.addItem(self.videoItem1)
        self.scene.addItem(self.videoItem2)
        self.mediaPlayer1.setVideoOutput(self.videoItem1)
        self.mediaPlayer2.setVideoOutput(self.videoItem2)

        #slide bar
        print self.ui.horizontalSlider
        self.ui.horizontalSlider.setRange(0, 0)
        self.ui.horizontalSlider.sliderMoved.connect(self.setPosition)
        # self.ui.horizontalSlider.sliderPressed.connect(self.sliderPressed)



        #print self.ui.graphicsView.width()/2,self.ui.graphicsView.height()
        #self.videoItem1.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height()))
        #self.videoItem2.setSize(QSizeF(self.ui.graphicsView.width()*10,self.ui.graphicsView.height()*10))
       # self.videoItem2.setSize(graphicsView.size())
        #self.videoItem2.setOffset(QPointF(500,500))
        #self.videoItem2.setOffset(QPointF(self.ui.graphicsView.width()/2,0))   
        #self.videoItem2.setPos(QPointF(0,0))
        # print self.ui.graphicsView.width(), self.ui.graphicsView.height()
        # print self.ui.graphicsView.size()
        # print self.videoItem2.boundingRect().width(), self.videoItem2.boundingRect().height()
        # print self.ui.graphicsView.sceneRect()
        #self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)

        #callbacks
        self.ui.actionQuit.triggered.connect(self.quit)
        self.ui.actionLoad_Project.triggered.connect(self.loadVideo)
        #self.ui.buttonPlay.clicked[bool].connect(self.setToggleText)
        self.ui.buttonPlay.clicked.connect(self.play)
        #print self.ui.graphicsView.sizeHint()


        #initialization
        self.loaded = False
        self.videoFilename = None
        self.frame_count=None
        self.width=None
        self.height=None
        self.frame_trans=None



        
    # ###actions starts from here###
    def quit(self):
        QApplication.quit()

    def loadVideo(self):
        self.writeLog("Loading video...")

        self.videoFilename = QFileDialog.getOpenFileName(self, 'Open File', '.')[0]
        if not self.videoFilename:
            self.writeLog("User cancelled - no video loaded")
            return
        else:
       		cap=cv2.VideoCapture(self.videoFilename)
	    	self.frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT)
	    	self.width=cap.get(3)
	    	self.height=cap.get(4)
	        self.mediaPlayer2.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename )))
	        self.mediaPlayer1.setMedia(QMediaContent(QUrl.fromLocalFile(self.videoFilename )))
	        self.ui.buttonPlay.setEnabled(True)
            # self.mediaPlayer2.setVideoOutput(self.videoItem2)
            # self.mediaPlayer1.setVideoOutput(self.videoItem1)
            # size= self.videoItem2.nativeSize()
            # print size
            #print self.mediaPlayer.duration()
          
            #print self.mediaPlayer.metaData()
        self.writeLog("Video loaded!")

    def play(self):
    	
        self.videoItem1.setAspectRatioMode(0)
        self.videoItem2.setAspectRatioMode(0)
        self.scene.setSceneRect(0,0,self.ui.graphicsView.width(),self.ui.graphicsView.height())
        self.videoItem1.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height()))
        self.videoItem2.setSize(QSizeF(self.ui.graphicsView.width()/2,self.ui.graphicsView.height()))
        self.videoItem1.setPos(QPointF(0,0))
        self.videoItem2.setPos(QPointF(self.ui.graphicsView.width()/2,0))
        #self.ui.graphicsView.setGeometry(0,0, 600,800)
        #print 'graphicsView size', self.ui.graphicsView.size()
        #print 'graphicsScene size', self.scene.sceneRect()
        #self.videoItem2.setSize(QSizeF(1000,300))
        #print 'graphicsVideoItem size',self.videoItem2.size()
        # print 'item x',self.videoItem2.scenePos().x()
        # print 'item y', self.videoItem2.scenePos().y()
        # print 'item x',self.videoItem1.scenePos().x()
        # print 'item y', self.videoItem1.scenePos().y()

        if self.mediaPlayer1.state() == QMediaPlayer.PlayingState:
        	self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPlay))
        	self.ui.buttonPlay.setText("Play")
        	self.mediaPlayer1.pause()
        	self.writeLog("Video paused")
        else: 
        	self.ui.buttonPlay.setIcon(self.ui.style().standardIcon(PyQt5.QtWidgets.QStyle.SP_MediaPause))
	        self.ui.buttonPlay.setText("Stop")
	        self.mediaPlayer1.play()
	        self.writeLog("Playing video")

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


        
        #size= self.videoItem2.nativeSize()
        # print self.mediaPlayer.duration()
      
        #print self.mediaPlayer.metaData()
      

        # print self.ui.graphicsView.width(), self.ui.graphicsView.height()
        # print self.ui.graphicsView.size()
        # print self.videoItem2.boundingRect().width(), self.videoItem2.boundingRect().height()
        # print self.ui.graphicsView.sceneRect()
        # print self.scene.sceneRect()
        # print self.ui.graphicsView.sizeHint()

    

    def setPosition(self, position):
    	self.mediaPlayer1.setPosition(position) 
    	self.mediaPlayer2.setPosition(position)  

    # when position of media changed, set slider and text box accordingly.
    def positionChanged(self, position):
        self.ui.horizontalSlider.setValue(position)
        if isinstance(self.frame_trans,float):
	        # print type(position),position
	        # print type(self.frame_trans),self.frame_trans 
	        # print position/self.frame_trans
	     	self.ui.lineEdit.setText(str(int(round(position/self.frame_trans,0))))
	       
        self.writeLog(str(position))    
    
    def durationChanged(self, duration):
	    self.ui.horizontalSlider.setRange(0, duration) 
	    self.frame_trans=self.mediaPlayer1.duration()/self.frame_count
	    print self.frame_trans

    

    def writeLog(self,text):
        self.ui.log.setText(text)
Ejemplo n.º 39
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())
Ejemplo n.º 40
0
class QGisMap(QtWidgets.QWidget, Ui_Form):
    
    def __init__(self,projectfile,MainWidget):
        QtWidgets.QMainWindow.__init__(self)
        if os.name == 'nt':
            ffmpeg = os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'
            versione = 'ffmpeg.exe'
        else:
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            versione = 'ffmpeg'
        if os.path.exists(ffmpeg) == True:
            self.setupUi(self)
            self.setWindowFlags(Qt.WindowStaysOnTopHint)
            self.Main = MainWidget
            self.projectfile = projectfile
            with open(self.projectfile,'r') as File:
                    for line in File:
                        if line[0:19] == 'Video file location':
                            self.videoFile = line.split('=')[-1][1:-1]
                        elif line[0:23] == 'Video start at msecond:':
                            self.fps = (1 / (float(line.split()[7]))) * 1000
                            self.StartMsecond = int(line.split()[4])
                        elif line[0:4] == 'DB =':
                            DB = line.split('=')[-1][1:-1]
                            if DB == 'None':
                                self.DB = None
                            else:
                                self.DB = DB
                            break            
            self.pushButton_3.setCheckable(True)
            self.EnableMapTool = False
            self.ExtractTool = 0
            self.dockWidget_4.hide()
            self.GPXList = []
            self.positionMarker=PositionMarker(self.Main.iface.mapCanvas())               
            self.muteButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaVolume))
            self.playButton.setIcon(
                        self.style().standardIcon(QStyle.SP_MediaPause))
            self.player = QMediaPlayer()
            self.player.setVideoOutput(self.video_frame)  
            self.playButton.clicked.connect(self.PlayPause)
            self.muteButton.clicked.connect(self.MuteUnmute)
            self.toolButton_11.clicked.connect(self.SkipBackward)
            self.toolButton_12.clicked.connect(self.SkipForward)
            self.SkipBacktoolButton_8.clicked.connect(self.BackwardFrame)
            self.SkipFortoolButton_9.clicked.connect(self.ForwardFrame)
            self.toolButton_4.clicked.connect(self.ExtractToolbar)
            self.toolButton_5.clicked.connect(self.close)   
            self.pushButtonCut_2.clicked.connect(self.ExtractCommand)
            self.pushButtonCutA_6.clicked.connect(self.ExtractFromA)
            self.pushButtonCutB_6.clicked.connect(self.ExtractToB)
            self.pushButton_5.clicked.connect(self.CancelVertex)  
            self.progressBar.hide()     
            self.Main.pushButton_2.hide()
            self.Main.pushButton_8.hide()
            self.Main.groupBox.show()
            self.Main.groupBox_4.hide()
            self.ExtractA = False
            self.ExtractB = False
            self.ExtractedDirectory = None 
            self.pushButtonCut_2.setEnabled(False)
            self.toolButton_6.setEnabled(False)
            self.LoadGPXVideoFromPrj(self.projectfile)  
        else:
            ret = QMessageBox.warning(self, "Warning", 'missing ffmpeg binaries, please download it from https://github.com/sagost/VideoUavTracker/blob/master/FFMPEG/'+versione+' and paste it in /.qgis3/python/plugins/Video_UAV_Tracker/FFMPEG/ ', QMessageBox.Ok)
            self.close()        
    def LoadGPXVideoFromPrj(self,VideoGisPrj):
        
        self.Polyline = []
        with open(VideoGisPrj,'r') as File:
            Counter = 0
            for line in File:
                if Counter < 5:
                    pass
                else:
                    line = line.split()
                    lat = float(line[0])
                    lon = float(line[1])
                    ele = float(line[2])
                    speed = float(line[3])
                    course = float(line[4])
                    time = line[5]
                    Point = [lat,lon,ele,speed,course,time]
                    qgsPoint = QgsPoint(lon,lat)
                    self.Polyline.append(qgsPoint)
                    self.GPXList.append(Point)
                Counter = Counter + 1
        self.GpsLayer = QgsVectorLayer("LineString?crs=epsg:4326", self.videoFile.split('.')[-2].split('/')[-1], "memory")
        self.pr = self.GpsLayer.dataProvider()
        feat = QgsFeature()
        feat.setGeometry(QgsGeometry.fromPolyline(self.Polyline))
        self.pr.addFeatures([feat])
        self.GpsLayer.updateExtents()
        if self.DB != None:
            try:
                self.DBLayer = QgsVectorLayer(self.DB,self.DB.split('.')[-2].split('/')[-1],'ogr')
                QgsProject.instance().addMapLayers([self.DBLayer,self.GpsLayer]) 
                self.AddPointMapTool = AddPointTool(self.Main.iface.mapCanvas(),self.DBLayer,self)
                self.toolButton_6.clicked.connect(self.AddPointTool)   
                self.toolButton_6.setEnabled(True)
            except:
                ret = QMessageBox.warning(self, "Warning", str(self.DB)+' is not a valid shapefile.', QMessageBox.Ok)
                return
        else:
            QgsProject.instance().addMapLayers([self.GpsLayer])    
        self.duration = len(self.GPXList)
        self.ExtractToB = self.duration
        self.horizontalSlider.setSingleStep(1000)
        self.horizontalSlider.setMinimum(0)
        self.horizontalSlider.setMaximum(len(self.GPXList)*1000)
        url = QUrl.fromLocalFile(str(self.videoFile))
        mc = QMediaContent(url)
        self.player.setMedia(mc)
        self.player.setPosition(self.StartMsecond)
        self.player.play()
        self.horizontalSlider.sliderMoved.connect(self.setPosition)
        self.player.stateChanged.connect(self.mediaStateChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.pushButton_3.clicked.connect(self.MapTool)
        self.skiptracktool = SkipTrackTool( self.Main.iface.mapCanvas(),self.GpsLayer , self)

    def AddPointTool(self):
        self.Main.iface.mapCanvas().setMapTool(self.AddPointMapTool) 
             
    def MapTool(self):
        if self.EnableMapTool == False:
            self.Main.iface.mapCanvas().setMapTool(self.skiptracktool)
            self.pushButton_3.setChecked(True)
            self.EnableMapTool = True
        else:
            self.Main.iface.mapCanvas().unsetMapTool(self.skiptracktool)
            self.pushButton_3.setChecked(False)
            self.EnableMapTool = False
                           
    def closeEvent(self, *args, **kwargs):
        try:
            self.player.stop()
            self.Main.iface.mapCanvas().scene().removeItem(self.positionMarker)
            self.CancelVertex()
            self.Main.pushButton_2.show()
            #self.Main.horizontalSpacer_2.show()
            self.Main.groupBox.hide()
            self.Main.pushButton_8.show()
            self.Main.groupBox_4.show()
            self.dockWidget_2.close()
        except:
            pass
        return QtWidgets.QWidget.closeEvent(self, *args, **kwargs)                      
    def mediaStateChanged(self, state):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPlay))
    
    def setPosition(self, position):
        self.player.setPosition(position+self.StartMsecond)   
    
    def secTotime(self,seconds): 
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            return "%d:%02d:%02d" % (h, m, s)   
                   
    def positionChanged(self, progress):
        if progress < self.StartMsecond:
            self.player.setPosition(self.StartMsecond)
            progress = self.StartMsecond
        AssociatedGps = round((progress - self.StartMsecond )/1000)
        self.DisplayPoint(AssociatedGps)
        totalTime = self.secTotime(self.duration)
        actualTime = self.secTotime((progress - self.StartMsecond )/1000)
        self.replayPosition_label.setText(actualTime + ' / '+totalTime)
        if not self.horizontalSlider.isSliderDown():
            self.horizontalSlider.setValue(progress - self.StartMsecond ) 

    def DisplayPoint(self,Point):
        if Point >= len(self.GPXList):
            Point = len(self.GPXList) - 1
        gpx = self.GPXList[Point]
        lat = round(gpx[0],7)
        lon = round(gpx[1],7)
        ele = gpx[2]
        speed = gpx[3]
        course = gpx[4]
        time = gpx[5]
        Point = QgsPointXY()
        Point.set(lon, lat)
        canvas = self.Main.iface.mapCanvas()
        crsSrc = QgsCoordinateReferenceSystem(4326)    # .gpx is in WGS 84
        crsDest = QgsProject.instance().crs()
        xform = QgsCoordinateTransform(crsSrc, crsDest)
        self.positionMarker.setHasPosition(True)
        self.Point = xform.transform(Point)
        self.positionMarker.newCoords(self.Point)
        self.positionMarker.angle = float(course)
        extent = canvas.extent() 
        boundaryExtent=QgsRectangle(extent)
        boundaryExtent.scale(0.7)
        if not boundaryExtent.contains(QgsRectangle(Point, self.Point)):
            extentCenter= self.Point
            newExtent=QgsRectangle(
                        extentCenter.x()-extent.width()/2,
                        extentCenter.y()-extent.height()/2,
                        extentCenter.x()+extent.width()/2,
                        extentCenter.y()+extent.height()/2
                        )
            self.Main.iface.mapCanvas().setExtent(newExtent)
            self.Main.iface.mapCanvas().refresh() 
        self.Main.label_14.setText('GPS Time: '+str(time))
        self.Main.label_15.setText('Course: '+"%.2f" % (course))
        self.Main.label_16.setText('Ele: '+"%.2f" %(ele))
        self.Main.label_17.setText('Speed m/s: '+"%.2f" %(speed))
        self.Main.label_19.setText('Lat : '+str(lat))
        self.Main.label_18.setText('Lon : '+str(lon))
                  
    def MuteUnmute(self):
        if self.player.mediaStatus() == 6 :
            if self.player.isMuted() == 1:
                self.player.setMuted(0)
                self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolume))
            elif self.player.isMuted() == 0:
                self.player.setMuted(1)
                self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolumeMuted))   
    
    def SkipForward(self): 
        position = self.player.position()
        self.player.setPosition(position+1000)
       
    def SkipBackward(self): 
        position = self.player.position()
        self.player.setPosition(position-1000)
      
    def ForwardFrame(self):  
        position = self.player.position()
        self.player.setPosition(position+int(self.fps))
      
    def BackwardFrame(self):
        position = self.player.position()
        self.player.setPosition(position-int(self.fps))
     
    def PlayPause(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        else:
            self.player.play()
            
    def findNearestPointInRecording(self, x,y):
        ClickPt = QgsPoint(x,y)
        Low =  ClickPt.distanceSquared(self.Polyline[0])
        NearPoint = 0
        Counter = 0
        for Point in self.Polyline:
            dist = ClickPt.distanceSquared(Point)
            if dist < Low:
                Low = dist
                NearPoint = Counter
                Counter = Counter + 1
            else:
                Counter = Counter + 1
        self.setPosition(NearPoint*1000)
        
    def ExtractSingleFrameOnTime(self, pos, outputfile):
        if os.name == 'nt':
            ffmpeg = ('"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"')
            os.popen(str(ffmpeg)+' -ss '+str(pos/1000)+' -i '+str('"' +self.videoFile+ '"')+ ' -t 1 '+str('"'+outputfile+'"'))
        else:
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            os.system(str(ffmpeg)+' -ss '+str(pos/1000)+' -i '+str(self.videoFile)+' -t 1 '+str(outputfile))
                 
    def AddPoint(self,x,y):
        self.Main.iface.mapCanvas().unsetMapTool(self.AddPointMapTool)
        Point = QgsPointXY(x,y)
        pos = self.player.position()
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        a = self.DBLayer.name()
        last_desc = '///'
        LayerName =str(a)
        last_desc2 = LayerName + ' Point N '
        directory = str(self.DB.split('.')[0])+'_Image/'
        if not os.path.exists(directory):
            os.makedirs(directory)
        fc = int(self.DBLayer.featureCount())
        self.ExtractSingleFrameOnTime(pos,directory+LayerName+'_'+str(fc)+'_.jpg')
        fields = self.DBLayer.fields()
        attributes = []
        lat,lon = Point.y(), Point.x()
        for field in fields:
            a = str(field.name())
            b = str(field.typeName())
            if a == 'id':
                fcnr = fc
                attributes.append(fcnr)  
            elif a == 'Lon(WGS84)':
                attributes.append(str(lon))                       
            elif a == 'Lat(WGS84)':
                attributes.append(str(lat))               
            elif a == 'Image link':
                attributes.append(str(directory+LayerName+'_'+str(fc)+'_.jpg'))                   
            else:                    
                if b == 'String':      
                    (a,ok) = QInputDialog.getText(
                                                  self.Main.iface.mainWindow(), 
                                                  "Attributes",
                                                  a + ' = String',
                                                  QLineEdit.Normal)
                    attributes.append(a)               
                elif b == 'Real':                    
                    (a,ok) = QInputDialog.getDouble(
                                                    self.Main.iface.mainWindow(), 
                                                    "Attributes",
                                                    a + ' = Real', decimals = 10)
                    attributes.append(a)
                elif b == 'Integer64':                    
                    (a,ok) = QInputDialog.getInt(
                                                 self.Main.iface.mainWindow(), 
                                                 "Attributes",
                                                 a + ' = Integer')
                    attributes.append(a)                    
        feature = QgsFeature()
        feature.setGeometry(QgsGeometry.fromPoint(Point))
        feature.setAttributes(attributes)
        self.DBLayer.startEditing()
        self.DBLayer.addFeature(feature)
        self.DBLayer.commitChanges()    
        self.DBLayer.triggerRepaint()

    def ExtractCommand(self):
        if self.ExtractToB <= self.ExtractFromA:
            ret = QMessageBox.warning(self, "Warning", '"To B" point must be after "from A" point', QMessageBox.Ok)
            self.CancelVertex()
        else:
            if os.name == 'nt':
                ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"'
            else:
                ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            Directory,_ = QFileDialog.getSaveFileName(caption= 'Save georeferenced images')
            if Directory:
                self.progressBar.show()
                self.progressBar.setValue(0)
                start = self.ExtractFromA
                if self.comboBox_6.currentText() == 'seconds':           
                    finish = self.ExtractToB - self.ExtractFromA
                    fps = self.doubleSpinBox_2.value()
                    if fps < 1.0:
                        fps = 1.0 / fps
                    elif fps > 1:
                        fps = 1.0 / fps
                        
                    if os.name == 'nt':
                        os.popen(str(ffmpeg+ ' -ss ' + str(start) + ' -i '+ str('"'+self.videoFile+'"')+ ' -t ' + str(finish) + ' -vf fps=' + str(fps) + ' ' + '"'+Directory + '_%d.png'+'"'))
                    else:
                        os.system(ffmpeg+' -ss '+ str(start) + ' -i '+ str(self.videoFile) + ' -t ' + str(finish) + ' -vf fps=' + str(fps) + ' ' + Directory + '_%d.png')
                else:
                    txtGPSFile = open(Directory + 'UTM_Coordinates.txt', 'w')
                    txtGPSFile.close()
                    txtGPSFile = open(Directory+ 'UTM_Coordinates.txt', 'a')
                    txtGPSFile.write('filename # East UTM # North UTM # Ele '+ '\n')
                    finish = self.ExtractToB
                    meters = self.doubleSpinBox_2.value()
                    Timerange = range(start, finish + 1)
                    RemainToUseMeterTotal = 0
                    if os.name == 'nt':
                        os.popen(ffmpeg+' -ss '+ str(start) + ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' + '"'+Directory + '_sec_' + str(start)+'.00.png'+'"')
                    else:
                        os.system(ffmpeg+' -ss '+ str(start) + ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(start)+'.00.png')
                    lonUTM, latUTM,quotainutile = self.transform_wgs84_to_utm(float(self.GPXList[start][1]) , float(self.GPXList[start][0]))
                    ele = float(self.GPXList[start][2])
                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_' + str(start)+'.00.png,'+' '+ str(lonUTM) + ', '+ str(latUTM) + ', ' + str(ele) + '\n')
                    for i in Timerange:
                        progessBarValue = ((i-start) * 100) // len(Timerange)
                        self.progressBar.setValue(int(progessBarValue))
                        latitude1,longitude1 = float(self.GPXList[i][0]) ,float(self.GPXList[i][1])
                        latitude2,longitude2 = float(self.GPXList[i+1][0]) ,float(self.GPXList[i+1][1])
                        ele1 = float(self.GPXList[i][2])
                        ele2 = float(self.GPXList[i+1][2])
                        Calculus = Geodesic.WGS84.Inverse(latitude1, longitude1, latitude2, longitude2)
                        DistanceBetweenPoint = Calculus['s12']    
                        Azimuth =   Calculus['azi2']                 
                        SpeedMeterSecond = DistanceBetweenPoint             #GPS refresh rate is actually 1, change parameter for different rates
                       # Time = 1                                            
                        if RemainToUseMeterTotal == 0:
                            if DistanceBetweenPoint >= meters:
                                decimalSecondToAdd = meters / DistanceBetweenPoint
                                RemainToUseMeter = DistanceBetweenPoint - meters
                                if os.name == 'nt':
                                    os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                             ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                else:
                                    os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                              ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                
                                
                                
                                
                                CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                while RemainToUseMeter > meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                if RemainToUseMeter == meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' +str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                    RemainToUseMeterTotal = 0  
                                elif RemainToUseMeter < meters:
                                    RemainToUseMeterTotal = RemainToUseMeter
                                    pass
                            else:
                                RemainToUseMeterTotal = meters - DistanceBetweenPoint       
                        elif RemainToUseMeterTotal > 0:
                            if DistanceBetweenPoint >= (meters - RemainToUseMeterTotal) :
                                decimalSecondToAdd = (meters - RemainToUseMeterTotal) / DistanceBetweenPoint
                                RemainToUseMeter = DistanceBetweenPoint - (meters - RemainToUseMeterTotal)
                                if os.name == 'nt':
                                    os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                             ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                else:
                                    os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                              ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                while RemainToUseMeter > meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                if RemainToUseMeter == meters:
                                    decimalSecondToAddMore = meters / SpeedMeterSecond
                                    RemainToUseMeter = RemainToUseMeter - meters
                                    decimalSecondToAdd = decimalSecondToAdd + decimalSecondToAddMore
                                    if os.name == 'nt':
                                        os.popen(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                 ' -i '+ str('"'+self.videoFile+'"') + ' -frames:v 1 ' +'"'+ Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png'+'"')
                                    else:
                                        os.system(ffmpeg+ ' -ss '+ str(i + decimalSecondToAdd) +
                                                  ' -i '+ str(self.videoFile) + ' -frames:v 1 ' + Directory + '_sec_' + str(i) + str(decimalSecondToAdd)[1:4] +'.png')
                                    
                                    CalculusDirect = Geodesic.WGS84.Direct(latitude1, longitude1, Azimuth,decimalSecondToAdd* SpeedMeterSecond) 
                                    X,Y,quotainutile = self.transform_wgs84_to_utm(CalculusDirect['lon2'],CalculusDirect['lat2'] )  
                                    Z = ele1 + decimalSecondToAdd*(ele2 - ele1)
                                    txtGPSFile.write(str(Directory.split('/')[-1]) + '_sec_'  + str(i) + str(decimalSecondToAdd)[1:4]+'.png,' + ' ' + str(X) + ', ' + str(Y) + ', ' + str(Z) + '\n')
                                    RemainToUseMeterTotal = 0
                                elif RemainToUseMeter < meters:
                                    RemainToUseMeterTotal = RemainToUseMeter
                            else:
                                RemainToUseMeterTotal = (meters - DistanceBetweenPoint) + RemainToUseMeterTotal
                    txtGPSFile.close()            
            self.progressBar.hide()
            
    def ExtractFromA(self):
        
        if self.ExtractA == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractAVertex)
        self.ExtractA = False
        self.ExtractFromA = round((self.player.position()- self.StartMsecond )/1000)
        canvas = self.Main.iface.mapCanvas()
        crsSrc = QgsCoordinateReferenceSystem(4326)    # .gpx is in WGS 84
        crsDest = QgsProject.instance().crs()
        xform = QgsCoordinateTransform(crsSrc, crsDest)
        latitude,longitude = self.Polyline[self.ExtractFromA].y(), self.Polyline[self.ExtractFromA].x()
        self.ExtractAVertex = QgsVertexMarker(canvas)
        self.ExtractAVertex.setCenter(xform.transform(QgsPointXY(longitude, latitude)))
        self.ExtractAVertex.setColor(QColor(0,255,0))
        self.ExtractAVertex.setIconSize(10)
        self.ExtractAVertex.setIconType(QgsVertexMarker.ICON_X)
        self.ExtractAVertex.setPenWidth(10)
        self.ExtractA = True
        if self.ExtractB == True:
            self.pushButtonCut_2.setEnabled(True)
        else:
            self.pushButtonCut_2.setEnabled(False)
            
    def ExtractToB(self):
        if self.ExtractB == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractBVertex)
        self.ExtractB = False    
        self.ExtractToB = round((self.player.position()- self.StartMsecond )/1000)  
        if self.ExtractA == True:
            if self.ExtractToB > self.ExtractFromA:
                canvas = self.Main.iface.mapCanvas()
                crsSrc = QgsCoordinateReferenceSystem(4326)    # .gpx is in WGS 84
                crsDest = QgsProject.instance().crs()
                xform = QgsCoordinateTransform(crsSrc, crsDest)   
                latitude,longitude = self.Polyline[self.ExtractToB].y(), self.Polyline[self.ExtractToB].x()
                self.ExtractBVertex = QgsVertexMarker(canvas)
                self.ExtractBVertex.setCenter(xform.transform(QgsPointXY(longitude, latitude)))
                self.ExtractBVertex.setColor(QColor(255,0,0))
                self.ExtractBVertex.setIconSize(10)
                self.ExtractBVertex.setIconType(QgsVertexMarker.ICON_X)
                self.ExtractBVertex.setPenWidth(10)
                self.ExtractB = True
                self.pushButtonCut_2.setEnabled(True)
            else:
                self.pushButtonCut_2.setEnabled(False)
                           
    def CancelVertex(self): 
        if self.ExtractA == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractAVertex)
            self.ExtractA = False
        if self.ExtractB == True:
            self.Main.iface.mapCanvas().scene().removeItem(self.ExtractBVertex)
            self.ExtractB = False
        self.pushButtonCut_2.setEnabled(False)
                  
    def ExtractToolbar(self):
        if self.ExtractTool == 0:
            self.dockWidget_4.show()
            self.ExtractTool = 1
        else:
            self.dockWidget_4.hide()
            self.ExtractTool = 0
            
    def transform_wgs84_to_utm(self, lon, lat): 
           
        def get_utm_zone(longitude):
            return (int(1+(longitude+180.0)/6.0))

        def is_northern(latitude):
            """
            Determines if given latitude is a northern for UTM
            """
            if (latitude < 0.0):
                return 0
            else:
                return 1
        utm_coordinate_system = osr.SpatialReference()
        utm_coordinate_system.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon  
        utm_coordinate_system.SetUTM(get_utm_zone(lon), is_northern(lat))
        wgs84_coordinate_system = utm_coordinate_system.CloneGeogCS() # Clone ONLY the geographic coordinate system 
        wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, utm_coordinate_system) # (<from>, <to>)
        return wgs84_to_utm_transform.TransformPoint(lon, lat, 0) # returns easting, northing, altitude 
Ejemplo n.º 41
0
class Player(QMediaPlayer):
    def __init__(self, parent=None):
        super(Player, self).__init__(parent)
        self.parent = parent
        self.player = QMediaPlayer()
        self.queueList = QMediaPlaylist()
        self.player.setPlaylist(self.queueList)
        self.queueData = []
        self.position = 0
        self.volume = 100

        self.player.mediaStatusChanged.connect(self.qmp_mediaStatusChanged)
        self.player.positionChanged.connect(self.qmp_positionChanged)
        self.player.durationChanged.connect(self.durationChanged)
        self.queueList.currentIndexChanged.connect(self.playlistPosChanged)

    def add(self, data):
        """Add track to the queue"""
        queueData = {
            'pc_title': data['pc_title'],
            'title': data['title'],
            'url': data['url'],
            'date': data['date_format'],
            'description': data['description']
        }
        self.queueData.append(queueData)
        self.queueList.addMedia(QMediaContent(QUrl(data['url'])))

    def playPause(self):
        icon = QIcon.fromTheme("media-playback-pause")

        if self.player.state() == QMediaPlayer.StoppedState:
            if self.player.mediaStatus() == QMediaPlayer.NoMedia:
                if self.queueList.mediaCount() != 0:
                    self.player.play()
            elif self.player.mediaStatus() == QMediaPlayer.LoadedMedia:
                self.queueList.setCurrentIndex(self.position)
                self.player.play()
            elif self.player.mediaStatus() == QMediaPlayer.BufferedMedia:
                self.player.play()
        elif self.player.state() == QMediaPlayer.PlayingState:
            icon = QIcon.fromTheme("media-playback-start")
            self.player.pause()
        elif self.player.state() == QMediaPlayer.PausedState:
            self.player.play()

        self.parent.playBtn.setIcon(icon)

    def startPlay(self):
        data = self.queueData[0]
        self.queueList.setCurrentIndex(0)
        self.parent.curPCLabel.setText(data['pc_title'])
        self.parent.curTrackName.setText(data['title'])
        self.player.play()
        icon = QIcon.fromTheme("media-playback-pause")
        self.parent.playBtn.setIcon(icon)

    def stop(self):
        self.player.stop()
        icon = QIcon.fromTheme("media-playback-start")
        self.parent.playBtn.setIcon(icon)

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

    def durationChanged(self, duration):
        total_time = '0:00:00'
        duration = self.player.duration()
        total_time = ms_to_time(duration)
        self.parent.timeSlider.setMaximum(duration)
        self.currentTrackDuration = duration
        self.parent.totalTimeLabel.setText(total_time)

    def qmp_mediaStatusChanged(self, status):
        icon = QIcon.fromTheme("media-playback-pause")
        if self.player.state() == QMediaPlayer.StoppedState:
            icon = QIcon.fromTheme("media-playback-start")
        elif self.player.state() == QMediaPlayer.PausedState:
            icon = QIcon.fromTheme("media-playback-start")

        self.parent.playBtn.setIcon(icon)

    def qmp_positionChanged(self, position, senderType=False):
        self.currentTime = position
        current_time = '0:00:00'

        if position != -1:
            current_time = ms_to_time(position)
            self.parent.timeLabel.setText(current_time)

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

    def playlistPosChanged(self):
        pos = self.queueList.currentIndex()
        data = self.queueData[pos]
        self.parent.curPCLabel.setText(data['pc_title'])
        self.parent.curTrackName.setText(data['title'])
        windowTitle = '{0} - {1}'.format(data['pc_title'], data['title'])
        self.parent.setWindowTitle(windowTitle)
        if self.queueList.mediaCount() > 1:
            if pos < self.queueList.mediaCount() - 1:
                self.parent.queueNextBtn.setEnabled(True)
            else:
                self.parent.queueNextBtn.setEnabled(False)

            if pos > 0:
                self.parent.queuePrevBtn.setEnabled(True)
            else:
                self.parent.queuePrevBtn.setEnabled(False)

            if pos < self.queueList.mediaCount():
                prevPos = 0
                if self.position < pos:
                    prevPos = pos - 1
                else:
                    prevPos = pos + 1
                prevItem = self.parent.queueList.item(prevPos)
                prevWidget = self.parent.queueList.itemWidget(prevItem)
                if prevItem:
                    prevWidget.statusIcon.setPixmap(QPixmap())

        self.position = pos
        item = self.parent.queueList.item(pos)
        widget = self.parent.queueList.itemWidget(item)
        if widget:
            icon = QIcon.fromTheme("media-playback-start")
            widget.statusIcon.setPixmap(icon.pixmap(16, 16))

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

    def rev10Secs(self):
        position = self.player.position()
        new_pos = position - 10000
        self.player.setPosition(new_pos)

    def for10Secs(self):
        position = self.player.position()
        new_pos = position + 10000
        self.player.setPosition(new_pos)

    def delete(self, position):
        """ Delete the track and her data from position"""
        self.queueData.pop(position)
        self.queueList.removeMedia(position)
        if (position == self.position):
            self.playlistPosChanged()
Ejemplo n.º 42
0
class NewProject(QtWidgets.QWidget, Ui_NewProject):
    
    def __init__(self,projectfile,MainWidget):
        QtWidgets.QWidget.__init__(self)
        self.setupUi(self)
        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.Main = MainWidget
        self.iface = self.Main.iface
        self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolume))
        self.replayPlay_pushButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPlay))
        if projectfile.split('.')[-1] =="vgp":
            self.projectfile = projectfile
        else:
            self.projectfile = projectfile +'.vgp'   
        self.videofile = None
        self.GPXfile = None
        self.GPXList = None
        self.fps = None
        self.RealFps = None
        self.DB = None
        self.player = QMediaPlayer()
        self.player.setVideoOutput(self.video_frame_2)
        self.player.durationChanged.connect(self.durationChanged)
        self.player.positionChanged.connect(self.positionChanged)
        self.player.stateChanged.connect(self.mediaStateChanged)
        self.toolButton_3.clicked.connect(self.ManageDB)
        self.pushButton_2.clicked.connect(self.Synchronize)
        self.pushButton.clicked.connect(self.SelectVideoGPX)
        self.replayPlay_pushButton.clicked.connect(self.PlayPause)
        self.muteButton.clicked.connect(self.MuteUnmute)
        self.horizontalSlider.sliderMoved.connect(self.setPosition)
        self.toolButton.clicked.connect(self.SkipBackward)
        self.toolButton_2.clicked.connect(self.SkipForward)
        self.SkipBacktoolButton_7.clicked.connect(self.BackwardFrame)
        self.SkipFortoolButton_8.clicked.connect(self.ForwardFrame)
             
    def closeEvent(self, *args, **kwargs):
        self.player.stop()
        
        return QtWidgets.QWidget.closeEvent(self, *args, **kwargs)  
    
    def mediaStateChanged(self, state):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.replayPlay_pushButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.replayPlay_pushButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaPlay))
             
    def Synchronize(self):
        TimeItem = self.comboBox.currentIndex()
        duration = self.player.duration()
        position = self.player.position()
        VideoPartLen = round((duration-position) / 1000) 
        GpxPartition = self.GPXList[TimeItem:VideoPartLen+TimeItem]
        outputFile = open(self.projectfile ,'w')
        if self.DB == None:
            outputFile.write('VideoGis Project v0.1 DO NOT MODIFY'+
                             '\nVideo file location = ' +self.videofile+
                             '\nVideo start at msecond: '+
                              str(self.player.position())+
                              ' #fps = '+str(self.RealFps)+
                              '\nDB = None'+
                              '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time  \n')
        else:
            outputFile.write('Video file location = ' +self.videofile+
                             '\nVideo start at msecond: '+
                              str(self.player.position())+
                              ' #fps = '+str(self.RealFps)+
                              '\nDB = '+str(self.DB.dataProvider().dataSourceUri().split('|')[0])+
                              '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time  \n')    
        Counter = 0
        for x in GpxPartition:
            if Counter != 0:
                ActualLatitude = x[1][0]
                ActualLongitude = x[1][1]
                PreviousLatitude = GpxPartition[Counter-1][1][0]
                PreviousLongitude = GpxPartition[Counter-1][1][1]
                GeodesicCalcolus = Geodesic.WGS84.Inverse(PreviousLatitude, PreviousLongitude, ActualLatitude, ActualLongitude)
                Speed = GeodesicCalcolus['s12'] /1
                Course = GeodesicCalcolus['azi2']
                if Course < 0:
                    Course += 360
                Ele = x[1][2]
                Time = x[1][3]
                Counter = Counter + 1
            else:
                ActualLatitude = x[1][0]
                ActualLongitude = x[1][1]
                PreviousLatitude = GpxPartition[Counter+1][1][0]
                PreviousLongitude = GpxPartition[Counter+1][1][1]
                GeodesicCalcolus = Geodesic.WGS84.Inverse(ActualLatitude, ActualLongitude, PreviousLatitude, PreviousLongitude)
                Speed = GeodesicCalcolus['s12'] * 1
                Course = GeodesicCalcolus['azi2']
                if Course < 0:
                    Course += 360
                Ele = x[1][2]
                Time = x[1][3]
                Counter = Counter + 1  
            outputFile.write(str(ActualLatitude)+' '+str(ActualLongitude)+' '+str(Ele)+' '+str(Speed)+' '+str(Course)+' '+str(Time)+'\n')    
        outputFile.close() 
        self.Main.LoadProjFromNew(self.projectfile)
        if os.name == 'nt':
            os.remove (self.tmp)
        self.close()
         
    def SelectVideoGPX(self):
        if os.name == 'nt':
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/ffmpeg.exe'
            versione = 'ffmpeg.exe'
        else:
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            versione = 'ffmpeg'
        if os.path.exists(ffmpeg) == True:
            self.comboBox.clear()
            if self.player.state() == QMediaPlayer.PlayingState:
                self.player.pause()    
            self.videofile = None
            self.GPXfile = None
            options = QFileDialog.Options()
            options |= QFileDialog.DontUseNativeDialog
            self.videofile, _ = QFileDialog.getOpenFileName(self,"Select Video File", "","All Files (*);;Video File (*.mp4 *.avi *.ogv)", options=options)
            if self.videofile:        
                self.GPXfile, _ = QFileDialog.getOpenFileName(self,"Select GPX file", "","All Files (*);;Video File (*.gpx)", options=options)
                if self.GPXfile:
                    self.ParseGpx(self.GPXfile)
                    self.LoadVideo(self.videofile)
                    self.replayPosition_label.setText( "-:- / -:-")
        else:
            ret = QMessageBox.warning(self, "Warning", 'missing ffmpeg binaries, please download it from https://github.com/sagost/VideoUavTracker/blob/master/FFMPEG/'+versione+' and paste it in /.qgis3/python/plugins/Video_UAV_Tracker/FFMPEG/ ', QMessageBox.Ok)
            self.close()
            
    def ParseGpx(self,GPXfile):
        gpx = parse(GPXfile)
        track = gpx.getElementsByTagName("trkpt")
        GPXList = []
        Error = 0
        GpxProgressiveNumber = 0
        Timestamp = 'Segnaposto'
        for name in track:
            dict = {'Lat': 0, 'Lon': 0, 'Ele': 0, 'Time':0}

            a = (name.toprettyxml(indent = '') ).split()
            for x in a:
                if x.find('lat') == 0:
                    lat = float(x.split('"')[1])
                    dict['Lat'] = float(x.split('"')[1])    
                elif x.find('lon') == 0:
                    lon = float(x.split('"')[1])
                    dict['Lon'] = float(x.split('"')[1])    
                elif x.find('<ele>') == 0:
                    dict['Ele'] = float(x[5:-6])   
                elif x.find('<time>') == 0:
                    
                    try:
                        
                        gpxtime = time.strftime('%Y-%m-%dT%H:%M:%S.%fZ',time.strptime(x[6:-7], '%Y-%m-%dT%H:%M:%S.%fZ'))
                        dict['Time']= x[6:-7]
                        
                    except ValueError:
                        try:
                            gpxtime = time.strftime('%Y-%m-%dT%H:%M:%SZ',time.strptime(x[6:-7],'%Y-%m-%dT%H:%M:%SZ'))
                            dict['Time']= x[6:-7]
                            
                        except ValueError:
                            try:
                                gpxtime = time.strftime('%Y-%m-%dT%H:%M:%S',time.strptime(x[6:-7],'%Y-%m-%dT%H:%M:%S'))
                                dict['Time']= x[6:-7]
                            except ValueError:
                                try:
                                    gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-7],'%Y-%m-%dT%H.%M.%S')) 
                                    dict['Time']= x[6:-7]
                                             
                                except ValueError:
                                    try:
                                        gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-13],'%Y-%m-%dT%H.%M.%S'))
                                        dict['Time']= x[6:-13] 
                                 
                                    except ValueError:
                                        try:
                                            gpxtime = time.strftime('%Y-%m-%dT%H.%M.%S',time.strptime(x[6:-13],'%Y-%m-%dT%H:%M:%S'))
                                            dict['Time']= x[6:-13]
                                           
                                        except ValueError:
                                            Error = 1
                                            FormatoErrore = str(x)
            
            if dict['Time'] != Timestamp:               
                Point = [dict['Lat'],dict['Lon'],dict['Ele'],dict['Time']]
                self.comboBox.addItem(str(GpxProgressiveNumber) + '-'+gpxtime )    
                GPXList.append([GpxProgressiveNumber,Point])
                GpxProgressiveNumber = GpxProgressiveNumber + 1
                Timestamp = dict['Time'] 
            else:
                Timestamp = dict['Time']
                
        if Error == 0:
            self.GPXList = GPXList
        else:
            ret = QMessageBox.warning(self, "Warning", FormatoErrore +'  UNKOWN GPX TIME FORMAT - ABORTED', QMessageBox.Ok)  
            self.close
        
    def LoadVideo(self,videofile):
        fps = self.getVideoDetails(str(videofile))
        self.RealFps = float(fps)
        self.fps = (1 / self.RealFps )*1000
        url = QUrl.fromLocalFile(str(self.videofile))
        mc = QMediaContent(url)
        self.player.setMedia(mc)
        self.player.play()
          
    def setPosition(self, position):
        self.player.setPosition(position*1000)   
    
    def durationChanged(self, duration):
        duration /= 1000
        self.horizontalSlider.setMaximum(duration)

    def secTotime(self,seconds): 
            m, s = divmod(seconds, 60)
            h, m = divmod(m, 60)
            return "%d:%02d:%02d" % (h, m, s)
           
    def positionChanged(self, progress):
        duration = self.player.duration()
        totalTime = self.secTotime(duration/1000)
        actualTime = self.secTotime(progress/1000)
        self.replayPosition_label.setText(actualTime + ' / '+totalTime)
        progress /= 1000
        if not self.horizontalSlider.isSliderDown():
            self.horizontalSlider.setValue(progress) 
               
    def MuteUnmute(self):
        if self.player.mediaStatus() == 6 :
            if self.player.isMuted() == 1:
                self.player.setMuted(0)
                self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolume))
            elif self.player.isMuted() == 0:
                self.player.setMuted(1)
                self.muteButton.setIcon(
                    self.style().standardIcon(QStyle.SP_MediaVolumeMuted))
                                 
    def PlayPause(self):
        if self.player.state() == QMediaPlayer.PlayingState:
            self.player.pause()
        else:
            self.player.play()
    
    def getVideoDetails(self,filepath):
        
        if os.name == 'nt':
            tmp = os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/tmp'
            tmp2 = '"'+tmp+'"'
            filepath2 = '"'+filepath+'"'
            a = open(tmp,'w')
            a.close()
            ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffmpeg.exe'+'"'
            a = os.popen(str(ffmpeg + ' -i '+filepath2+' 2> '+tmp2))
            while os.stat(tmp).st_size < 1500:
                pass
            a = open(tmp,'r')
            lines = a.readlines()
            a.close()
            for l in lines:
                l = l.strip()
                if str(l).startswith("Stream #0:0"):
                    linea = str(l).split(',')[-4]
                    dopo = linea.find('fps')
                    fps = float(linea[0:dopo])
                    self.tmp = tmp
                    return fps
        else:
            tmpf = tempfile.NamedTemporaryFile()
            ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffmpeg'
            os.system(str(ffmpeg)+" -i \"%s\" 2> %s" % (filepath, tmpf.name))
            lines = tmpf.readlines()
            tmpf.close()
            for l in lines:
                l = l.strip()     
                if str(l).startswith("b'Stream #0:0"):
                    linea = str(l).split(',')[-4]
                    dopo = linea.find('fps')
                    fps = float(linea[0:dopo])
                    return fps
         
    def SkipForward(self): 
        position = self.player.position()
        self.player.setPosition(position+1000)
    
    def SkipBackward(self): 
        position = self.player.position()
        self.player.setPosition(position-1000)
    
    def ForwardFrame(self):  
        position = self.player.position()
        self.player.setPosition(position+int(self.fps))
    
    def BackwardFrame(self):
        position = self.player.position()
        self.player.setPosition(position-int(self.fps))

    def ManageDB(self):
        self.player.pause()
        shapeFileFirst,_ =  QFileDialog.getSaveFileName(caption = 'Save shape file', filter = "Esri shp (*.shp)")
        if shapeFileFirst:
            if shapeFileFirst.split('.')[-1] == 'shp':
                shapeFile = shapeFileFirst
            else:
                shapeFile = shapeFileFirst + '.shp'
            try:
                os.remove(shapeFile)
                os.remove(shapeFileFirst.split('.')[0]+'.qpg')
                os.remove(shapeFileFirst.split('.')[0]+'.prj')
                os.remove(shapeFileFirst.split('.')[0]+'.cpg')
                os.remove(shapeFileFirst.split('.')[0]+'.shx')
                os.remove(shapeFileFirst.split('.')[0]+'.dbf')
                
            except OSError:
                pass 
            crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            fields = QgsFields()
            QgsVectorFileWriter(shapeFile, "CP1250", fields, QgsWkbTypes.Point, crs, "ESRI Shapefile")
            EmptyLayer = QgsVectorLayer(shapeFile, shapeFile.split('.')[0].split('/')[-1], 'ogr')
            self.dialoga = TableManager(self.iface, EmptyLayer,self)
            self.dialoga.exec_()
    
    def AcceptNewDB(self,DB):
        self.DB = DB
Ejemplo n.º 43
0
class VideoWindow(QMainWindow):

    def __init__(self, app, parent=None):
        super(VideoWindow, self).__init__(parent)
        self.app = app
        self.setWindowTitle("sofa")
        self.setWindowIcon(QIcon('src/static/img/tofu.png'))
        self.rate = 1
        self.isNewMark = False
        self.openedFile = None
        self.initUI()
        self.set_default_shortcuts()
        self.shortcuts = {}
        self.comm = SignalBus.instance()

    def initUI(self):
        videoWidget = self.create_player()
        self.errorLabel = QLabel()
        self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
                QSizePolicy.Maximum)
        self.create_menu_bar()
        self.wid = QWidget(self)
        self.setCentralWidget(self.wid)
        self.set_layout(videoWidget, self.wid)
        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)

    def create_player(self):
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        videoWidget = QVideoWidget()
        self.clipsWidget = BadClipsWidget()
        self.create_control()

        self.playButton.clicked.connect(self.play)
        self.speedUpButton.clicked.connect(self.speed)
        self.slowDownButton.clicked.connect(self.slow)
        self.adv3Button.clicked.connect(partial(self.advance, 3))
        self.goBack3Button.clicked.connect(partial(self.back, 3))
        self.advanceButton.clicked.connect(partial(self.advance, 10))
        self.goBackButton.clicked.connect(partial(self.back, 10))
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.cutButton.clicked.connect(self.createMark)

        return videoWidget

    def set_default_shortcuts(self):
        self.playButton.setShortcut(QKeySequence(Qt.Key_Space))
        self.speedUpButton.setShortcut(QKeySequence(Qt.Key_Up))
        self.slowDownButton.setShortcut(QKeySequence(Qt.Key_Down))
        self.advanceButton.setShortcut(QKeySequence(Qt.Key_Right))
        self.goBackButton.setShortcut(QKeySequence(Qt.Key_Left))
        self.cutButton.setShortcut(QKeySequence(Qt.Key_C))

    def create_control(self):
        self.playButton = _create_button(
                self.style().standardIcon(QStyle.SP_MediaPlay))
        self.speedUpButton = _create_button(
                self.style().standardIcon(QStyle.SP_MediaSeekForward))
        self.slowDownButton = _create_button(
                self.style().standardIcon(QStyle.SP_MediaSeekBackward))
        self.adv3Button = _create_button(
                self.style().standardIcon(QStyle.SP_ArrowRight))
        self.advanceButton = _create_button(
                self.style().standardIcon(QStyle.SP_MediaSkipForward))
        self.goBack3Button = _create_button(
                self.style().standardIcon(QStyle.SP_ArrowLeft))
        self.goBackButton = _create_button(
                self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        self.cutButton = _create_button(self.style().standardIcon(
            QStyle.SP_MessageBoxCritical))
        self.timeBox = QLabel(format_time(0), self)
        self.timeBox.setAlignment(Qt.AlignCenter)
        self.rateBox = QLabel(str(self.rate) + 'x', self)
        self.rateBox.setAlignment(Qt.AlignCenter)
        self.hlightSliderTips = HlightSliderTipsWidget()
        self.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)

    def create_menu_bar(self):
        openAction = create_action('open.png', '&Open', 'Ctrl+O', 'Open video',
                self.openFile, self)
        saveAction = create_action('save.png', '&Save Clips', 'Ctrl+S',
                'Save anonimized clips', self.saveClips, self)
        exitAction = create_action('exit.png', '&Exit', 'Ctrl+Q', 'Exit',
                self.exitCall, self)

        menuBar = self.menuBar()
        fileMenu = menuBar.addMenu('&File')
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)
        fileMenu.addAction(exitAction)

    def set_layout(self, videoWidget, wid):
        labellingLayout = QVBoxLayout()
        labellingLayout.addWidget(self.clipsWidget)

        controlLayout = self.make_control_layout()

        videoAreaLayout = QVBoxLayout()
        videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        videoAreaLayout.addWidget(videoWidget)
        videoAreaLayout.addLayout(controlLayout)
        videoAreaLayout.addWidget(self.errorLabel)

        layout = QHBoxLayout()
        layout.addLayout(videoAreaLayout, 4)
        layout.addLayout(labellingLayout)

        wid.setLayout(layout)

    def make_control_layout(self):
        buttonsLayout = QHBoxLayout()
        buttonsLayout.setContentsMargins(0, 0, 0, 0)
        buttonsLayout.addWidget(self.timeBox)
        buttonsLayout.addWidget(self.slowDownButton)
        buttonsLayout.addWidget(self.goBackButton)
        buttonsLayout.addWidget(self.goBack3Button)
        buttonsLayout.addWidget(self.playButton)
        buttonsLayout.addWidget(self.adv3Button)
        buttonsLayout.addWidget(self.advanceButton)
        buttonsLayout.addWidget(self.speedUpButton)
        buttonsLayout.addWidget(self.rateBox)
        cutLayout = QHBoxLayout()
        cutLayout.setContentsMargins(0, 0, 0, 0)
        cutLayout.addSpacerItem(QSpacerItem(200, 5, QSizePolicy.Minimum,
            QSizePolicy.Minimum))
        cutLayout.addWidget(self.cutButton)
        cutLayout.addSpacerItem(QSpacerItem(200, 5, QSizePolicy.Minimum,
            QSizePolicy.Minimum))
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.positionSlider)
        layout.addWidget(self.hlightSliderTips)
        layout.addLayout(buttonsLayout)
        layout.addLayout(cutLayout)
        return layout

    def openFile(self):
        self.rawFileName, _ = QFileDialog.getOpenFileName(self, "Open video",
                QDir.homePath())
        if self.rawFileName != '':
            should_process = QMessageBox.question(self.wid, 'Open video',
                    'Do you want to pre process the video?',
                    QMessageBox.Yes | QMessageBox.No)
            if should_process == QMessageBox.Yes:
                self.fileName = TMP_VIDEO_PATH
                process = ProcVideoDialog(self.rawFileName, self.fileName, self)
                self.comm.videoProcessed.connect(self.openMedia)
            else:
                self.fileName = self.rawFileName
                self.processMetaData()
                self.openMedia()


    def processMetaData(self):
        '''
        Get array indicating "suspicious" frames
        '''
        # open metadata file
        self.metaDataFile = self.fileName.rsplit(".", 1)[0] + ".csv"
        # get only the array with "colors" (==0: green; !=0: red)
        self.colorsArray = get_metadata_colors(self.metaDataFile)
        self.hlightSliderTips.setColorsArray(self.colorsArray, useYellow=False)


    @pyqtSlot()
    def openMedia(self):
        self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(self.fileName)))
        self.openedFile = os.path.basename(self.fileName)
        self.setWindowTitle("sofa - " + self.openedFile)
        self.playButton.setEnabled(True)
        self.speedUpButton.setEnabled(True)
        self.slowDownButton.setEnabled(True)
        self.advanceButton.setEnabled(True)
        self.adv3Button.setEnabled(True)
        self.goBackButton.setEnabled(True)
        self.goBack3Button.setEnabled(True)
        self.cutButton.setEnabled(True)
        self.rate = 1

    def exitCall(self):
        if self.openedFile is not None:
            os.remove(self.fileName)
        sys.exit(self.app.exec_())

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

    def slow(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.rate -= 0.5
            # TODO: Workaround pt 1
            # https://forum.qt.io/topic/88490/change-playback-rate-at-...
            # ...runtime-problem-with-position-qmediaplayer/8
            currentPos = self.mediaPlayer.position()
            # TODO: Workaround pt 1
            self.mediaPlayer.setPlaybackRate(self.rate)
            # TODO: Workaround pt 2
            self.mediaPlayer.setPosition(currentPos)
            # TODO: Workaround pt 2: end
            self.rateBox.setText(str(self.rate)+'x')

    def speed(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.rate += 0.5
            # TODO: Workaround pt 1
            # https://forum.qt.io/topic/88490/change-playback-rate-at-...
            # ...runtime-problem-with-position-qmediaplayer/8
            currentPos = self.mediaPlayer.position()
            # TODO: Workaround pt 1
            self.mediaPlayer.setPlaybackRate(self.rate)
            # TODO: Workaround pt 2
            self.mediaPlayer.setPosition(currentPos)
            # TODO: Workaround pt 2: end
            self.rateBox.setText(str(self.rate)+'x')

    def advance(self, t=10):
        currentPos = self.mediaPlayer.position()
        nextPos  = currentPos + t*1000
        self.setPosition(nextPos)

    def back(self, t=10):
        currentPos = self.mediaPlayer.position()
        nextPos  = max(currentPos - t*1000, 0)
        self.setPosition(nextPos)

    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)
        self.hlightSliderTips.setValue(position)
        self.timeBox.setText(format_time(int(position/1000)))

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

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

    def handleError(self):
        self.playButton.setEnabled(False)
        self.speedUpButton.setEnabled(False)
        self.slowDownButton.setEnabled(False)
        self.advanceButton.setEnabled(False)
        self.goBackButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())

    def saveClips(self):
        prefix = os.path.splitext(os.path.basename(self.rawFileName))[0] + \
                '_slice_'
        dirPath = QFileDialog.getExistingDirectory(self, 'Select Dir')
        if dirPath != '':
            try:
                self.errorLabel.setText('Saving clips... please wait')
                video = VideoFileClip(self.fileName)
                marks = self.clipsWidget.get_marks()
                begin_time = 0.0
                for i, m in enumerate(marks):
                    end_time = float(m[0])
                    out_path = os.path.join(dirPath, prefix+str(i)+".mp4")
                    clip = video.subclip(begin_time, end_time)
                    clip.write_videofile(out_path)
                    begin_time = float(m[1])
                end_video = self.mediaPlayer.duration()/1000
                if begin_time < end_video and len(marks) > 0:
                    i = len(marks)
                    out_path = os.path.join(dirPath, prefix+str(i)+".mp4")
                    clip = video.subclip(begin_time)
                    clip.write_videofile(out_path)
                self.errorLabel.setText('Clips saved at ' + dirPath)
                QMessageBox.information(self.wid, 'Sucess',
                        'Clips succesfully saved')
            except:
                self.errorLabel.setText('Error: Could not save file.')
                QMessageBox.warning(self.wid, 'Error',
                        'Could not save file. Check permissions')

    @pyqtSlot()
    def createMark(self):
        state = self.mediaPlayer.state()
        if state == QMediaPlayer.PlayingState or state == \
                QMediaPlayer.PausedState:
            self.clipsWidget.new_mark(self.mediaPlayer.position()/1000,
                    self.isNewMark)
            self.isNewMark = not self.isNewMark
Ejemplo n.º 44
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, parent=None):
        super(VideoPlayer, self).__init__(parent)

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

        videoWidget = QVideoWidget()

        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.positionSlider = QSlider(Qt.Horizontal)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.sliderMoved.connect(self.setPosition)

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

        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.errorLabel)

        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)

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

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

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        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)

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

    def handleError(self):
        self.playButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
Ejemplo n.º 46
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 ""
Ejemplo n.º 47
0
class VideoWindow(QWidget):
    sigTimeChanged = pyqtSignal(object)

    def __init__(self, project=None, parent=None):
        super(VideoWindow, self).__init__(parent)
        self.project = project
        self.setWindowTitle("Video")
        self.mediaPlayer = QMediaPlayer()  #None, QMediaPlayer.VideoSurface)
        self.last_position = 0
        self.position_on_new_file = 0
        self.duration = -1
        self.waiting_for_file = False
        self.media_state_before_file_transition = self.mediaPlayer.state()
        self.video_time_offset = 0.0

        self.play_icon = QIcon(play_icon_file)
        self.clock_icon = QIcon(clock_icon_file)
        self.pause_icon = QIcon(pause_icon_file)

        videoWidget = QVideoWidget()
        self.videoWidget = videoWidget
        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setIcon(self.play_icon)
        self.playButton.clicked.connect(self.play)

        self.timeOffsetButton = QPushButton()
        self.timeOffsetButton.setIcon(self.clock_icon)
        self.timeOffsetButton.clicked.connect(self.setTimeOffset)

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

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

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

        layout = QVBoxLayout()
        layout.addWidget(videoWidget)
        layout.addLayout(controlLayout)
        layout.addWidget(self.errorLabel)  # Hide error Label

        # Set widget to contain window contents
        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.mediaStatusChanged.connect(self.mediaStatusChanged)
        self.mediaPlayer.error.connect(self.handleError)
        self.mediaPlayer.setNotifyInterval(40)  # 25 fps

        if self.project is None:
            self.current_time_range = [0, 0]
            self.current_file = ''
            # self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(self.current_file)))
            # self.playButton.setEnabled(True)
            # self.mediaPlayer.play()
        elif self.project.current_animal.video_files:
            self.current_file = self.project.current_animal.video_files[0]
            self.current_time_range = [
                self.project.current_animal.video_init_time[0],
                self.project.current_animal.video_init_time[0] +
                self.project.current_animal.video_duration[0]
            ]
            self.mediaPlayer.setMedia(
                QMediaContent(QUrl.fromLocalFile(self.current_file)))
            self.playButton.setEnabled(True)
        else:
            self.current_file = ''
            self.current_time_range = [0, 0]

    def setTimeOffset(self):
        offset, okpressed = QInputDialog.getDouble(
            self,
            'Video time offset',
            'Offset video time position (seconds)',
            value=self.video_time_offset)
        if okpressed:
            self.video_time_offset = offset
            current_position = self.current_time_range[
                0] + self.last_position / 1000
            self.setGlobalPosition(0)
            self.setGlobalPosition(current_position)

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

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

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

    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.pause_icon)
        else:
            self.playButton.setIcon(self.play_icon)

    def positionChanged(self, position):
        # Connected to video player
        # print('positionChanged',position,self.last_position,self.waiting_for_file,self.duration,self.current_time_range)
        # if self.duration == -1:
        #     print('positionChanged: no file - duration ==-1')
        #     return
        # if self.waiting_for_file:
        #     print('positionChanged: Waiting to load file')
        #     return
        # if position == 0:
        #     print('positionChanged: avoiding setting positions to 0')
        #     return
        if position == 0 or self.waiting_for_file or self.duration == -1 or position == self.last_position:
            # avoid position changes on file transitions or repeated signals on same position
            return
        if position < self.duration - 40:  # avoid time changes when switching files
            self.last_position = position
            self.positionSlider.setValue(position)
            self.sigTimeChanged.emit(position / 1000 +
                                     self.current_time_range[0])
        else:  # position is at the end of file - try to switch to next file
            pos = self.current_time_range[1] + .04
            print('Trying to jump to next file', self.current_time_range[1],
                  self.duration, pos)
            self.setGlobalPosition(pos)

    def durationChanged(self, duration):
        # print('duration changed',duration)
        self.duration = duration
        self.positionSlider.setRange(0, duration)
        self.mediaPlayer.setPosition(
            self.position_on_new_file
        )  # if duration changes avoid the position going back to 0

    def setPosition(self, position):
        # connected to slider
        # print('setPosition',position)
        self.mediaPlayer.setPosition(
            position)  #  milliseconds since the beginning of the media

    def setGlobalPosition(self, pos):
        # Connected to project main model sigTimeChanged
        # open the right media
        if self.current_time_range[0] <= pos <= self.current_time_range[
                1]:  # correct file opened
            position = int((pos - self.current_time_range[0]) * 1000)
            if self.mediaPlayer.state() == QMediaPlayer.PlayingState and abs(
                    position - self.last_position) < 200:
                # skip position setting by signal of main model to ensure smooth video plaback
                return
            # go to correct relative position
            self.mediaPlayer.setPosition(position)  # UNIX time
            return
        else:
            for i, file in enumerate(self.project.current_animal.video_files
                                     ):  # search for file to open
                arange = [
                    self.project.current_animal.video_init_time[i] +
                    self.video_time_offset,
                    self.project.current_animal.video_init_time[i] +
                    self.project.current_animal.video_duration[i] +
                    self.video_time_offset
                ]
                if (arange[0] <= pos <= arange[1]):
                    print('Changing video file: ', file)
                    self.current_file = file
                    self.errorLabel.setText("File: " + self.current_file)
                    self.current_time_range = arange
                    self.waiting_for_file = True
                    self.media_state_before_file_transition = self.mediaPlayer.state(
                    )
                    self.mediaPlayer.stop()
                    position = (pos - self.current_time_range[0]) * 1000
                    self.position_on_new_file = int(position)
                    # print('Changing position_on_new_file: ', self.position_on_new_file,pos)
                    self.mediaPlayer.setMedia(
                        QMediaContent(QUrl.fromLocalFile(file)))
                    self.playButton.setEnabled(True)
                    # self.duration = (arange[1]-arange[0])*1000
                    return
        print('no video file found for current position')
        self.errorLabel.setText("No video file found for current position")
        self.mediaPlayer.stop()
        self.mediaPlayer.setMedia(QMediaContent())
        self.current_file = ''
        self.current_time_range = [0, 0]
        # self.duration = 0
        self.playButton.setEnabled(False)
        self.positionSlider.setRange(0, 0)
        self.positionSlider.setValue(0)

    def mediaStatusChanged(self, status):
        if self.waiting_for_file:
            if self.mediaPlayer.mediaStatus() == QMediaPlayer.LoadedMedia:
                self.waiting_for_file = False
                # print('finished loading file')
                # self.mediaPlayer.stop()
                self.mediaPlayer.setPosition(self.position_on_new_file)
                self.mediaPlayer.play()
                time.sleep(.05)
                self.mediaPlayer.pause()
                if self.media_state_before_file_transition == QMediaPlayer.PlayingState:
                    self.mediaPlayer.play()
                # print('finished setting position on new file')

    def handleError(self):
        self.playButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
        print("Video - Error: " + self.mediaPlayer.errorString())
Ejemplo n.º 48
0
class Player(QWidget):
    muted = muted
    auto_play = auto_play
    full_screen = full_screen
    model = Movies
    session = session

    def __init__(self):
        super().__init__()
        self.setGeometry(0, 0, 1560, 300)
        from core.view import BaseView
        self.base_view = BaseView([], self)
        p = self.palette()
        p.setColor(QPalette.Window, Qt.black)
        self.setPalette(p)

    def run_window(self):
        self.base_view.set_data(self.id)
        self.set_setings()
        self.data = self.base_view.data
        self.init_ui()
        self.show()
        self.setWindowTitle(self.data.name)

    def set_star(self, stars, id):
        Star = None
        for star_array in stars:
            if star_array.id == id:
                Star = star_array
        return Star

    def set_setings(self):

        self.save_setings()

        with open('player_setings.JSON') as setings:
            data = json.load(setings)
            self.muted = data['muted']
            self.auto_play = data['auto_play']
            self.full_screen = data['full_screen']

    def save_setings(self):

        array = {
            "muted": self.muted,
            "auto_play": self.auto_play,
            "full_screen": self.full_screen
        }

        json_array = json.dumps(array)

        if Path('player_setings.JSON').is_file() is False:
            f = open('player_setings.JSON', "x")
            f.write(json_array)
            f.close()

    def set_player(self):
        if self.muted:
            self.mute_clicked()
        if self.auto_play:
            self.play_video()
        if self.full_screen:
            self.full_screen_switch()

    def init_ui(self):
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.mediaPlayer.setMedia(
            QMediaContent(QUrl.fromLocalFile(self.data.src)))

        videowidget = QVideoWidget()

        self.playBtn = QPushButton()
        self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playBtn.clicked.connect(self.play_video)

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

        self.show_full_screen_button = QPushButton('Full Screen')
        self.show_full_screen_button.clicked.connect(self.full_screen_switch)

        self.movie_info_button = QPushButton('Movie')
        self.movie_info_button.clicked.connect(self.movie_info)

        if self.data.series:
            self.series_info_button = QPushButton('Series')
            self.series_info_button.clicked.connect(self.series_info)

        self.mute = QPushButton()
        self.mute.setIcon(self.style().standardIcon(QStyle.SP_MediaVolume))
        self.mute.clicked.connect(self.mute_clicked)

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

        hboxLayout = QHBoxLayout()
        hboxLayout.setContentsMargins(20, 20, 20, 10)

        hboxLayout.addWidget(self.playBtn)
        hboxLayout.addWidget(self.slider)
        hboxLayout.addWidget(self.mute)
        hboxLayout.addWidget(self.movie_info_button)

        if self.data.series:
            hboxLayout.addWidget(self.series_info_button)
        hboxLayout.addWidget(self.show_full_screen_button)
        self.set_player()

        self.hboxLayout2 = QHBoxLayout()
        self.hboxLayout2.setContentsMargins(10, 10, 10, 10)

        self.buttons_stars = QButtonGroup()
        self.buttons_series = QButtonGroup()

        self.add_grup_movies_buttons()
        # create vbox layout
        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(videowidget)
        vboxLayout.addLayout(hboxLayout)
        vboxLayout.addLayout(self.hboxLayout2)
        vboxLayout.addWidget(self.label)

        self.setLayout(vboxLayout)

        self.mediaPlayer.setVideoOutput(videowidget)

        # media player signals

        self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
        self.mediaPlayer.positionChanged.connect(self.position_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)

    def series_info(self):
        self.base_view.load_view('series', self.data.series[0])

    def movie_info(self):
        self.base_view.load_view('movies', self.data)

    def buttom_genarator(self, list, fuction, id):
        for button in list.buttons():
            if button is list.button(id):
                fuction(button.data)

    def on_movies_series_play(self, id):
        self.buttom_genarator(self.buttons_series, self.next_series, id)

    def on_movies_star_play(self, id):
        self.buttom_genarator(self.buttons_stars, self.next_star, id)

    def add_grup_movies_buttons(self):
        self.button_series = [
            {
                'button': self.on_movies_series_play,
                'obejct': self.buttons_series
            },
        ]

        index = 0
        for series in self.data.series:
            button = QPushButton('next video in series ' + str(series))
            self.hboxLayout2.addWidget(button)
            button.data = series
            self.button_series[0]['obejct'].addButton(button)
            self.button_series[0]['obejct'].buttonClicked[int].connect(
                self.button_series[0]['button'])
            index = index + 1

        self.buttons_star = [
            {
                'button': self.on_movies_star_play,
                'obejct': self.buttons_stars
            },
        ]

        index = 0
        for star in self.data.stars:
            if len(star.movies) > 3:
                button = QPushButton('next video with star ' + str(star))
                self.hboxLayout2.addWidget(button)
                button.data = star
                self.buttons_star[0]['obejct'].addButton(button)
                self.buttons_star[0]['obejct'].buttonClicked[int].connect(
                    self.buttons_star[0]['button'])
            index = index + 1

    def mute_clicked(self):
        if self.mediaPlayer.isMuted() is False:
            icon = QStyle.SP_MediaVolumeMuted
            self.mediaPlayer.setMuted(True)
            self.muted = True
        else:
            icon = QStyle.SP_MediaVolume
            self.mediaPlayer.setMuted(False)
            self.muted = False

        self.mute.setIcon(self.style().standardIcon(icon))

    def next_series(self, series):
        movies_in_series = self.data.series[0].movies
        self.close()
        self.base_view.load_view('play', self.faind_item(movies_in_series))

    def next_star(self, star):
        star = self.set_star(self.data.stars, star.id)
        movies_with_star = star.movies
        self.close()
        self.base_view.load_view('play', self.faind_item(movies_with_star))

    def faind_item(self, array):
        def faind_item_greater_then_actual_item(array, math_index):
            index_item = 0
            for item in array:
                if index_item > math_index:
                    return index_item
                elif math_index == len(array) - 1:
                    return 0
                index_item = index_item + 1

        math_index = ''
        index_in_array = 0
        for item in array:
            if self.data.id == item.id:
                math_index = index_in_array
            index_in_array = index_in_array + 1

        next_item = faind_item_greater_then_actual_item(array, math_index)
        return array[next_item]

    def full_screen_switch(self):
        if self.isFullScreen() is False:
            self.showFullScreen()
            self.full_screen = True
        else:
            self.showNormal()
            self.full_screen = False

    def mute_switch(self):
        self.changeMuting.emit(not self.muted)

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

    def mediastate_changed(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            icon = QStyle.SP_MediaPause

        else:
            icon = QStyle.SP_MediaPlay

        self.playBtn.setIcon(self.style().standardIcon(icon))

    def position_changed(self, position):
        self.slider.setValue(position)

    def duration_changed(self, duration):
        self.slider.setRange(0, duration)

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

    def handle_errors(self):
        self.playBtn.setEnabled(False)
        self.label.setText("Error: " + self.mediaPlayer.errorString())

    def closeEvent(self, QCloseEvent):
        os.remove("player_setings.JSON")
        self.save_setings()
        self.mediaPlayer.stop()
Ejemplo n.º 49
0
class VideoWindow(QMainWindow):
    start_time = 0.0

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

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

        videoWidget = QVideoWidget()

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        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.errorLabel = QLabel()
        self.errorLabel.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Maximum)

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

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

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

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

        start_time = time.time()

        # Create side layout
        mainLayout = QHBoxLayout()

        self.label = QtWidgets.QLabel("Faces: ")
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel("Total: ")
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel("Tempo: %.2f" %
                                        (time.time() - start_time))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel("")
        self.label_4.setObjectName("Duração: ")

        sideLayout = QVBoxLayout()
        sideLayout.setContentsMargins(0, 50, 0, 130)
        sideLayout.addWidget(self.label)
        sideLayout.addWidget(self.label_2)
        sideLayout.addWidget(self.label_3)
        sideLayout.addWidget(self.label_4)

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

        layout = QVBoxLayout()
        layout.setContentsMargins(150, 20, 20, 50)
        layout.addWidget(videoWidget)
        layout.addLayout(controlLayout)
        layout.addWidget(self.errorLabel)

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

        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)

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

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

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

    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)

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

    def handleError(self):
        self.playButton.setEnabled(False)
        self.errorLabel.setText("Error: " + self.mediaPlayer.errorString())
Ejemplo n.º 50
-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()