Beispiel #1
0
class PlayManager(QWidget):

    NO_PLAYING_SONG = "没有正在播放的歌曲"

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

        self.player = QMediaPlayer(self)
        self.player.setAudioRole(QAudio.MusicRole)

        self.player.durationChanged.connect(self.duration_changed)
        self.player.positionChanged.connect(self.position_changed)
        self.player.mediaStatusChanged.connect(self.status_changed)
        self.player.bufferStatusChanged.connect(self.buffering_progress)
        self.player.stateChanged.connect(self.state_changed)
        self.player.error[QMediaPlayer.Error].connect(
            self.display_error_message)

        self.play_control = PlayControl(layout, parent)
        self.play_control.set_state(self.player.state())
        self.play_control.play.connect(self.player.play)
        self.play_control.pause.connect(self.player.pause)
        self.play_control.stop.connect(self.player.stop)

        self.player.stateChanged.connect(self.play_control.set_state)

        self.song_label = QLabel()
        self.song_label.setText(self.NO_PLAYING_SONG)
        self.song_label.setWordWrap(True)

        song_grid = QGridLayout(parent)
        song_grid.addWidget(self.song_label, 0, 0)

        self.duration_label = QLabel()
        self.duration_label.setText("00:00 / 00:00")
        self.slider = QSlider(Qt.Horizontal, parent)
        self.slider.setRange(0, self.player.duration() / 1000)
        self.slider.sliderMoved.connect(self.seek)
        progress_layout = QHBoxLayout(parent)
        progress_layout.insertWidget(0, self.duration_label)
        progress_layout.insertWidget(0, self.slider)
        song_grid.addLayout(progress_layout, 1, 0)

        self.status_label = QLabel()
        song_grid.addWidget(self.status_label, 2, 0)

        layout.addLayout(song_grid)

        if not self.is_player_available():
            QMessageBox.warning(self, "警告", "QMediaPlayer 对象无可用的服务")
            return

        self.song = None

    def is_player_available(self):
        return self.player.isAvailable()

    def add_to_play(self, spider, song):
        self.song = song
        spider.get_song_url(song)
        url = song.url
        if url is None or len(url) == 0:
            return
        req = QNetworkRequest(QUrl(url))
        req.setHeader(QNetworkRequest.UserAgentHeader,
                      HttpRequestConfig.CHROME_USER_AGENT)
        self.player.setMedia(QMediaContent(req))

    def duration_changed(self, duration):
        self.duration = int(duration / 1000)
        self.slider.setMaximum(self.duration)
        t = "00:00 / %s" % (self.song.get_time())
        self.duration_label.setText(t)

    def position_changed(self, progress):
        if not self.slider.isSliderDown():
            self.slider.setValue(int(progress / 1000))

        self.update_duration_info(int(progress / 1000))

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

    def state_changed(self, state):
        if QMediaPlayer.PlayingState == state \
                or QMediaPlayer.PausedState == state:
            self.song_label.setText("%s - %s" %
                                    (self.song.get_singers(), self.song.name))
        else:
            self.song_label.setText(self.NO_PLAYING_SONG)

    def status_changed(self, status):
        if QMediaPlayer.UnknownMediaStatus == status \
                or QMediaPlayer.NoMedia == status \
                or QMediaPlayer.LoadedMedia == status \
                or QMediaPlayer.BufferedMedia == status:
            self.set_status_info("")
        elif QMediaPlayer.LoadingMedia == status:
            self.set_status_info("加载中...")
        elif QMediaPlayer.BufferingMedia == status:
            self.set_status_info("缓存中...")
        elif QMediaPlayer.StalledMedia == status:
            self.set_status_info("等待中...")
        elif QMediaPlayer.EndOfMedia == status:
            QApplication.alert(self)
        elif QMediaPlayer.InvalidMedia == status:
            self.display_error_message()

    @pyqtSlot(int)
    def buffering_progress(self, progress):
        if self.player.mediaStatus() == QMediaPlayer.StalledMedia:
            self.set_status_info("等待中 %d%%" % (progress, ))
        else:
            self.set_status_info("缓存中 %d%%" % (progress, ))

    def set_status_info(self, info):
        self.status_label.setText(info)

    def display_error_message(self):
        self.set_status_info(self.player.errorString())

    def update_duration_info(self, current_info):
        s = time.strftime("%M:%S", time.gmtime(current_info))
        t = "%s / %s" % (s, self.song.get_time())
        self.duration_label.setText(t)
Beispiel #2
0
class Control:
    """A class that handles the logic behind the program by manipulating the GUI classes
    and calling their methods in response to received signals."""

    MAGIC = b"\x01\xff"

    def __init__(self, screens: list) -> None:
        self.player = QMediaPlayer()
        self.player.setAudioRole(QAudio.MusicRole)
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)
        self.mainWindow = MainWindow(self, screens)
        self.mainArea = self.mainWindow.centralWidget().upperBox.mainArea
        self.songList = self.mainWindow.centralWidget().upperBox.songList
        self.mediaControlArea = self.mainWindow.centralWidget(
        ).mediaControlArea
        self.mainWindow.show()
        self.library = None
        self.currentSong = None
        self.playing = False
        self.random = False
        self.repeat = 0
        self.volume = 50

        self.volumeChange(self.volume)
        self.mediaControlArea.volumeControl.setValue(self.volume)

        self.mainTimer = QTimer()
        self.mainTimer.setInterval(100)
        self.mainTimer.timeout.connect(self.updateSongProgress)
        self.mainTimer.start()

        self.libraryUpdateTimer = QTimer()
        self.libraryUpdateTimer.setInterval(15_000)
        self.libraryUpdateTimer.timeout.connect(self.updateLibrary)
        self.libraryUpdateTimer.start()

        self._connection = None
        self.connections()

        self.displayedType = None
        self.displayedName = None
        self.types = None
        self.songListWidth = None
        values = self.load()
        if values:
            self.mainWindow.setGeometry(*values)
            self.volumeChange(self.volume)
            self.mediaControlArea.volumeControl.setValue(self.volume)

        self.setUpTimer = QTimer()
        self.setUpTimer.setInterval(20)
        self.setUpTimer.setSingleShot(True)
        self.setUpTimer.timeout.connect(self.setAreas)
        self.setUpTimer.start()

    def connections(self):
        self.player.currentMediaChanged.connect(self.updateCurrentSong)
        self.player.durationChanged.connect(self.updateSongProgressRange)
        self.player.stateChanged.connect(self.playerStatusChanged)
        self.mediaControlArea.previousButton.click.connect(
            self.playlist.previous)
        self.mediaControlArea.repeatButton.click.connect(
            self.repeatButtonClick)
        self.mediaControlArea.stopButton.click.connect(self.stopButtonClick)
        self.mediaControlArea.playButton.click.connect(self.playButtonClick)
        self.mediaControlArea.randomButton.click.connect(
            self.randomButtonClick)
        self.mediaControlArea.nextButton.click.connect(self.playlist.next)
        self.mediaControlArea.muteButton.click.connect(self.mute)
        self.mediaControlArea.songProgress.sliderMoved.connect(
            self.songProgressMove)
        self.mediaControlArea.volumeControl.sliderMoved.connect(
            self.volumeChange)

    def setAreas(self) -> None:
        """Called after the GUI is created to provide user with a feedback
        that the program is running in case a larger amount of songs will be added
        when the Library class is initialized."""
        # TODO add a tooltip that will notify the user larger amount of songs is being loaded
        #  (freezes the program as the execution moves to the Library class.)
        self.library = library.Library()
        self.types = {
            "artist": self.library.getSongsForArtist,
            "album": self.library.getSongsForAlbum,
            "playlist": self.library.getSongsForPlaylist
        }
        self.mainArea.setAreas(self.library)
        self.setUpTimer.deleteLater()
        self.setUpTimer = None
        self.getSongs(self.displayedType, self.displayedName)
        if self.songListWidth is not None:
            songListGeometry = self.songList.geometry()
            self.songList.preferredWidth = songListGeometry.width(
            ) - self.songListWidth
            self.mainWindow.centralWidget().upperBox.line.resizeWidgets(
                songListGeometry.width() - self.songListWidth)

    def updateLibrary(self) -> None:
        self.library.update()
        self.mainArea.updateView(self.library)

    def updateCurrentSong(self) -> None:
        """Update all areas that may display information about the currently
        playing song - SongList, Now Playing tab, BottomBox"""
        media = self.player.currentMedia()
        self.currentSong = media.request().url().toLocalFile().replace(
            "/", "\\")
        if self.currentSong in self.library.library:
            self.songList.updateActiveSong(self.currentSong)
            self.mainArea.updateActiveSong(self.playlist.currentIndex())
            songEntry = self.library.library[self.currentSong]
            self.mediaControlArea.updateSongInfo(
                f"{songEntry[ARTIST]} - {songEntry[NAME]}")

    def updateSongProgressRange(self) -> None:
        """Updates the range of the slider that represents the song position."""
        self.mediaControlArea.updateSongProgressRange(self.player.duration())

    def playerStatusChanged(self) -> None:
        """Used to properly update the player look after the current playlist has finished."""
        index = self.playlist.currentIndex()
        if index == -1:
            self.stopButtonClick()

    def getSongs(self, isType: str, name: str) -> None:
        """Retrieves the songs for a given artist, album or playlist based on type
        and passes the resulting list to the SongList class."""
        if isType is None:
            isType = self.displayedType
        if name is None:
            name = self.displayedName
        orderBy = self.songList.buttonOrderBy.text()
        reverse = True if self.songList.buttonOrderReverse.text() == chr(
            0x25bc) else False
        listForType = self.types[isType](name, orderBy, reverse)
        playlist = None
        if isType == "playlist":
            playlist = name
        if len(listForType) == 0:
            artists = self.library.artists
            if len(artists):
                listForType = self.library.getSongsForArtist(artists[0])
        self.songList.updateSongList(listForType, self.library.library,
                                     self.currentSong, playlist, isType)
        self.displayedType = isType
        self.displayedName = name

    def playSongList(self, song: str = None) -> None:
        """Called when user double-clicks on an artist/album/playlist widget or a song
        in right-hand side panel."""
        self.playlist.clear()
        index = 0
        loopIndex = 0
        for songPath in self.songList.garbageProtector:
            if song == songPath:
                index = loopIndex
            self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(songPath)))
            loopIndex += 1
        if self.playlist.isEmpty():
            return
        self.player.play()
        if index > 0:
            self.playlist.setCurrentIndex(index)
        self.playing = True
        self.mediaControlArea.playButton.updatePictures(
            bottom.pausePixmap, bottom.pauseHoverPixmap, False)
        self.mainArea.setNowPlayingArea(self.library)
        self.mainArea.updateActiveSong(self.playlist.currentIndex())

    def playSongWidget(self,
                       songPath: str,
                       afterCurrent: bool = False) -> None:
        if afterCurrent:
            index = self.playlist.currentIndex() + 1
            self.playlist.insertMedia(
                index, QMediaContent(QUrl.fromLocalFile(songPath)))
        else:
            self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(songPath)))
        self.mainArea.setNowPlayingArea(self.library)
        self.mainArea.updateActiveSong(self.playlist.currentIndex())
        self.playing = True

    def removeFromNowPlaying(self, widget) -> None:
        if self.playlist.mediaCount() > 1:
            for row in range(self.mainArea.nowPlayingLayout.rowCount()):
                for column in range(
                        self.mainArea.nowPlayingLayout.columnCount()):
                    if self.mainArea.nowPlayingLayout.itemAtPosition(
                            row, column).widget() is widget:
                        self.playlist.removeMedia(row - 1)
                        break
                else:
                    continue
                break
        else:
            self.stopButtonClick()
            self.playlist.clear()
        self.mainArea.setNowPlayingArea(self.library)
        if self.playing:
            self.mainArea.updateActiveSong(self.playlist.currentIndex())

    def playMediaWidget(self, isType: str, target: str, startOver: bool,
                        afterCurrent: bool) -> None:
        """Called from MediaWidget - plays all songs for MediaWidget's type and name."""
        if startOver:
            self.playlist.clear()
        if afterCurrent:
            index = self.playlist.currentIndex() + 1
            for songPath in self.types[isType](target):
                self.playlist.insertMedia(
                    index, QMediaContent(QUrl.fromLocalFile(songPath)))
                index += 1
        else:
            for songPath in self.types[isType](target):
                self.playlist.addMedia(
                    QMediaContent(QUrl.fromLocalFile(songPath)))
        if startOver:
            self.player.play()
            self.playing = True
            self.mediaControlArea.playButton.updatePictures(
                bottom.pausePixmap, bottom.pauseHoverPixmap, False)
        self.mainArea.setNowPlayingArea(self.library)
        self.mainArea.updateActiveSong(self.playlist.currentIndex())

    def playFromNowPlaying(self, song: str) -> None:
        """Called when user double-clicks on a song in the Now Playing tab."""
        for n in range(self.playlist.mediaCount()):
            media = self.playlist.media(n)
            if song == media.request().url().toLocalFile().replace("/", "\\"):
                self.playlist.setCurrentIndex(n)
                if not self.playing:
                    self.player.play()
                    self.playing = True
                return

    def createPlaylist(self, playlistName: str) -> None:
        self.library.createPlaylist(playlistName)
        self.mainArea.setMainAreaPlaylists(self.library)

    def addToExistingPlaylist(self, playlist: str, songOrWidget: str,
                              isType: str) -> None:
        if isType in self.types:
            for song in self.types[isType](songOrWidget):
                self.library.addToPlaylist(playlist, song)
        else:
            self.library.addToPlaylist(playlist, songOrWidget)
        self.library.update()

    def removeFromPlaylist(self, playlist: str, song: str) -> None:
        self.library.deleteFromPlaylist(playlist, song)
        self.mainArea.setMainAreaPlaylists(self.library)
        self.library.update()
        self.getSongs("playlist", playlist)

    def renamePlaylist(self, playlistName: str, newPlaylistName: str) -> None:
        self.library.renamePlaylist(playlistName, newPlaylistName)
        self.mainArea.setMainAreaPlaylists(self.library)
        self.library.update()

    def deletePlaylist(self, playlistName: str) -> None:
        self.library.deletePlaylist(playlistName)
        self.mainArea.setMainAreaPlaylists(self.library)
        self.library.update()

    def addWatchedFolder(self, folder: str) -> None:
        """Adds a folder to the Library class. all mp3 files within the folder
        and its sub-folders will be added to the library and accessible to the player."""
        self.library.addFolder(folder.replace("/", "\\"))
        self.mainArea.updateView(self.library)

    def removeWatchedFolder(self, folder: str) -> None:
        """Removes folder from the library, updates view and stops playback if
        the current song was in the now-removed folder."""
        self.library.deleteFolder(folder)
        self.mainArea.updateView(self.library)
        if self.currentSong not in self.library.library:
            self.songList.updateSongList([], [], "", "")
            self.player.stop()
            self.playlist.clear()
            self.mediaControlArea.updateSongInfo("")
            self.songList.nowPlayingSong = None
            self.mainArea.nowPlayingSong = None
            self.playing = False
            self.mediaControlArea.updatePlayButton(self.playing, False)

    def playButtonClick(self, passMove: bool = True) -> None:
        if not self.playing:
            if self.playlist.isEmpty():
                self.playSongList()
                return
            self.playing = True
            self.player.play()
            self.mainArea.updateActiveSong(self.playlist.currentIndex())
            self.songList.updateActiveSong(self.currentSong)
        else:
            self.playing = False
            self.player.pause()
        self.mediaControlArea.updatePlayButton(self.playing, passMove)

    def repeatButtonClick(self) -> None:
        if self.repeat == 0:
            self.repeat = 1
            self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
        elif self.repeat == 1:
            self.repeat = 2
            self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)
        elif self.repeat == 2:
            self.repeat = 0
            self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
        self.mediaControlArea.updateRepeatButton(self.repeat)

    def randomButtonClick(self) -> None:
        if not self.random:
            self.random = True
            self.playlist.setPlaybackMode(QMediaPlaylist.Random)
        else:
            self.random = False
            self.playlist.setPlaybackMode(QMediaPlaylist.Sequential)
        self.mediaControlArea.updateRandomButton(self.random)

    def stopButtonClick(self) -> None:
        self.playing = False
        self.player.stop()
        if self.songList.nowPlayingSong is not None:
            self.songList.nowPlayingSong.clear()
        if self.mainArea.nowPlayingSong is not None:
            self.mainArea.nowPlayingSong.clear()
        self.mediaControlArea.updatePlayButton(self.playing, False)

    def mute(self) -> None:
        if not self.player.isMuted():
            self.player.setMuted(True)
            self.mediaControlArea.showMute()
        else:
            self.player.setMuted(False)
            self.volumeChange(self.volume)

    def volumeChange(self, volume: int) -> None:
        logVolume = QAudio.convertVolume(volume / 100,
                                         QAudio.LogarithmicVolumeScale,
                                         QAudio.LinearVolumeScale) * 100
        self.player.setVolume(logVolume)
        self.volume = volume
        self.mediaControlArea.updateVolumeBar(volume)

    def songProgressMove(self, position: int) -> None:
        self.player.setPosition(position)

    def updateSongProgress(self) -> None:
        position = self.player.position()
        if 0 <= position < 2_000_000_000:
            if self.player.state() > 0:
                self.mediaControlArea.updateSongProgress(position)
                if self.playing:
                    self.songList.activeSongPixmap()
                    self.mainArea.activeSongPixmap()
            else:
                self.mediaControlArea.updateSongProgress(0)

    def disconnect(self):
        self.player.currentMediaChanged.disconnect()
        self.player.durationChanged.disconnect()
        self.player.stateChanged.disconnect()
        self.mediaControlArea.previousButton.click.disconnect()
        self.mediaControlArea.repeatButton.click.disconnect()
        self.mediaControlArea.stopButton.click.disconnect()
        self.mediaControlArea.playButton.click.disconnect()
        self.mediaControlArea.randomButton.click.disconnect()
        self.mediaControlArea.nextButton.click.disconnect()
        self.mediaControlArea.muteButton.click.disconnect()
        self.mediaControlArea.songProgress.sliderMoved.disconnect()
        self.mediaControlArea.volumeControl.sliderMoved.disconnect()

    def close(self) -> None:
        self.disconnect()
        self.player.stop()
        self.mainTimer.stop()
        self.save()

    def save(self) -> None:
        """Called on exit, saves current view, geometry and volume."""
        with gzip.open(r"musicplayer\mpdata", "wb") as fh:
            fh.write(self.MAGIC)
            toBeWritten = struct.pack(f"<h{len(self.displayedType.encode())}s",
                                      len(self.displayedType.encode()),
                                      self.displayedType.encode())
            fh.write(toBeWritten)
            fh.write(self.MAGIC)
            toBeWritten = struct.pack(f"<h{len(self.displayedName.encode())}s",
                                      len(self.displayedName.encode()),
                                      self.displayedName.encode())
            fh.write(toBeWritten)
            fh.write(self.MAGIC)
            geo = self.mainWindow.geometry()
            toBeWritten = struct.pack("<4h", geo.x(), geo.y(), geo.width(),
                                      geo.height())
            fh.write(toBeWritten)
            toBeWritten = struct.pack("<h", self.volume)
            fh.write(toBeWritten)
            toBeWritten = struct.pack("<h", self.songList.width())
            fh.write(toBeWritten)

    def load(self) -> [bool, tuple]:
        """Called on startup, loads view, geometry and volume saved on previous run."""
        try:
            with gzip.open(r"musicplayer\mpdata", "rb") as fh:
                if not fh.read(2) == self.MAGIC:
                    return False
                length = fh.read(2)
                length = struct.unpack("<h", length)[0]
                displayedType = fh.read(length)
                displayedType = struct.unpack(f"<{length}s",
                                              displayedType)[0].decode("utf8")
                if displayedType in ["artist", "album", "playlist"]:
                    self.displayedType = displayedType
                if not fh.read(2) == self.MAGIC:
                    return False
                length = fh.read(2)
                length = struct.unpack("<h", length)[0]
                displayedName = fh.read(length)
                displayedName = struct.unpack(f"<{length}s",
                                              displayedName)[0].decode("utf8")
                if not fh.read(2) == self.MAGIC:
                    return False
                self.displayedName = displayedName
                variables = []
                for n in range(6):
                    var = fh.read(2)
                    var = struct.unpack("<h", var)[0]
                    variables.append(var)
                x, y, width, height, volume, songListWidth = variables
                self.volume = volume
                self.songListWidth = songListWidth
                return x, y, width, height
        except Exception:
            return False
class MyQtApp(multimediaUI.Ui_MainWindow, QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("Multimedia Project")

        self.play_btn.clicked.connect(self.play)
        self.pause_btn.clicked.connect(self.pause)
        self.stop_btn.clicked.connect(self.stop)
        self.play_btn.setEnabled(False)
        self.pause_btn.setEnabled(False)
        self.stop_btn.setEnabled(False)

        #read metadata
        file_meta = open('final.json', "r")
        self.metadata = json.load(file_meta)
        self.num_img = len(self.metadata)
        file_meta.close()

        # synopsis = readrgb.readrgbtoQImage("version2_synopsis.rgb", 352*self.num_img, 288)
        synopsis = readrgb.readrgbtoQImage("final.rgb", 352 * self.num_img,
                                           288)
        #print(self.synopsis.size())
        self.total_length = 120 * self.num_img  # synopsis from 0 to total length
        pixmap_syn = QPixmap.fromImage(synopsis).scaled(
            120 * self.num_img, 1440, Qt.KeepAspectRatio,
            Qt.SmoothTransformation)
        self.synopsis.setPixmap(pixmap_syn)
        self.synopsis.mousePressEvent = self.getPos

        self.sound = QVideoWidget()
        self.sound.setGeometry(QtCore.QRect(859, 10, 111, 21))
        self.sound.setObjectName("sound")

        self.soundPlayer = QMediaPlayer(None, QMediaPlayer.LowLatency)
        self.soundPlayer.setAudioRole(2)

        self.v_thread = Img_Thread(self.updateframe)
        self.v_thread.signal.connect(self.stop)
        self.v_thread.n = 0
        self.v_thread.start()

        self.sound_delay = 0.2

    def play(self):
        #print("play")
        #if self.soundPlayer.state() != QMediaPlayer.PlayingState:
        #print(self.soundPlayer.position()/1000)
        #time.sleep(0.05)
        #print(self.v_thread.isFinished())
        self.thistimestart_frame = self.current_frame - 1
        self.soundPlayer.play()
        time.sleep(self.sound_delay)  # wait for the sound track to play
        # while self.soundPlayer.position() <= 1:
        #     pass
        self.tic = time.perf_counter()
        self.image_thread()
        #self.soundPlayer.play()
        self.play_btn.setEnabled(False)
        self.pause_btn.setEnabled(True)
        self.stop_btn.setEnabled(True)

    def updateframe(self):
        #print(self.current_frame)
        fileName = "image-" + str(self.current_frame).zfill(4) + ".rgb"
        video = readrgb.readrgbtoQImage(self.folderName + fileName)
        pixmap_vdo = QPixmap.fromImage(video)
        ontime = (self.current_frame - self.thistimestart_frame) / 30
        delay = time.perf_counter() - self.tic
        if delay < ontime:
            #if (ontime-delay) > 0.033:
            #    print("long wait", ontime-delay)
            time.sleep(ontime - delay)
        else:
            print("too late", delay - ontime)

        self.video.setPixmap(pixmap_vdo)
        #print(self.current_frame)
        self.current_frame += 1

    def image_thread(self):
        self.v_thread.n = self.end_frame - self.current_frame + 1
        self.v_thread.kill = 0
        self.v_thread.start()

    def pause(self):
        #print("pause")

        #if self.soundPlayer.state() == QMediaPlayer.PlayingState:
        self.soundPlayer.pause()
        self.v_thread.kill = 1

        time.sleep(0.04)
        #print(self.v_thread.isFinished())
        print(self.current_frame)
        self.current_frame = self.soundPlayer.position() * 30 // 1000 + 1
        print(self.current_frame)

        self.play_btn.setEnabled(True)
        self.pause_btn.setEnabled(False)

    def stop(self):
        #print("stop")
        if self.soundPlayer.state() != QMediaPlayer.StoppedState:
            self.soundPlayer.pause()
            #print(self.soundPlayer.position()/1000)
            print(self.soundPlayer.position() / 1000 - self.end_frame / 30)
        self.v_thread.kill = 1
        self.current_frame = self.start_frame
        self.soundPlayer.setPosition(self.start_time)
        self.play_btn.setEnabled(True)
        self.pause_btn.setEnabled(False)
        self.stop_btn.setEnabled(False)

    def show_img(self):
        if self.soundPlayer.state() != QMediaPlayer.StoppedState:
            self.stop()
            self.play_btn.setEnabled(False)
        video = readrgb.readrgbtoQImage("." + self.fileName)
        pixmap_vdo = QPixmap.fromImage(video)

        self.video.setPixmap(pixmap_vdo)
        self.Displaying.setText("Displaying Image: " + self.fileName)

    def play_video(self):
        self.current_frame = self.start_frame
        self.soundPlayer.setMedia(
            QMediaContent(QUrl.fromLocalFile(os.path.abspath(
                self.audio_file))))  # mac
        # self.soundPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(self.audio_file)))
        self.soundPlayer.setPosition(self.start_time)
        fileName = "image-" + str(self.start_frame).zfill(4) + ".rgb"
        video = readrgb.readrgbtoQImage(self.folderName + fileName)
        pixmap_vdo = QPixmap.fromImage(video)
        self.current_frame += 1
        self.video.setPixmap(pixmap_vdo)
        self.Displaying.setText("Displaying Video: " + self.folderName)
        self.play()

    def getfiles(self, idx):
        #print(idx)
        if idx >= self.num_img:
            idx = self.num_img - 1
        tp = self.metadata[idx]["tp"]  # tp = 1: video ; tp = 0: image
        if tp == 1:
            # for video
            self.folderName = "." + self.metadata[idx][
                "folder"]  #"../../576RGBVideo1/"
            # self.folderName = "/Users/luckyjustin/Documents/JustinProject/576Project/CSCI576ProjectMedia/576RGBVideo1/"
            self.start_frame = self.metadata[idx]["start"]  #1
            self.end_frame = self.metadata[idx]["end"]  #1000
            self.start_time = (self.start_frame - 1) * 1000 / 30
            self.audio_file = "." + self.metadata[idx]["audio"]  #"video_1.wav"
            #self.audio_file = "/Users/luckyjustin/Documents/JustinProject/576Project/CSCI576ProjectMedia/video_1.wav"
            #print(self.folderName)
            #print(self.audio_file)
            #print("start frame = " + str(self.start_frame/30))
            #print("end frame = " + str(self.end_frame/30))

        else:
            # for image
            self.fileName = self.metadata[idx]["path"]  #"image-0003.rgb"
        return tp  # tp = 1: video ; tp = 0: image

    def getPos(self, event):
        x = event.pos().x()
        #print(x)
        tp = self.getfiles(x // 120)  # x//(width of an image = 120)
        if self.soundPlayer.state() == QMediaPlayer.PlayingState:
            self.v_thread.kill = 1
            time.sleep(0.04)  # for racing
        if tp:
            self.play_video()
        else:
            self.show_img()