class Player(QGraphicsVideoItem): def __init__(self, parent=None): super().__init__() self.parent = parent self.player = QMediaPlayer() self.player.setVideoOutput(self) def playerPlayOrOpen(self, arg=None): if type(arg) == list and len(arg) > 1: content = QMediaContent(QUrl.fromLocalFile(arg[1])) self.player.setMedia(content) self.play() def addVideo(self, video): content = QMediaContent(QUrl.fromLocalFile(video)) self.player.setMedia(content) self.play() def sliderChanged(self, pos): self.player.setPosition(pos) def mouseDoubleClickEvent(self, event): if not self.parent.isFullScreen(): self.parent.showFullScreen() else: self.parent.showNormal() def play(self): self.player.play() def stop(self): self.player.stop() def pause(self): self.player.pause() def setMuted(self, mute): self.player.setMuted(mute) def mutedState(self): if self.player.isMuted(): self.setMuted(False) else: self.setMuted(True) def isMuted(self): return self.player.isMuted() def setVolume(self, value): self.player.setVolume(value) def volume(self): return self.player.volume()
class MediaPlayer(metaclass=Observable): class Error(Enum): none = QMediaPlayer.NoError unsupported_format = QMediaPlayer.FormatError access_denied = QMediaPlayer.AccessDeniedError closed = signal() playing = signal(Track) stopped = signal(Track) error_occurred = signal(Track) def __init__(self): self._media_library = create_media_library() self._playlist = [] self._player = QMediaPlayer() self._player.stateChanged.connect(self._state_changed) self._player.mediaStatusChanged.connect(self._media_status_changed) def play(self, track): self._playlist.append(track) self._player.setMedia(self._media_library.fetch(track.filename)) self._player.play() def stop(self): self._player.stop() def _media_status_changed(self, state): if state == QMediaPlayer.BufferedMedia: self._error = QMediaPlayer.NoError self.playing.emit(self._playlist[0]) elif state == QMediaPlayer.InvalidMedia: # On windows 8, we only get an InvalidMedia status in case of error, # so we need to keep track of the error that occurred self._error = QMediaPlayer.FormatError @property def error(self): return MediaPlayer.Error(self._player.error() or self._error) def _state_changed(self, state): if state == QMediaPlayer.StoppedState and self.error is not MediaPlayer.Error.none: self.error_occurred.emit(self._playlist.pop(0), self.error) elif state == QMediaPlayer.StoppedState: self.stopped.emit(self._playlist.pop(0)) def dispose(self): self._player.stop() # force the deletion of the player on windows because windows # doesn't release the handle and prevents further instanciations sip.delete(self._player) self._player = None self._media_library.dispose() self.closed.emit()
def __alarm(self): if not self.go: return; self.timer.stop() player = QMediaPlayer(self); player.setMedia(QMediaContent(QUrl.fromLocalFile(self.music))); player.setVolume(100); player.play(); self.setEnabled(False) QMessageBox.critical(self, "ALERTA", "TIME TO DIE<br>" + self.ui.groupBox.title(), QMessageBox.Yes) self.setEnabled(True) player.stop() player.deleteLater()
class Story(QMainWindow): def __init__(self, language, side, username): QMainWindow.__init__(self) uic.loadUi("windows/Story.ui", self) self.lang = language self.username = username self.side = side self.reload_text() #Declarando el reproductor y ajustándolo en la ventana self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) video_widget = QVideoWidget() wid = QWidget(self) self.setCentralWidget(wid) layout = QVBoxLayout() layout.addWidget(video_widget) wid.setLayout(layout) #Asignando la salida de video y el archivo a reproducir self.media_player.setVideoOutput(video_widget) self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(QFileInfo(self.video).absoluteFilePath()))) self.show() def showEvent(self, event): """Play the story video when the window appears This is an override method""" self.media_player.play() def hideEvent(self, event): """Stop the story video when the window close This is an override method""" self.media_player.stop() def keyPressEvent(self, event): """Go to set ships window when the player press the space key This is an override method""" if event.key() == Qt.Key_Space: from setShipsWindow import SetShips self.ship = SetShips(self.lang, self.side, self.username) self.ship.show() self.close() def reload_text(self): """Change the language of the window according to the chosen previously""" self.language = LANGUAGE.get(self.lang) self.setWindowTitle(self.language["story"]) self.video = self.language["video"]
class Video(QDialog): def __init__(self, video, parent=None): super(Video, self).__init__(parent) self.ui = Ui_Video() self.ui.setupUi(self) self.video = video self.setWindowTitle("Video - %s" % video.title) self.ui.urlEdit.setText(video.url) self.ui.titleLabel.setText(video.title) self.ui.durationLabel.setText(unicode(video.duration)) self.ui.authorLabel.setText(unicode(video.author)) self.ui.dateLabel.setText(unicode(video.date)) if video.rating_max: self.ui.ratingLabel.setText('%s / %s' % (video.rating, video.rating_max)) else: self.ui.ratingLabel.setText('%s' % video.rating) self.mediaPlayer = QMediaPlayer() self.mediaPlayer.durationChanged.connect(self._setMax) self.mediaPlayer.seekableChanged.connect(self.ui.seekSlider.setEnabled) self.mediaPlayer.positionChanged.connect(self._slide) self.ui.seekSlider.valueChanged.connect(self.mediaPlayer.setPosition) mc = QMediaContent(QUrl(video.url)) self.mediaPlayer.setMedia(mc) self.ui.videoPlayer.setMediaObject(self.mediaPlayer) self.mediaPlayer.play() @Slot(object) def _slide(self, pos): blocking = self.ui.seekSlider.blockSignals(True) self.ui.seekSlider.setValue(pos) self.ui.seekSlider.blockSignals(blocking) @Slot(object) def _setMax(self, duration): self.ui.seekSlider.setMaximum(duration) def closeEvent(self, event): self.mediaPlayer.stop() event.accept() def hideEvent(self, event): self.mediaPlayer.stop() event.accept()
class Video(QDialog): def __init__(self, video, parent=None): super(Video, self).__init__(parent) self.ui = Ui_Video() self.ui.setupUi(self) self.video = video self.setWindowTitle("Video - %s" % video.title) self.ui.urlEdit.setText(video.url) self.ui.titleLabel.setText(video.title) self.ui.durationLabel.setText(unicode(video.duration)) self.ui.authorLabel.setText(unicode(video.author)) self.ui.dateLabel.setText(unicode(video.date)) if video.rating_max: self.ui.ratingLabel.setText('%s / %s' % (video.rating, video.rating_max)) else: self.ui.ratingLabel.setText('%s' % video.rating) self.mediaPlayer = QMediaPlayer() self.mediaPlayer.durationChanged.connect(self._setMax) self.mediaPlayer.seekableChanged.connect(self.ui.seekSlider.setEnabled) self.mediaPlayer.positionChanged.connect(self._slide) self.ui.seekSlider.valueChanged.connect(self.mediaPlayer.setPosition) mc = QMediaContent(QUrl(video.url)) self.mediaPlayer.setMedia(mc) self.ui.videoPlayer.setMediaObject(self.mediaPlayer) self.mediaPlayer.play() @Slot('qint64') def _slide(self, pos): blocking = self.ui.seekSlider.blockSignals(True) self.ui.seekSlider.setValue(pos) self.ui.seekSlider.blockSignals(blocking) @Slot('qint64') def _setMax(self, duration): self.ui.seekSlider.setMaximum(duration) def closeEvent(self, event): self.mediaPlayer.stop() event.accept() def hideEvent(self, event): self.mediaPlayer.stop() event.accept()
class play_audio: def __init__(self,audio_file): url = QUrl.fromLocalFile(audio_file) content = QMediaContent(url) self.player = QMediaPlayer() self.player.setMedia(content) self.player.mediaStatusChanged.connect(self.statusChanged) def statusChanged(self,status): # print(status,'dddddd',self.player.playerState) if status == QMediaPlayer.StoppedState: self.stop() def start(self): self.player.play() def stop(self): self.player.stop() del self
def handler(): """Handler function for one tick timer""" nonlocal counter counter -= timedelta(seconds=1) self.update_time(counter.strftime("%H:%M:%S")) if counter.second <= 0 and counter.minute <= 0 and counter.hour <= 0: player = QMediaPlayer() url = QtCore.QUrl.fromLocalFile( QtCore.QDir().absolutePath() + "/" + MUSIC_DIR + "{}.mp3".format(self.selectSignal.currentText())) player.setMedia(QMediaContent(url)) player.setVolume(self.volume.value()) player.play() timer.stop() timer.deleteLater() time_end = datetime.now() self.db_connect.create_track(time_start, time_end, self.timer_text.toPlainText()) QtWidgets.QMessageBox.about(self, "Timetracker", "Время вышло") player.stop() self.print_table()
class GetRington(QWidget, Ui_Form): def __init__(self, path): super().__init__() self.setupUi(self) self.path = path self.set_rington_settings.clicked.connect(self.get_rington) self.melody_paths = { self.melodies_lst[0]: 'other_files/melody1.mp3', self.melodies_lst[1]: 'other_files/melody2.mp3', self.melodies_lst[2]: 'other_files/melody3.mp3', self.melodies_lst[3]: 'other_files/melody4.mp3', self.melodies_lst[4]: 'other_files/melody5.mp3' } quit = QAction(self) quit.triggered.connect(self.closeEvent) self.player = QMediaPlayer() for i in range(5): if self.melody_paths[self.melodies_lst[i]] == path: self.melodies_lst[i].setChecked(True) for i in range(5): self.melodies_lst[i].clicked.connect(self.play_melody) def play_melody(self): for i in range(5): if self.melodies_lst[i].isChecked(): self.current_path = self.melody_paths[self.melodies_lst[i]] self.player.setMedia(QMediaContent(QUrl(self.current_path))) self.player.play() def get_rington(self): self.result_path = '' for i in range(len(self.melodies_lst)): if self.melodies_lst[i].isChecked(): self.result_path = self.melody_paths[self.melodies_lst[i]] self.closeEvent() return self.result_path def closeEvent(self, a0=None): self.close() self.player.stop()
class VideoPlayer(QWidget): # noinspection PyArgumentList def __init__(self, width: int, height: int, parent=None): super(VideoPlayer, self).__init__(parent) video_item = QGraphicsVideoItem() video_item.setAspectRatioMode(Qt.IgnoreAspectRatio) video_item.setSize(QSizeF(width, height)) scene = QGraphicsScene(self) scene.addItem(video_item) graphics_view = QGraphicsView(scene) graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) layout = QVBoxLayout() layout.addWidget(graphics_view) self.setLayout(layout) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVideoOutput(video_item) self.mediaPlayer.setVolume(0) def play(self): self.mediaPlayer.play() def stop(self): self.mediaPlayer.stop() # noinspection PyArgumentList def load_loop(self, name): global config play_loop = QMediaPlaylist() play_loop.addMedia(QMediaContent(QUrl.fromLocalFile(config['preview_path'] + name))) play_loop.setPlaybackMode(QMediaPlaylist.Loop) self.mediaPlayer.setPlaylist(play_loop) # noinspection PyArgumentList def load(self, name): global config self.mediaPlayer.stop() if os.path.isfile(config['preview_path'] + name): local = QUrl.fromLocalFile(config['preview_path'] + name) else: local = QUrl.fromLocalFile(config['preview_path'] + 'default.mp4') media = QMediaContent(local) self.mediaPlayer.setMedia(media)
def loose(self): if globals.loose_animation: video = QVideoWidget() video.resize(500, 400) video.setWindowTitle("GAME OVER") player = QMediaPlayer() player.setVideoOutput(video) player.setMedia( QMediaContent(QUrl.fromLocalFile("../Video/bum.gif"))) video.show() player.play() self.signals.add_music.emit() time.sleep(5.5) self.signals.delete_music.emit() player.stop() video.close() else: __loose_statement = QMessageBox.question( QMessageBox(), "GAME OVER!!", "You loose!!!\nYour time: {}".format(globals.time), QMessageBox.Ok)
class songctl(object): def __init__(self, queue, signals): self.queue = queue self.signals = signals self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.stateChanged.connect( signals._signal_stateChanged.emit) self.mediaPlayer.positionChanged.connect( signals._signal_positionChanged.emit) self.mediaPlayer.durationChanged.connect( signals._signal_durationChanged.emit) #self.mediaPlayer.error.connect(self.handleError) def handleError(self): return self.mediaPlayer.errorString() def play(self, localpath): print('localpath:{}'.format(localpath)) self.mediaPlayer.stop() self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(localpath))) self.mediaPlayer.play() print('开始播放{}'.format('23333'))
class Clock_alarm(QWidget): def __init__(self, name, weekdays, time, song, sleep, extreme, onnn, volume, start_time): super().__init__() uic.loadUi("clock_alarm.ui", self) hours, minutes = time.split(':') if len(hours) == 1: hours = '0' + hours if len(minutes) == 1: minutes = '0' + minutes self.ca_cw_alarm.setText(hours + ':' + minutes) self.DeActivate.clicked.connect(self.alarm_deactivate) self.setWindowFlags(Qt.FramelessWindowHint) self.player = QMediaPlayer() if not extreme: self.player.setMedia(QMediaContent(QUrl.fromLocalFile(song))) else: self.player.setMedia(QMediaContent(QUrl.fromLocalFile("S3RL - HentaiExtreme Bass Boosted.mp3"))) self.player.setVolume(volume) if start_time: self.player.setPosition(start_time * 1000) self.player.play() self.extreme = extreme self.sleep = sleep def alarm_deactivate(self): if not self.extreme: if not self.sleep: self.player.stop() self.hide() else: self.slch_win = SleepCheck(self) self.slch_win.show() else: self.player.setVolume(100)
class Speaker(QObject): def __init__(self, parent=None): super(Speaker,self).__init__(parent) self.player = QMediaPlayer(self) try: self.backup = steel.available_engines()[0]() self.backup.set("rate", 150) except: self.backup = None print("Could not start a backup offline speaker.") @pyqtSlot(str, str) def speak(self, name, text, lang="pt-br"): fpath = "./speeches/" + name + ".mp3" if not os.path.isdir("./speeches"): os.mkdir("./speeches") if not os.path.isfile(fpath): print("Running TTS...") try: data = urlencode( [("tl", lang), ("q", text), ("ie", "UTF-8")] ) bin_data = data.encode("utf8") req = Request("http://translate.google.com/translate_tts", bin_data, {"User-Agent":"My agent !"}) fin = urlopen(req) mp3 = fin.read() fout = open(fpath, "wb") fout.write(mp3) fout.close() except Exception as exc: print("Error trying to get TTS file:", str(exc)) if self.backup != None: print("Proceeding to use backup speaker...") self.backup.speak(text) return self.player.stop() self.player.setMedia(QMediaContent(QUrl.fromLocalFile(QFileInfo(fpath).absoluteFilePath()))) self.player.play()
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)
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)
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 ApplicationWindow(QtWidgets.QMainWindow): global wavFileName global fig,chartFig global duration, counterClick global colorName, text_ global startAnnotation, endTimeToPlay # >> QtMultimedia Signals #---------------------- play = pyqtSignal() pause = pyqtSignal() stop = pyqtSignal() def __init__(self): global playerStarted global wavFileName, fig, chartFig global playerStarted, durationFlag, duration global colorName, text_, counterClick global startAnnotation, endTimeToPlay QtWidgets.QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.main_widget = QtWidgets.QWidget(self) playerStarted = False #DEFINE PLAYER-PLAYLIST #---------------------- self.source = QtCore.QUrl.fromLocalFile(os.path.abspath(wavFileName)) self.content = QMediaContent(self.source) self.player = QMediaPlayer() self.playlist = QMediaPlaylist(self) self.playlist.addMedia(self.content) self.player.setPlaylist(self.playlist) # >> Define annotations and gantt chart #---------------------- self.wave = Waveform() fig = self.wave self.chart = Chart() chartFig = self.chart # >> Define player buttons #---------------------- playButton = QPushButton("Play") pauseButton = QPushButton("Pause") stopButton = QPushButton("Stop") # >> Define layouts #---------------------- waveLayout = QVBoxLayout() waveLayout.addWidget(self.wave) waveLayout.addWidget(self.chart) line = QFrame() line.setFrameShape(QFrame.VLine) line.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Expanding) waveLayout.addWidget(line) #Buttons layout buttonLayout = QVBoxLayout() buttonLayout.addWidget(playButton) buttonLayout.addWidget(pauseButton) buttonLayout.addWidget(stopButton) buttonLayout.setAlignment(Qt.AlignTop) # >> Specify final layout align #---------------------- layout = QHBoxLayout(self.main_widget) layout.addLayout(waveLayout) layout.addLayout(buttonLayout) # >> Define buttons connections #---------------------- playButton.clicked.connect(self.Play) pauseButton.clicked.connect(self.Pause) stopButton.clicked.connect(self.Stop) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) # PLAYER BUTTON FUNCTIONS # >> Play audio (whole signal or segment) #---------------------- def Play(self): global playerStarted global durationFlag global duration, counterClick global startTimeToPlay, endTimeToPlay, first #GET CLICKS FROM WAVEFORM #---------------------- #Initialize connection-position ONCE if not playerStarted: #10ms for changePosition -> Not Delaying self.player.positionChanged.connect(self.checkPositionToStop) self.player.setNotifyInterval(10) if durationFlag==0: playerStarted = True startTimeToPlay = 0 self.start = startTimeToPlay self.end = duration*1000 - 10 endTimeToPlay = self.end counterClick = 3 elif durationFlag==1: playerStarted = True self.start = startTimeToPlay self.end = duration*1000 - 10 endTimeToPlay = self.end counterClick = 3 elif durationFlag==2: playerStarted = True self.start = startTimeToPlay self.end = endTimeToPlay self.player.setPosition(self.start) playFlag = True self.player.play() # >> Pause audio playing #---------------------- def Pause(self): #Not begging from self.start playerStarted = True self.player.setPosition(self.time_) self.player.pause() # >> Stop audio playing #---------------------- def Stop(self): self.player.stop() #Begin again segment self.start = startTimeToPlay self.player.setPosition(self.start) # >> Check ms in audio to stop play #---------------------- def checkPositionToStop(self): self.time_ = self.player.position() print self.time_ if self.time_ >= self.end: self.Stop() self.player.setPosition(self.start) def fileQuit(self): self.close() def closeEvent(self, ce): self.fileQuit()
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) # 窗口名称
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()
class MyWidget(QMainWindow): def __init__(self): super().__init__() uic.loadUi('ui/alarm_clock_form.ui', self) self.initUI() self.alarm_clock_list = [] self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) self.player.setPlaylist(self.playlist) def initUI(self): self.digital_clock = DigitalClock(self.clockWidget) self.digital_clock.time_tick.connect(self.time_tick) clock_widget_layout = QHBoxLayout() clock_widget_layout.addWidget(self.digital_clock) self.clockWidget.setLayout(clock_widget_layout) self.addAlarmClockButton.clicked.connect(self.add_alarm_clock) def closeEvent(self, event): reply = QMessageBox.question(self, 'Выход', "Вы уверены что хотите выйти? Будильники перестанут работать", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: event.accept() else: event.ignore() def add_alarm_clock(self): dialog = NewAlarmClockDialog() dialog_result = dialog.exec_() if (dialog_result == QDialog.Accepted): widget_item = QListWidgetItem(self.listWidget); alarm_clock_item = AlarmClockItem(dialog.nameLineEdit.text(), dialog.timeEdit.time(), dialog.filePathLineEdit.text()) alarm_clock_item.alarm.connect(self.alarm) self.alarm_clock_list.append(alarm_clock_item) alarm_clock_item_widget = AlarmClockItemWidget(alarm_clock_item, widget_item, self) alarm_clock_item_widget.alarm_clock_remove.connect(self.alarm_clock_remove) widget_item.setSizeHint(alarm_clock_item_widget.sizeHint()); self.listWidget.setItemWidget(widget_item, alarm_clock_item_widget); dialog.deleteLater() def alarm_clock_remove(self): self.listWidget.takeItem(self.listWidget.row(self.sender().list_widget_item)) self.alarm_clock_list.remove(self.sender().alarm_clock) def time_tick(self): for alarm_clock in self.alarm_clock_list: if alarm_clock.is_active: alarm_clock.tick() def alarm(self): alarm_clock = self.sender() self.play_sound(alarm_clock.alarm_sound) QMessageBox.information(self, 'Будильник', 'Будильник "' + alarm_clock.title + '"', QMessageBox.Ok) alarm_clock.is_alarm = False self.stop_sound() def play_sound(self, sound): if len(sound): self.player.stop() self.playlist.clear() media_content = QMediaContent(QUrl.fromLocalFile(sound)) self.playlist.addMedia(media_content) self.player.play() def stop_sound(self): self.player.stop()
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))
class videoViewer(QDialog): def __init__(self): super(videoViewer,self).__init__() loadUi('..\gui\viewer.ui',self) self.setWindowTitle('Recorded Videos') self.setWindowIcon(QIcon('..\resources\icon.png')) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videoWidget = QVideoWidget(self) layout = QVBoxLayout() layout.addWidget(videoWidget) self.mediaPlayer.setVideoOutput(videoWidget) self.videoWidget.setLayout(layout) self.userPath = os.path.join(os.getcwd(),'..\data') userList = [o for o in os.listdir(self.userPath) if os.path.isdir(os.path.join(self.userPath,o))] self.list1.addItems(userList) self.list1.itemClicked.connect(self.loadFile) self.playButton.clicked.connect(self.play) self.pauseButton.clicked.connect(self.pause) self.stopButton.clicked.connect(self.stop) self.exitButton.clicked.connect(self.exit) self.playButton.setEnabled(False) self.pauseButton.setEnabled(False) self.stopButton.setEnabled(False) self.timer = QTimer(self) self.timer.timeout.connect(self.updateFrame) self.understanding1.setText('-') self.understanding2.setText('-') self.data = pickle.load(open('..\data\data.pkl','rb')) self.mediaPlayer.mediaStatusChanged.connect(self.mediaStatusfn) def mediaStatusfn(self): if self.mediaPlayer.position()==self.mediaPlayer.duration(): self.mediaPlayer.stop() def updateFrame(self): currentFrame = round(self.mediaPlayer.position()*30/1000) totalFrame = round(self.mediaPlayer.duration()*30/1000) if currentFrame>totalFrame: self.timer.stop() self.mediaPlayer.stop() else: if self.understandingData[self.i][0]<currentFrame and self.i<len(self.understandingData)-1: self.i += 1 self.understanding1.setText(str(self.understandingData[self.i][1])) self.understanding2.setText(str(self.understandingData[self.i][1])) def play(self): self.mediaPlayer.play() self.pauseButton.setEnabled(True) self.playButton.setEnabled(False) self.stopButton.setEnabled(True) self.timer.start(30) def pause(self): self.mediaPlayer.pause() self.playButton.setEnabled(True) self.pauseButton.setEnabled(False) self.timer.stop() def stop(self): self.mediaPlayer.stop() self.playButton.setEnabled(True) self.pauseButton.setEnabled(False) self.stopButton.setEnabled(False) self.timer.stop() def exit(self): self.close() def loadFile(self, item): self.filePath = os.path.join(self.userPath,item.text()) fileList = [o for o in os.listdir(self.filePath) if not os.path.isdir(os.path.join(self.filePath,o))] self.list2.clear() self.list2.addItems(fileList) self.list2.itemClicked.connect(self.playFile) def playFile(self, item): if (os.path.splitext(item.text())[-1].lower()=='.avi'): self.fileLabel.setText(item.text()) self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(os.path.join(self.filePath,item.text())))) for file, understanding in self.data.items(): if os.path.basename(file)==item.text(): self.understandingData = understanding break self.playButton.setEnabled(True) self.pauseButton.setEnabled(False) self.stopButton.setEnabled(False) self.i = 0
class EditPlaylistItem(QDialog): def __init__(self, parent, daze_data, current_item): super().__init__(parent) self.daze_data = daze_data self.media_player = QMediaPlayer(self) self.media_player.stateChanged.connect(self.media_state_changed) self.media_player.positionChanged.connect(self.position_changed) self.vbox = QVBoxLayout() self.hbox = QHBoxLayout() self.hbox2 = QHBoxLayout() self.setGeometry(200, 200, 550, 150) self.current_item = current_item self.audio_name = QLabel(current_item.data()) self.save_button = QPushButton('Save', self) self.save_button.clicked.connect(self.save_clicked) self.close_button = QPushButton('Close', self) self.close_button.clicked.connect(self.close_clicked) self.play_button = QPushButton(self) self.play_button.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.play_button.clicked.connect(self.play_audio) self.play_button.setEnabled(True) media_path = (self.daze_data.get('Playlist').get( self.current_item.data()).get('filename')) audio = mp3.MP3(media_path) self.audio_length = audio.info.length self.qrangeslider = QRangeSlider(parent=self) self.qrangeslider.setFixedHeight(50) self.qrangeslider.setMin(0) self.qrangeslider.setMax(round(self.audio_length)) self.max_val = round(self.audio_length) self.min_val = round(0) self.qrangeslider.setRange(0, round(self.audio_length)) self.qrangeslider.setBackgroundStyle( 'background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #222, stop:1 #333);' ) self.qrangeslider.setSpanStyle( 'background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #282, stop:1 #393);' ) self.qrangeslider.handle.setTextColor(0) self.qrangeslider.start_changed.connect(self.start_changed) self.qrangeslider.end_changed.connect(self.end_changed) self.end_time = str( datetime.timedelta(seconds=round(self.audio_length))) self.length_time = self.end_time self.start_time = str(datetime.timedelta(seconds=round(0))) self.current_time = self.start_time self.running_time = QLabel('{}/{}'.format(self.current_time, self.length_time)) self.vbox.addWidget(self.audio_name) self.hbox2.addWidget(self.play_button) self.hbox2.addWidget(self.qrangeslider) self.hbox2.addWidget(self.running_time) self.hbox.addWidget(self.close_button) self.hbox.addWidget(self.save_button) self.vbox.addLayout(self.hbox2) self.vbox.addLayout(self.hbox) self.setLayout(self.vbox) self.audio_filename = (self.daze_data.get('Playlist').get( current_item.data()).get('filename')) # possibly set slider to audio length here audio_file = QUrl.fromLocalFile(self.audio_filename) audio_content = QMediaContent(audio_file) self.media_player.setMedia(audio_content) def end_changed(self, max_val): self.media_player.pause() self.max_val = max_val self.end_time = str(datetime.timedelta(seconds=round(self.max_val))) def start_changed(self, min_val): self.min_val = min_val self.media_player.pause() self.start_time = str(datetime.timedelta(seconds=round(self.min_val))) self.media_player.setPosition(self.min_val * 1000) def media_state_changed(self, state): if self.media_player.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 position_changed(self, value): # maybe add a slider to update here pos = int((self.media_player.position() / 1000)) self.running_time.setText('{}/{}'.format( datetime.timedelta(seconds=pos), self.length_time)) if int((self.media_player.position() / 1000)) == self.max_val: self.media_player.pause() def play_audio(self): if self.media_player.state() == QMediaPlayer.PlayingState: self.media_player.pause() else: self.media_player.play() def save_clicked(self): song = AudioSegment.from_mp3(self.audio_filename) min_mili = self.min_val * 1000 max_mili = self.max_val * 1000 new_song = song[min_mili:max_mili + 1000] new_song.export(self.audio_filename, format='mp3') self.close_clicked() def close_clicked(self): self.media_player.stop() self.close() def closeEvent(self, event): self.media_player.stop() super().closeEvent(event)
def stop(self): QMediaPlayer.stop(self)
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute( Qt.WA_NoSystemBackground, True ) self.colorDialog = None self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setEnabled(False) self.lbl.setFixedWidth(60) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setEnabled(False) self.elbl.setFixedWidth(60) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet (stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) controlLayout = QHBoxLayout() controlLayout.setContentsMargins(5, 0, 5, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.lbl) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.elbl) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.videoWidget) layout.addLayout(controlLayout) self.setLayout(layout) self.myinfo = "©2016\nAxel Schneider\n\nMouse Wheel = Zoom\nUP = Volume Up\nDOWN = Volume Down\n" + \ "LEFT = < 1 Minute\nRIGHT = > 1 Minute\n" + \ "SHIFT+LEFT = < 10 Minutes\nSHIFT+RIGHT = > 10 Minutes\nf = Fullscreen On/Off" self.widescreen = True self.setAcceptDrops(True) self.setWindowTitle("QT5 Player") self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint) self.setGeometry(700, 400, 400, 290) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu); self.customContextMenuRequested[QtCore.QPoint].connect(self.contextMenuRequested) self.hideSlider() self.show() self.playFromURL() #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence("o"), self) self.shortcut.activated.connect(self.openFile) self.shortcut = QShortcut(QKeySequence(" "), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence("f"), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Up), self) self.shortcut.activated.connect(self.volumeUp) self.shortcut = QShortcut(QKeySequence(Qt.Key_Down), self) self.shortcut.activated.connect(self.volumeDown) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Right) , self) self.shortcut.activated.connect(self.forwardSlider10) self.shortcut = QShortcut(QKeySequence(Qt.ShiftModifier + Qt.Key_Left) , self) self.shortcut.activated.connect(self.backSlider10) self.shortcut = QShortcut(QKeySequence("c") , self) self.shortcut.activated.connect(self.showColorDialog) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Movie", QDir.homePath(), "Videos (*.mp4 *.ts *.avi *.mpeg *.mpg *.mkv *.VOB *.m4v)") if fileName != '': self.loadFilm(fileName) print("File loaded") def playFromURL(self): self.mediaPlayer.pause() clip = QApplication.clipboard() myurl = clip.text() if myurl.startswith("http"): self.mediaPlayer.setMedia(QMediaContent(QUrl(myurl))) elif myurl.startswith("/"): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(myurl))) else: return self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(myurl) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0,0,0,0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: " + self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() print("Goodbye ...") app.quit() def contextMenuRequested(self,point): menu = QtWidgets.QMenu() actionFile = menu.addAction("open File (o)") actionclipboard = menu.addSeparator() actionURL = menu.addAction("URL / File from Clipboard (u)") actionclipboard = menu.addSeparator() actionToggle = menu.addAction("show / hide Slider (s)") actionFull = menu.addAction("Fullscreen (f)") action169 = menu.addAction("16 : 9") action43 = menu.addAction("4 : 3") actionColors = menu.addAction("Color Options (c)") actionSep = menu.addSeparator() actionInfo = menu.addAction("Info (i)") actionsep2 = menu.addSeparator() actionQuit = menu.addAction("Exit (q)") actionFile.triggered.connect(self.openFile) actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) action169.triggered.connect(self.screen169) action43.triggered.connect(self.screen43) actionColors.triggered.connect(self.showColorDialog) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self,event): mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mscale = event.angleDelta().y() / 5 if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.778) else: self.setGeometry(mleft, mtop, mwidth + mscale, (mwidth + mscale) / 1.33) def screen169(self): self.widescreen = True mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.778 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def screen43(self): self.widescreen = False mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() mratio = 1.33 self.setGeometry(mleft, mtop, mwidth, mwidth / mratio) def handleFullscreen(self): if self.windowState() & QtCore.Qt.WindowFullScreen: self.showNormal() print("no Fullscreen") else: self.showFullScreen() print("Fullscreen entered") def handleInfo(self): msg = QMessageBox() msg.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) msg.setGeometry(self.frameGeometry().left() + 30, self.frameGeometry().top() + 30, 300, 400) msg.setIcon(QMessageBox.Information) msg.setText("QT5 Player") msg.setInformativeText(self.myinfo) msg.setStandardButtons(QMessageBox.Close) msg.exec() def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.778) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def showSlider(self): self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() mwidth = self.frameGeometry().width() mheight = self.frameGeometry().height() mleft = self.frameGeometry().left() mtop = self.frameGeometry().top() self.positionSlider.setFocus() if self.widescreen == True: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.55) else: self.setGeometry(mleft, mtop, mwidth, mwidth / 1.33) def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000*60) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000*60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000*60) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000*60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() \ - QPoint(self.frameGeometry().width() / 2, \ self.frameGeometry().height() / 2)) event.accept() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasFormat('text/plain'): event.accept() else: event.ignore() ########### drag files ############# def dropEvent(self, event): if event.mimeData().hasUrls(): f = str(event.mimeData().urls()[0].toLocalFile()) self.loadFilm(f) elif event.mimeData().hasText(): f = str(event.mimeData().text()) self.mediaPlayer.setMedia(QMediaContent(QUrl(f))) self.mediaPlayer.play() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() print(str(self.mediaPlayer.media().canonicalResource().resolution())) def openFileAtStart(self, filelist): matching = [s for s in filelist if ".myformat" in s] if len(matching) > 0: self.loadFilm(matching) ##################### update Label ################################## def handleLabel(self): self.lbl.clear() mtime = QTime(0,0,0,0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString()) ################################################################### def showColorDialog(self): if self.colorDialog is None: brightnessSlider = QSlider(Qt.Horizontal) brightnessSlider.setRange(-100, 100) brightnessSlider.setValue(self.videoWidget.brightness()) brightnessSlider.sliderMoved.connect( self.videoWidget.setBrightness) self.videoWidget.brightnessChanged.connect( brightnessSlider.setValue) contrastSlider = QSlider(Qt.Horizontal) contrastSlider.setRange(-100, 100) contrastSlider.setValue(self.videoWidget.contrast()) contrastSlider.sliderMoved.connect(self.videoWidget.setContrast) self.videoWidget.contrastChanged.connect(contrastSlider.setValue) hueSlider = QSlider(Qt.Horizontal) hueSlider.setRange(-100, 100) hueSlider.setValue(self.videoWidget.hue()) hueSlider.sliderMoved.connect(self.videoWidget.setHue) self.videoWidget.hueChanged.connect(hueSlider.setValue) saturationSlider = QSlider(Qt.Horizontal) saturationSlider.setRange(-100, 100) saturationSlider.setValue(self.videoWidget.saturation()) saturationSlider.sliderMoved.connect( self.videoWidget.setSaturation) self.videoWidget.saturationChanged.connect( saturationSlider.setValue) layout = QFormLayout() layout.addRow("Brightness", brightnessSlider) layout.addRow("Contrast", contrastSlider) layout.addRow("Hue", hueSlider) layout.addRow("Saturation", saturationSlider) button = QPushButton("Close Window") button.setFixedWidth(120) layout.addRow(button) self.colorDialog = QDialog(self) self.colorDialog.setWindowTitle("Color Options") self.colorDialog.setLayout(layout) button.clicked.connect(self.colorDialog.close) self.colorDialog.setGeometry(300, 250, 300, 100) self.colorDialog.show()
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)
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)
class VideoSortApp(QMainWindow, Ui_MainWindow, QWidget): def __init__(self): super(VideoSortApp, self).__init__() self.setupUi(self) self.filename = None self.directory = None self.sort.setEnabled(False) self.fileOpen.clicked.connect(self.fileDialog) self.dirOpen.clicked.connect(self.folderDialog) self.sort.clicked.connect(self.sortVideo) self.results.setViewMode(self.results.IconMode) self.results.setResizeMode(self.results.Adjust) self.features = [] self.sorted = None #player properties self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.playlist = QMediaPlaylist(self.player) self.videoItem = QGraphicsVideoItem() self.videoItem.setSize(QtCore.QSizeF(640, 480)) scene = QGraphicsScene(self) scene.addItem(self.videoItem) self.graphicsView.setScene(scene) self.player.setVideoOutput(self.videoItem) self.graphicsView.resize(640,480) self.graphicsView.show() self.results.itemDoubleClicked.connect(self.seekVideo) self.videoLoaded = False def sizeHint(self): return QtCore.QSize(640,480) def fileDialog(self): dialog = QFileDialog() if dialog.getOpenFileName: self.filename = dialog.getOpenFileName()[0] self.sort.setEnabled(True) def folderDialog(self): dialog = QFileDialog() if dialog.getExistingDirectory: self.directory = dialog.getExistingDirectory() self.sort.setEnabled(True) def sortVideo(self): dialog = QFileDialog() folder = dialog.getExistingDirectory(self, 'Select output directory for thumbnail images') if folder: if self.filename: self.getThread = VideoSort(self.filename, folder, 'frame') #self.results.setIconSize(QtCore.QSize(self.getThread.thumbInfo['resolution'][0], self.getThread.thumbInfo['resolution'][1])) #slot self.getThread.resultsSignal.connect(self.setFeatures) self.getThread.start() self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(self.filename))) self.currentMedia = self.filename if self.directory: formatList = ['.mp4', '.mov', '.mkv', '.avi'] for dirname, dirnames, filenames in os.walk(self.directory): supportedFiles = [os.path.abspath(os.path.join(dirname, path)) for path in filenames if os.path.splitext(path)[1] in formatList] for filename in supportedFiles: self.getThread = VideoSort(filename, folder, os.path.splitext(filename.split('/')[-1])[0]) self.getThread.resultsSignal.connect(self.setFeatures) self.getThread.start() self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(filename))) #Just set the last file as the current file self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(filename))) self.currentMedia = filename def setFeatures(self, features): for feature in features: self.features.append(feature) self.hue.toggled.connect(self.displayResults) self.saturation.toggled.connect(self.displayResults) self.contours.toggled.connect(self.displayResults) def displayResults(self): self.results.clear() if self.hue.isChecked(): sortedFeatures = sorted(self.features, key=lambda res: res['hue']['std'], reverse=False) self.sorted = True if self.saturation.isChecked(): sortedFeatures = sorted(self.features, key=lambda res: res['sat']['std'], reverse=False) self.sorted = True if self.contours.isChecked(): sortedFeatures = sorted(self.features, key=lambda res: res['contours']['area'], reverse=False) self.sorted = True if self.sorted: for feature in sortedFeatures: icon = QtGui.QIcon(feature['thumbnail']) item = VideoListItem(icon, feature) self.results.addItem(item) def seekVideo(self, Qitem): #Need to write a callback function to only seek once player is loaded - provide loading media graphic or progress bar self.player.stop() print self.player.mediaStatus() if Qitem.feature['video'] != self.currentMedia: self.player.setMedia(QMediaContent(QtCore.QUrl.fromLocalFile(Qitem.feature['video']))) self.videoLoadProgress(self.player) self.currentMedia = Qitem.feature['video'] else: self.videoLoaded = True if self.videoLoaded: self.player.setPosition(Qitem.feature['milliseconds']) self.player.play() else: #set up progress bar here, or loading text def videoLoadProgress(self, QMediaPlayerObject): self.videoStatus = VideoLoadStatus(QMediaPlayerObject) self.videoStatus.videoLoaded.connect(self.getVideoStatus) def getVideoStatus(self, status): self.status = status
class VideoPreview(QWidget): def __init__(self, parent=None, fileName=None): super(VideoPreview, self).__init__(parent) 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) 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) 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.openFile(fileName) self.play() def openFile(self, fileName): 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()) def closeEvent(self, event): event.ignore() self.mediaPlayer.stop() super(VideoPreview, self).closeEvent(event)
class DPlayerCore(QWidget): def __init__(self): """Initialize player and load playlist if any.""" super().__init__() self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.shuffling = False self.repeatingPlaylist = False self.repeatingSong = False self.musicOrder = [] self.loadPlaylist(QUrl( 'file://{}/lastListened.m3u'.format(os.getcwd()))) self.lyricsApi = 'http://api.musixmatch.com/ws/1.1/' self.lyricsApiKey = '4b364f0652e471aa50813a22cdf830ea' self.lastFMapi = 'http://ws.audioscrobbler.com/2.0/' self.lastFMapikey = '052c43a00a4fc294bb3c9e0c38bdf710' self.lastFMsecret = '14c66392fa9c6c142a41ccc2b0674e19' self.username = None self.password = None self.network = None self.error = 'Something went wrong! Try again later.' def play(self): """Start the player.""" self.player.play() def pause(self): """Pause the player.""" self.player.pause() def stop(self): """Stop the player.""" self.player.stop() def previous(self): """Play previous song.""" self.playlist.previous() def next(self): """Play next song.""" self.playlist.next() def mute(self): """Mute the player.""" self.player.setMuted(True) def unmute(self): """Unmute the player.""" self.player.setMuted(False) def setVolume(self, value): """Set player's volume to value.""" self.player.setVolume(value) def add(self, fileNames): """Add fileNames to the playlist.""" for name in fileNames: url = QUrl.fromLocalFile(QFileInfo(name).absoluteFilePath()) self.playlist.addMedia(QMediaContent(url)) self.musicOrder.append([name]) self.added(len(fileNames)) def added(self, added): """Saves music info in musicOrder.""" for name, index in zip( self.musicOrder[self.playlist.mediaCount() - added:], range(self.playlist.mediaCount() - added, len(self.musicOrder))): name = name[0] artist = self.getArtist(name)[0] title = self.getTitle(name)[0] album = self.getAlbum(name)[0] seconds = self.getDuration(name) duration = QTime(0, seconds // 60, seconds % 60) duration = duration.toString('mm:ss') self.musicOrder[index].extend( [artist, title, album, duration]) def remove(self, songIndexes): """Remove songIndexes from the playlist.""" for index in songIndexes: self.songChanged = True del self.musicOrder[index] self.playlist.removeMedia(index) self.songChanged = False def savePlaylist(self, path): """Save playlist to path.""" if path.toString()[len(path.toString()) - 4:] != '.m3u': path = QUrl('{}.m3u'.format(path.toString())) self.playlist.save(path, 'm3u') def loadPlaylist(self, path): """Load playlist form path.""" count = self.playlist.mediaCount() self.playlist.load(path) for index in range(count, self.playlist.mediaCount()): self.musicOrder.append( [self.playlist.media(index).canonicalUrl().path()]) self.added(self.playlist.mediaCount() - count) def clearPlaylist(self): """Delete all songs in the playlist.""" self.playlist.clear() self.musicOrder = [] def shuffle(self, value): """Shuffle playlist if value = True.""" self.shuffling = value if self.repeatingSong: return if self.shuffling: self.playlist.setPlaybackMode(QMediaPlaylist.Random) elif self.repeatingPlaylist: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) else: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) def repeatPlaylist(self, value): """Repeat playlist after the last song is finished if value = True.""" self.repeatingPlaylist = value if self.repeatingSong or self.shuffling: return if self.repeatingPlaylist: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) else: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) def repeatSong(self, value): """Repeat current song if value = True.""" self.repeatingSong = value if self.repeatingSong: self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) elif self.shuffling: self.playlist.setPlaybackMode(QMediaPlaylist.Random) elif self.repeatingPlaylist: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) else: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) def sort(self, column, order): """Sort playlist by column in order.""" ordered = sorted(self.musicOrder, key=itemgetter(column + 1), reverse=order) self.clearPlaylist() for song in ordered: url = QUrl.fromLocalFile(QFileInfo(song[0]).absoluteFilePath()) self.playlist.addMedia(QMediaContent(url)) self.musicOrder = ordered def findLyrics(self, index): """Returns lyrics for song at index.""" if self.musicOrder[index][2] == 'Unknown': return 'Unknown song.' searchSong = '{}track.search?q_track={}'.format( self.lyricsApi, self.musicOrder[index][2].replace(' ', '%20')) if self.musicOrder[index][1] != 'Unknown': searchSong = '{}&q_artist={}'.format( searchSong, self.musicOrder[index][1].replace(' ', '%20')) searchSong = '{}&f_has_lyrics=1&apikey={}'.format( searchSong, self.lyricsApiKey) try: requestSong = requests.get(searchSong) except requests.ConnectionError: return self.error songJson = requestSong.json() if requestSong.status_code != 200 or \ songJson['message']['header']['available'] == 0: return self.error songId = songJson[ 'message']['body']['track_list'][0]["track"]["track_id"] searchLyrics = '{}track.lyrics.get?track_id={}&apikey={}'.format( self.lyricsApi, songId, self.lyricsApiKey) try: requestLyrics = requests.get(searchLyrics) except requests.ConnectionError: return self.error if requestLyrics.status_code != 200 or \ songJson['message']['header']['available'] == 0: return self.error return requestLyrics.json()[ 'message']['body']['lyrics']['lyrics_body'][:-58] # spam and bacon def findInfo(self, index): """Returns info about artist and album for index if any.""" info = [] if self.musicOrder[index][1] != 'Unknown': artist = self.artistInfo(self.musicOrder[index][1]) if artist != self.error: info += artist if self.musicOrder[index][1] != 'Unknown' and \ self.musicOrder[index][3] != 'Unknown': album = self.albumInfo(self.musicOrder[index][1], self.musicOrder[index][3]) if album != self.error: info += album if info: return info else: return ['Unknown artist and song!'] def artistInfo(self, artist): """Returns info about artist if any.""" try: response = requests.get( ('{}/?method=artist.getinfo&artist={}&api_key={}&' 'format=json&autocorrect=1').format( self.lastFMapi, artist, self.lastFMapikey)) except Exception: return self.error if response.status_code != 200: return self.error artist = 'Artist: {}'.format(response.json()['artist']['name']) bio = 'Bio: {}'.format( response.json()['artist']['bio']['summary'].replace('.', '.\n')) spam = bio.find('<a') bio = bio[:spam] return [artist, bio] def albumInfo(self, artist, album): """Returns info about album if any.""" try: response = requests.get( ('{}/?method=album.getinfo&artist={}&album={}&api_key={}&' 'format=json&autocorrect=1').format( self.lastFMapi, artist, album, self.lastFMapikey)) except Exception: return self.error if response.status_code != 200 or \ 'album' not in response.json().keys(): return self.error album = 'Album: {}'.format(response.json()['album']['name']) tracks = ['Tracks: '] t = response.json()['album']['tracks']['track'] for track, index in zip(t, range(len(t))): tracks.append('{}. {}'.format(index + 1, track['name'])) info = [album, '\n'.join(tracks)] if 'wiki' in response.json()['album'].keys(): wiki = response.json()['album']['wiki'] if 'published' in wiki.keys(): info.append('Published: {}'.format(wiki['published'])) if 'summary' in wiki.keys(): summary = wiki['summary'].replace('.', '.\n') spam = summary.find('<a') info.append('Summary: {}'.format(summary[:spam])) if 'Musical style' in wiki.keys(): info.append('Musical style: {}'.format(wiki['Musical style'])) return info def login(self, username, password): """Creates lastFM network.""" self.username = username self.password = pylast.md5(password) try: self.network = pylast.LastFMNetwork(api_key=self.lastFMapikey, api_secret=self.lastFMsecret, username=self.username, password_hash=self.password) except Exception: self.username = None self.password = None self.network = None return False return True def logout(self): """Destoys lastFM network and current user info.""" self.username = None self.password = None self.network = None def loveTrack(self, index): """Love track at index in lastFM.""" if self.network is None: return False track = self.network.get_track(self.musicOrder[index][1], self.musicOrder[index][2]) try: track.love() except Exception: return False return True def unloveTrack(self, index): """Unlove track at index in lastFM.""" if self.network is None: return False track = self.network.get_track(self.musicOrder[index][1], self.musicOrder[index][2]) try: track.unlove() except Exception: return False return True def isMuted(self): """Returns True if player is muted.""" return self.player.isMuted() def getArtist(self, song): """Returns the artist of song.""" if song[-4:] == '.mp3': obj = EasyID3(song) if 'artist' in obj.keys(): return obj['artist'] elif 'TAG' in mediainfo(song).keys(): obj = mediainfo(song)['TAG'] if 'artist' in obj.keys(): return [obj['artist']] elif 'ARTIST' in obj.keys(): return [obj['ARTIST']] else: return ['Unknown'] else: return ['Unknown'] def getTitle(self, song): """Returns the title of song.""" if song[-4:] == '.mp3': obj = EasyID3(song) if 'title' in obj.keys(): return obj['title'] elif 'TAG' in mediainfo(song).keys(): obj = mediainfo(song)['TAG'] if 'title' in obj.keys(): return [obj['title']] elif 'TITLE' in obj.keys(): return [obj['TITLE']] else: return ['Unknown'] else: return ['Unknown'] def getAlbum(self, song): """Returns the album of song.""" if song[-4:] == '.mp3': obj = EasyID3(song) if 'album' in obj.keys(): return obj['album'] elif 'TAG' in mediainfo(song).keys(): obj = mediainfo(song)['TAG'] if 'album' in obj.keys(): return [obj['album']] elif 'ALBUM' in obj.keys(): return [obj['ALBUM']] else: return ['Unknown'] else: return ['Unknown'] def getDuration(self, song): """Returns the duration of song.""" if song[-4:] == '.mp3': return MP3(song).info.length return int(float(mediainfo(song)['duration']))
class task1(QDialog): def __init__(self, nam): super(task1,self).__init__() loadUi('..\gui\task.ui',self) self.setWindowTitle('Activity Recorder') self.setWindowIcon(QIcon('..\resources\icon.png')) self.image = None self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videoWidget = QVideoWidget(self) self.recording = False self.start_webcam.clicked.connect(self.startWebcam) self.stop_webcam.clicked.connect(self.stopWebcam) self.exit.clicked.connect(self.exitClicked) self.playStatus = 'Pause' self.nameLabel.setText(nam) self.name = nam layout = QVBoxLayout() layout.addWidget(videoWidget) self.mediaPlayer.setVideoOutput(videoWidget) self.widget.setLayout(layout) self.cwd = os.getcwd() self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(self.cwd+"..\lecture_videos\lecture.mp4"))) self.webcamEnabled = 0 self.frame = 0 self.markerArr = [] self.c0.stateChanged.connect(lambda: self.checkClick(0,self.c0)) self.c1.stateChanged.connect(lambda: self.checkClick(1,self.c1)) self.c2.stateChanged.connect(lambda: self.checkClick(2,self.c2)) self.c3.stateChanged.connect(lambda: self.checkClick(3,self.c3)) self.c4.stateChanged.connect(lambda: self.checkClick(4,self.c4)) self.c5.stateChanged.connect(lambda: self.checkClick(5,self.c5)) self.c6.stateChanged.connect(lambda: self.checkClick(6,self.c6)) self.c7.stateChanged.connect(lambda: self.checkClick(7,self.c7)) self.c8.stateChanged.connect(lambda: self.checkClick(8,self.c8)) self.c9.stateChanged.connect(lambda: self.checkClick(9,self.c9)) self.capture = None self.out = None self.recordedVideo.clicked.connect(self.videoViewerLaunch) def videoViewerLaunch(self): num, ok = QInputDialog.getText(self, "Verify yourself","Enter Password") if ok and num=='a': viewWindow = videoViewer() viewWindow.show() viewWindow.exec_() elif ok and num!='a': QMessageBox.critical(self, 'Error', "wrong password..", QMessageBox.Ok) def checkClick(self,n,checkItem): if checkItem.isChecked(): self.markerArr.append([self.frame,n]) def exitClicked(self): result = QMessageBox.question(self, 'Message', "Are you sure?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if result == QMessageBox.Yes: if self.capture != None: self.capture.release() self.timer.stop() self.mediaPlayer.stop() if self.out != None: self.out.release() self.close() def startWebcam(self): self.exit.setEnabled = False if self.webcamEnabled == 0: self.savedir = self.cwd+"..\data\\"+self.name if not os.path.exists(self.savedir): os.mkdir(self.savedir) self.fourcc = cv2.VideoWriter_fourcc('X','V','I','D') self.outputFile = self.savedir+"\\"+str(QDateTime.currentMSecsSinceEpoch())+".avi" self.out = cv2.VideoWriter(self.outputFile, self.fourcc, 30.0, (640,480)) self.capture = cv2.VideoCapture(0) self.capture.set(cv2.CAP_PROP_FRAME_WIDTH,640) self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT,480) self.webcamEnabled = 1 self.timer = QTimer(self) self.timer.timeout.connect(self.updateFrame) self.start_webcam.setText(self.playStatus) if self.playStatus=='Play': self.playStatus = 'Pause' self.mediaPlayer.pause() self.timer.stop() self.recording = False else: self.playStatus = 'Play' self.mediaPlayer.play() self.timer.start(5) self.recording = True self.stop_webcam.setEnabled(True) def updateFrame(self): ret, image = self.capture.read() if ret==True: image = cv2.flip(image,1) if self.recording == True: self.out.write(image) self.frame += 1 else: self.stopWebcam() QMessageBox.critical(self, 'Error', "Error opening webcam", QMessageBox.Ok) def saveCSV(self): try: data = pickle.load(open('..\data\data.pkl','rb')) except FileNotFoundError: data = {} data[self.outputFile] = self.markerArr pickle.dump(data,open('..\data\data.pkl','wb')) def stopWebcam(self): self.webcamEnabled = 0 self.timer.stop() self.saveCSV() self.capture.release() self.start_webcam.setText('Play') self.playStatus = 'Pause' self.stop_webcam.setEnabled(False) self.mediaPlayer.stop() self.recording = False self.out.release() self.exit.setEnabled = True
class MyWin(QtWidgets.QMainWindow): lbs = [] rbs = [[''] * 10] * 15 # emply list 15x10 bgrs = [] labels = [] variants = [] correct = [] value = [] tp = [] picName = [] lblPic = [] logStr = '' triggeredNum = 0 minNum = 0 name1 = '' group1 = '' timeRes = 0 timesListening = 4 def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) while self.name1 == '' or self.group1 == '': dialog = StartDialog(self) if dialog.exec_(): self.name1 = dialog.lineEdit.text() self.group1 = dialog.lineEdit_2.text() self.duration = 0 self.playerState = QMediaPlayer.StoppedState self.timerAud = QtCore.QTimer(self) self.player = QMediaPlayer() self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) # frame with buttons play and stop, and duration label self.frame = QtWidgets.QFrame(self.ui.scrollAreaWidgetContents) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame) self.horizontalLayout.setObjectName("horizontalLayout") self.pushButton = QtWidgets.QPushButton(self.frame) self.pushButton.setObjectName("pushButton") self.horizontalLayout.addWidget(self.pushButton) self.pushButton_3 = QtWidgets.QPushButton(self.frame) self.pushButton_3.setObjectName("pushButton_3") self.horizontalLayout.addWidget(self.pushButton_3) self.labelDuration = QtWidgets.QLabel(self.frame) self.labelDuration.setText('0') self.horizontalLayout.addWidget(self.labelDuration) # creating timer self.timer = QtCore.QTimer(self) # xml handling (read & mix) self.mixXml() # read to DOM self.readToDom() # assigning layout to the scrollarea self.verticalLayout = QtWidgets.QVBoxLayout( self.ui.scrollAreaWidgetContents) self.verticalLayout.setObjectName("verticalLayout") # adding title self.trTitle = QtWidgets.QLabel(self.ui.scrollAreaWidgetContents) self.trTitle.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.trTitle.setText('') # adding standart widgets for listening self.verticalLayout.addWidget(self.trTitle) self.lblAud = QtWidgets.QLabel(self.ui.scrollAreaWidgetContents) self.lblAud.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.lblAud.setText('') self.horizontalSlider = QtWidgets.QSlider( self.ui.scrollAreaWidgetContents) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") # adding frame self.verticalLayout.addWidget(self.lblAud) self.verticalLayout.addWidget(self.horizontalSlider) self.verticalLayout.addWidget(self.frame) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPlay)) self.pushButton_3.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaStop)) self.pushButton_3.setEnabled(False) # adding widgets to the scrollarea self.addWidgetsToInterface() self.timer.timeout.connect(lambda: self.updater(self.timeSeconds)) # starting timer self.timer.start(1000) self.player.durationChanged.connect(self.durationChanged1) self.player.positionChanged.connect(self.positionChanged1) self.player.stateChanged.connect(self.setState) self.horizontalSlider.setRange(0, self.player.duration() / 1000) self.pushButton.clicked.connect(self.play1) self.pushButton_3.clicked.connect(self.stop1) self.horizontalSlider.sliderMoved.connect(self.changePosition) self.ui.pushButton.clicked.connect(self.finish) def open1(self, filename): self.audiofile = filename fileInfo = QtCore.QFileInfo(self.audiofile) url = QtCore.QUrl.fromLocalFile(fileInfo.absoluteFilePath()) self.playlist.addMedia(QMediaContent(url)) self.pushButton.setEnabled(True) def play1(self): if self.playerState in (QMediaPlayer.StoppedState, QMediaPlayer.PausedState): self.player.play() elif self.playerState == QMediaPlayer.PlayingState: self.player.pause() def stop1(self): self.player.stop() def positionChanged1(self, progress): progress = progress / 1000 if not self.horizontalSlider.isSliderDown(): self.horizontalSlider.setValue(progress) self.updateDurationInfo(progress) def durationChanged1(self, duration): duration = duration / 1000 self.duration = duration self.horizontalSlider.setMaximum(duration) def updateDurationInfo(self, currentInfo): duration = self.duration if currentInfo or duration: currentTime = QtCore.QTime( (currentInfo / 3600) % 60, (currentInfo / 60) % 60, currentInfo % 60, (currentInfo * 1000) % 1000) totalTime = QtCore.QTime((duration / 3600) % 60, (duration / 60) % 60, duration % 60, (duration * 1000) % 1000) format1 = 'hh:mm:ss' if duration > 3600 else 'mm:ss' tStr = currentTime.toString(format1) + " / " + totalTime.toString( format1) else: tStr = '' if (self.timesListening - 1) < 0: self.labelDuration.setText(tStr + ' -осталось количество прослушиваний ' + '0') else: self.labelDuration.setText(tStr + ' -осталось количество прослушиваний ' + str(self.timesListening - 1)) def setState(self, state): if state != self.playerState: self.playerState = state if state == QMediaPlayer.StoppedState: self.timesListening -= 1 if self.timesListening <= 0: self.pushButton.clicked.connect(self.stop1) self.horizontalSlider.setEnabled(False) self.pushButton_3.setEnabled(False) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPlay)) elif state == QMediaPlayer.PlayingState: self.horizontalSlider.setEnabled(True) self.pushButton_3.setEnabled(True) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPause)) elif state == QMediaPlayer.PausedState: self.horizontalSlider.setEnabled(False) self.pushButton_3.setEnabled(True) self.pushButton.setIcon(self.style().standardIcon( QtWidgets.QStyle.SP_MediaPlay)) def changePosition(self, seconds): if self.playerState == QMediaPlayer.PausedState: pass elif self.playerState == QMediaPlayer.PlayingState: self.player.setPosition(seconds * 1000) def finish(self): self.timeRes = self.timeSeconds self.timeSeconds = 0 def mixXml(self): # read xml and mix the lines self.linesMixed = [] self.r = open("db6.xml", 'r', encoding='utf-8') self.fileRead = self.r.readlines() for line in range(2, len(self.fileRead) - 1): self.linesMixed.append(self.fileRead[line]) random.shuffle(self.linesMixed) self.r.close() # write temporary xml with new mixed lines self.w = open("temp.xml", 'w', encoding='utf-8') self.w.write('''<?xml version="1.0" encoding="utf-8"?>\n<content>\n''') for line in self.linesMixed: self.w.write('%s' % line) self.w.write('</content>') self.w.close() def readToDom(self): # read to DOM self.dom = xml.dom.minidom.parse('temp.xml') self.collection = self.dom.documentElement # reading timeout to a variable self.timeSeconds = int( self.collection.getElementsByTagName("time")[0].childNodes[0].data) # reading title self.title = self.collection.getElementsByTagName( "ttl")[0].childNodes[0].data self.questAudio = self.collection.getElementsByTagName( "aud")[0].childNodes[0].data aud = self.collection.getElementsByTagName("aud")[0] audFile = aud.getAttribute('src') self.open1(audFile) self.timeConstant = self.timeSeconds self.linesArr = self.collection.getElementsByTagName("q") for line in range(0, len(self.linesArr)): # label's text self.labels.append(self.linesArr[line].childNodes[0].data) # variants' text self.variants.append( self.linesArr[line].getAttribute('ans').split('**?**')) # correct answer self.correct.append(self.linesArr[line].getAttribute('cor')) # value self.value.append(int(self.linesArr[line].getAttribute('pnt'))) # reading type self.tp.append(self.linesArr[line].getAttribute('type')) # adding picture name if any if self.linesArr[line].hasAttribute('pic'): self.picName.append(self.linesArr[line].getAttribute('pic')) else: self.picName.append('empty') # Mix variants for variant in self.variants: random.shuffle(variant) # Deleting temporary file os.remove('temp.xml') def addWidgetsToInterface(self): # adding widgets to the scrollarea self.trTitle.setText("Тренажер %s" % self.title) self.lblAud.setText("<b>%s</b>" % self.questAudio) for line in range(0, len(self.labels)): self.lbs.append(QtWidgets.QLabel(self.ui.scrollAreaWidgetContents)) self.lbs[line].setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.lbs[line].setText('<b>%s</b>' % self.labels[line]) self.verticalLayout.addWidget(self.lbs[line]) # adding picture if self.picName[line] != 'empty': self.lblPic.append( QtWidgets.QLabel(self.ui.scrollAreaWidgetContents)) self.lblPic[line].setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.lblPic[line].setPixmap( QtGui.QPixmap(os.getcwd() + "/" + self.picName[line])) self.verticalLayout.addWidget(self.lblPic[line]) else: self.lblPic.append( QtWidgets.QLabel(self.ui.scrollAreaWidgetContents)) # adding button group self.bgrs.append(QtWidgets.QButtonGroup(self.ui.centralwidget)) if self.tp[line] == 'chb': self.bgrs[line].setExclusive(False) self.correct[line] = self.correct[line].split('**?**') # click counter self.bgrs[line].buttonClicked.connect(self.increaseNum) for v in range(0, len(self.variants[line])): # check br/chb if self.tp[line] == 'rb': self.rbs[line][v] = QtWidgets.QRadioButton( self.ui.scrollAreaWidgetContents) elif self.tp[line] == 'chb': self.rbs[line][v] = QtWidgets.QCheckBox( self.ui.scrollAreaWidgetContents) self.bgrs[line].addButton(self.rbs[line][v]) self.rbs[line][v].setText(self.variants[line][v]) self.verticalLayout.addWidget(self.rbs[line][v]) def increaseNum(self): self.triggeredNum += 1 def check(self): counter = 0 for group in range(0, len(self.bgrs)): # adding questions self.logStr += self.labels[group] + '\n' self.logStr += 'Сложность: %d\n' % self.value[group] # check rb/chb if self.tp[group] == 'rb': self.minNum += 1 correctThis = '--' for rb in self.bgrs[group].buttons(): # adding variants self.logStr += '\t' + rb.text() + '\n' if rb.isChecked(): if rb.text() == self.correct[group]: correctThis = rb.text() counter += self.value[group] elif self.tp[group] == 'chb': if self.correct[group][0] != 'none': self.minNum += len(self.correct[group]) correctThis = [] chbCor = [] for rb in self.bgrs[group].buttons(): # adding variants self.logStr += '\t' + rb.text() + '\n' if rb.isChecked(): # marked checkboxes chbCor.append(rb.text()) if len(chbCor) == 0: chbCor.append('none') chbCor.sort() self.correct[group].sort() if self.correct[group] == chbCor: counter += self.value[group] correctThis = chbCor self.logStr += 'Правильный ответ: %s' % self.listToString( self.correct[group]) + '\n' self.logStr += 'Ответ пользователя: %s' % self.listToString( correctThis) + '\n' if self.listToString( self.correct[group]) == self.listToString(correctThis): self.logStr += 'TRUE\n' else: self.logStr += 'FALSE\n' self.logStr += '\n' # And this is the result! Rounded to 2 decimal points self.result = float(counter / sum(self.value) * 100) message = "Your result is " + "%.2f" % self.result + "%" self.ui.statusbar.setStyleSheet('color: navy; font-weight: bold;') self.ui.statusbar.showMessage(message) # creating log file self.log() def listToString(self, getlist): if type(getlist).__name__ == 'list': string = '' for i in getlist: string += i + '; ' string = string[:-2] + '.' return string else: return getlist def updater(self, val): val = self.timeSeconds if val == 0: self.timer.stop() self.check() self.ui.scrollArea.setEnabled(False) self.ui.pushButton.setEnabled(False) self.ui.label.setText(self.intToTime(val)) self.timeSeconds -= 1 def intToTime(self, num): h = 0 m = 0 if num >= 3600: h = num // 3600 num = num % 3600 if num >= 60: m = num // 60 num = num % 60 s = num str1 = "%d." % h if m < 10: str1 += "0%d:" % m else: str1 += "%d:" % m if s < 10: str1 += "0%d" % s else: str1 += "%d" % s return str1 # returns time as a string def log(self): logFileName = self.name1 + '_' + self.group1 + '_%.2f' % self.result + '_' + str( self.timeConstant - self.timeRes) + '_%.2f' % ( self.triggeredNum / self.minNum * 100) + '_' + str( int(round(time.time() * 1000))) + '.txt' file = open(logFileName, 'w', encoding='utf-8') file.write("Тренажер: %s\n" % self.title) file.write("Имя: %s\nГруппа: %s\n" % (self.name1, self.group1)) file.write("Дата и время записи: ") file.write(time.strftime("%Y-%m-%d %H:%M:%S")) file.write('\n\n') file.write(self.logStr) file.write('\n') file.write("Результат: %.2f" % self.result + " %\n") file.write('Выполнено за %d с\n' % (self.timeConstant - self.timeRes)) # Nubmer of iteractions in percent relative to minimal number of interactions. # Minimal number of iteractions equals the quantity of radio buttons # multiplied by the quantity of correct variants in questions with check boxes # see line 140 and 150-151. file.write('Коэффициент интеракций: %.2f' % (self.triggeredNum / self.minNum * 100) + ' %') # makes log file read only os.chmod(os.path.abspath(logFileName), stat.S_IREAD) file.close() self.triggeredNum = 0 self.logStr = ''
class PodCastPlayer(QWidget): downloadClicked = pyqtSignal() def __init__(self, parent=None): super().__init__() self.layout = QHBoxLayout(self) self.playButton = QPushButton(self) self.playButton.setText(self.tr("Play")) self.pauseButton = QPushButton(self) self.pauseButton.setText(self.tr("Pause")) self.stopButton = QPushButton(self) self.stopButton.setText(self.tr("Stop")) self.playerProgress = QSlider(self) self.playerProgress.setOrientation(Qt.Horizontal) self.playerProgress.setValue(0) self.timeLabel = QLabel(self) self.timeLabel.setText("00:00") self.durationLabel = QLabel(self) self.durationLabel.setText("00:00") self.downloadButton = QPushButton(self) self.downloadButton.setText(self.tr("Download")) self.layout.addWidget(self.playButton) self.layout.addWidget(self.pauseButton) self.layout.addWidget(self.stopButton) self.layout.addWidget(self.timeLabel) self.layout.addWidget(self.playerProgress) self.layout.addWidget(self.durationLabel) self.layout.addWidget(self.downloadButton) self.mediaPlayer = QMediaPlayer(self) self.mediaPlayer.setVolume(100) self.playButton.clicked.connect(self.play) self.pauseButton.clicked.connect(self.pause) self.stopButton.clicked.connect(self.stop) self.downloadButton.clicked.connect(self.downloadClicked) self.playerProgress.sliderMoved.connect(self.mediaPlayer.setPosition) self.mediaPlayer.durationChanged.connect( self.playerProgress.setMaximum) self.mediaPlayer.durationChanged.connect(self.setDurationLabel) self.mediaPlayer.positionChanged.connect(self.setTimeLabel) self.mediaPlayer.positionChanged.connect(self.playerProgress.setValue) def setDurationLabel(self, duration): self.durationLabel.setText( time.strftime("%H:%M:%S", time.gmtime(duration / 1000))) def setTimeLabel(self, pos): self.timeLabel.setText( time.strftime("%H:%M:%S", time.gmtime(pos / 1000))) def addMedia(self, media): self.url = QUrl(media) self.playerProgress.setValue(0) self.timeLabel.setText("00:00") self.durationLabel.setText("00:00") self.mediaPlayer.setMedia(QMediaContent(QNetworkRequest(self.url))) def play(self): self.mediaPlayer.play() def pause(self): self.mediaPlayer.pause() def stop(self): self.mediaPlayer.stop()
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
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.curDictWord = None self.curWord = None self.curDictWordChange = False self.curDictWordLock = False self.ui = Ui_MainWindow_Ex() self.ui.setupUi(self) # hide progress bar self.ui.groupBox_5.setVisible(False) self.ui.groupBox_7.setVisible(False) # --------------------------------- # init dictionary self.dictionaries = [CambridgeUS(), CambridgeUK()] for obj in self.dictionaries: self.ui.dictBox.addItem(obj.displayname) self.ui.dictBox.currentIndexChanged.connect(self._dictionary_change) # connection self.ui.qwebView.loadStarted.connect(self._load_started) self.ui.qwebView.loadProgress.connect(self._load_progress) self.ui.qwebView.loadFinished.connect(self._load_finished) self.ui.refresh.clicked.connect(self._refresh_webview) self.ui.dictMktts.clicked.connect(self._refresh_mktts) # select dict self.ui.dictBox.setCurrentIndex(0) self._dictionary_change(0) # --------------------------------- # media play self.titlePlayer = QMediaPlayer(self) self.titlePlayer.stateChanged.connect(self._titleStateChanged) self.ui.titlePlay.clicked.connect(self._titlePlay) self.ui.titleStop.clicked.connect(self._titleStop) self.ui.titleMktts.clicked.connect(self._titleMktts) self.ui.titleEdit.textChanged.connect(self._titleTextChanged) self.contentPlayer = QMediaPlayer(self) self.contentPlayer.stateChanged.connect(self._contentStateChanged) self.ui.contentPlay.clicked.connect(self._contentPlay) self.ui.contentStop.clicked.connect(self._contentStop) self.ui.contentMktts.clicked.connect(self._contentMktts) self.ui.contentEdit.textChanged.connect(self._contentTextChanged) self.ui.tabBar.currentChanged.connect(self._tarbarChanged) self.update_dictword(None) def save_dictword_change(self): if self.curDictWordChange and self.curDictWord: self.curDictWord.save() def stop_voice_play(self): if self.titlePlayer.state() == QMediaPlayer.PlayingState: self.titlePlayer.stop() self.titlePlayer.setPlaylist(None) if self.contentPlayer.state() == QMediaPlayer.PlayingState: self.contentPlayer.stop() self.contentPlayer.setPlaylist(None) def update_dictword(self, dictwordobj): # if busy to mktts , don't update to cur dictword if self.curDictWordLock: return self.save_dictword_change() self.stop_voice_play() self.curDictWord = None self.curWord = None for i in range(self.ui.tabBar.count() - 1, -1, -1): self.ui.tabBar.removeTab(i) if dictwordobj is None: self.ui.queryword.setText('') self.ui.titleEdit.setPlainText('') self.ui.contentEdit.setPlainText('') self.ui.tabBar.setVisible(False) self.ui.titleEdit.setEnabled(False) self.ui.titlePlay.setEnabled(False) self.ui.titleStop.setEnabled(False) self.ui.titleMktts.setEnabled(False) self.ui.contentEdit.setEnabled(False) self.ui.contentPlay.setEnabled(False) self.ui.contentStop.setEnabled(False) self.ui.contentMktts.setEnabled(False) else: if len(dictwordobj.words) > 1: for w in dictwordobj.words: self.ui.tabBar.addTab(w.name) self.ui.tabBar.setCurrentIndex(0) self.ui.tabBar.setVisible(True) else: self.ui.tabBar.setVisible(False) self.curDictWord = dictwordobj self.curWord = dictwordobj.words[0] self.ui.queryword.setText(self.curDictWord.query_word) self.ui.titleEdit.setPlainText(self.curWord.title_text) self.ui.contentEdit.setPlainText(self.curWord.content_text) self.ui.titleEdit.setEnabled(True) self.ui.titleMktts.setEnabled(True) self.ui.titlePlay.setEnabled(True) self.ui.titleStop.setEnabled(False) self.ui.contentEdit.setEnabled(True) self.ui.contentMktts.setEnabled(True) self.ui.contentPlay.setEnabled(True) self.ui.contentStop.setEnabled(False) @pyqtSlot(int) def _tarbarChanged(self, index): if self.curDictWord is None: return self.stop_voice_play() self.curWord = self.curDictWord.words[index] self.ui.titleEdit.setPlainText(self.curWord.title_text) self.ui.contentEdit.setPlainText(self.curWord.content_text) self.ui.titleEdit.setEnabled(True) self.ui.titleMktts.setEnabled(True) self.ui.titlePlay.setEnabled(True) self.ui.titleStop.setEnabled(False) self.ui.contentEdit.setEnabled(True) self.ui.contentMktts.setEnabled(True) self.ui.contentPlay.setEnabled(True) self.ui.contentStop.setEnabled(False) @pyqtSlot() def _titleTextChanged(self): if self.curDictWord is None: return txt = self.ui.titleEdit.toPlainText() self.curWord.title_text = txt self.curDictWordChange = True @pyqtSlot(bool) def _titlePlay(self, checked): if self.curDictWord is None: return self.stop_voice_play() if self.curWord.title_voices: mp3list = [os.path.join(self.curDictWord.data_path, fname) for fname in self.curWord.title_voices] playlist = QMediaPlaylist(self) for fmp3 in mp3list: playlist.addMedia(QUrl.fromLocalFile(fmp3)) self.titlePlayer.setPlaylist(playlist) self.titlePlayer.play() @pyqtSlot(bool) def _titleStop(self, checked): self.stop_voice_play() @pyqtSlot(bool) def _titleMktts(self, checked): if self.curDictWord is None: return self.stop_voice_play() self.mk_voice(True) @pyqtSlot() def _contentTextChanged(self): if self.curDictWord is None: return txt = self.ui.contentEdit.toPlainText() self.curWord.content_text = txt self.curDictWordChange = True @pyqtSlot(bool) def _contentPlay(self, checked): if self.curDictWord is None: return self.stop_voice_play() if self.curWord.content_voices: mp3list = [os.path.join(self.curDictWord.data_path, fname) for fname in self.curWord.content_voices] playlist = QMediaPlaylist(self) for fmp3 in mp3list: playlist.addMedia(QUrl.fromLocalFile(fmp3)) self.titlePlayer.setPlaylist(playlist) self.titlePlayer.play() @pyqtSlot(bool) def _contentStop(self, checked): self.stop_voice_play() @pyqtSlot(bool) def _contentMktts(self, checked): if self.curDictWord is None: return self.stop_voice_play() self.mk_voice(False) @pyqtSlot(QMediaPlayer.State) def _titleStateChanged(self, status): if status == QMediaPlayer.PlayingState: self.ui.titlePlay.setEnabled(False) self.ui.titleStop.setEnabled(True) else: self.ui.titlePlay.setEnabled(True) self.ui.titleStop.setEnabled(False) @pyqtSlot(QMediaPlayer.State) def _contentStateChanged(self, status): if status == QMediaPlayer.PlayingState: self.ui.contentPlay.setEnabled(False) self.ui.contentStop.setEnabled(True) else: self.ui.contentPlay.setEnabled(True) self.ui.contentStop.setEnabled(False) @pyqtSlot(int) def _dictionary_change(self, index): diobj = self.dictionaries[index] self.ui.accentBox.clear() lang = diobj.language default_ttslang = diobj.default_ttslang for k, v in tts_languages: if k.startswith(lang): self.ui.accentBox.addItem(v, k) for i in range(self.ui.accentBox.count()): k = self.ui.accentBox.itemData(i) if k == default_ttslang: self.ui.accentBox.setCurrentIndex(i) break else: self.ui.accentBox.setCurrentIndex(0) self.ui.qwebView.load(QUrl(diobj.home)) @pyqtSlot(bool) def _refresh_webview(self, checked): self.ui.qwebView.reload() @pyqtSlot(bool) def _refresh_mktts(self, checked): url = self.ui.qwebView.page().url() index = self.ui.dictBox.currentIndex() diobj = self.dictionaries[index] qok, qword = diobj.check_url(url) if qok: tts_lang = self.ui.accentBox.currentData() dictwordobj, is_new = self.load_word(diobj, qword, tts_lang) if not is_new: dictwordobj.words.clear() func = partial(self.process, diobj, dictwordobj) self.ui.qwebView.page().toHtml(func) @pyqtSlot() def _load_started(self): self.ui.groupBox_7.setVisible(True) self.ui.dictBox.setEnabled(False) self.ui.accentBox.setEnabled(False) self.ui.dictMktts.setEnabled(False) @pyqtSlot(int) def _load_progress(self, val): self.ui.loadingBar.setValue(val) @pyqtSlot(bool) @except_check def _load_finished(self, bok): self.ui.groupBox_7.setVisible(False) self.ui.dictBox.setEnabled(True) self.ui.accentBox.setEnabled(True) self.ui.dictMktts.setEnabled(True) if bok: url = self.ui.qwebView.page().url() index = self.ui.dictBox.currentIndex() diobj = self.dictionaries[index] qok, qword = diobj.check_url(url) if qok: tts_lang = self.ui.accentBox.currentData() dictwordobj, is_new = self.load_word(diobj, qword, tts_lang) if is_new: func = partial(self.process, diobj, dictwordobj) self.ui.qwebView.page().toHtml(func) else: self.update_dictword(dictwordobj) def closeEvent(self, event): """ rewrite closeEvent, so when mainwindows closing, can clear up :param event: :return: None """ AsyncTask.check_thread() self.save_dictword_change() def load_word(self, diobj, qword, tts_lang): """ load dictobj, if don't exist then create it :param diobj: :param qword: :return: dictobj, is_new """ data_path = os.path.join(data_dir, 'dictionaries', diobj.name, qword) if os.path.exists(data_path) and not os.path.isdir(data_path): raise RuntimeError("Loading failed: [%s] is'nt directory" % data_path) if os.path.exists(data_path): try: dictwordobj = DictWord.load(data_path) return dictwordobj, False except Exception as e: QMessageBox.warning(self, 'Warning', 'Loading failed: [%s], %s' % (data_path, str(e))) else: os.makedirs(data_path, exist_ok=True) dictwordobj = DictWord(data_path=data_path, tts_lang=tts_lang, query_word=qword) return dictwordobj, True @coroutine def process(self, diobj, dictwordobj, html): self.ui.groupBox_5.setVisible(True) try: info = '%s, parse html' % dictwordobj.query_word self.ui.progressBar.setValue(0) self.ui.progressLabel.setText(info) bok = yield AsyncTask(diobj.parse_html, dictwordobj, html) if not bok: dictwordobj.clear() info = '%s, parse failed!' % dictwordobj.query_word self.ui.progressBar.setValue(100) self.ui.progressLabel.setText(info) yield AsyncTask(time.sleep, 3) self.ui.groupBox_5.setVisible(False) return info = '%s, translate to voice ...' % dictwordobj.query_word self.ui.progressBar.setValue(10) self.ui.progressLabel.setText(info) total = 0 for w in dictwordobj.words: if not w.title_voices and w.title_text: total += 1 if not w.content_voices and w.content_text: total += 1 cur = 0 for w in dictwordobj.words: if not w.title_voices and w.title_text: fname, fpath = dictwordobj.mk_voice_fname() yield AsyncTask(trans_tts, w.title_text, fpath) w.title_voices.append(fname) cur += 1 progress = 10 + int(90 * cur / total) self.ui.progressBar.setValue(progress) self.ui.progressLabel.setText(info) if not w.content_voices and w.content_text: fname, fpath = dictwordobj.mk_voice_fname() yield AsyncTask(trans_tts, w.content_text, fpath) w.content_voices.append(fname) progress = 10 + int(90 * cur / total) self.ui.progressBar.setValue(progress) self.ui.progressLabel.setText(info) except (Exception, GeneratorExit): dictwordobj.clear() self.ui.groupBox_5.setVisible(False) raise info = '%s, finished!' % dictwordobj.query_word self.ui.progressBar.setValue(100) self.ui.progressLabel.setText(info) dictwordobj.save() self.ui.groupBox_5.setVisible(False) self.update_dictword(dictwordobj) return @coroutine(is_block=True) def mk_voice(self, is_title): self.curDictWordLock = True progressdlg = QProgressDialog('Mktts', parent=self) progressdlg.setWindowModality(Qt.WindowModal) progressdlg.setAutoClose(False) progressdlg.setAutoReset(False) progressdlg.setCancelButton(None) progressdlg.show() try: info = '%s, translate to voice ...' % self.curDictWord.query_word progressdlg.setLabelText(info) progressdlg.setValue(10) fname, fpath = self.curDictWord.mk_voice_fname() txt = self.curWord.title_text if is_title else self.curWord.content_text yield AsyncTask(trans_tts, txt, fpath) if is_title: self.curWord.title_voices = [fname] else: self.curWord.content_voices = [fname] except (Exception, GeneratorExit): self.curDictWordLock = False progressdlg.done(0) raise info = '%s, finished!' % self.curDictWord.query_word progressdlg.setLabelText(info) progressdlg.setValue(100) self.curDictWordChange = True self.curDictWordLock = False progressdlg.done(0) return
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
class VideoPlayer(QWidget): def __init__(self, aPath, parent=None): super(VideoPlayer, self).__init__(parent) self.setAttribute(Qt.WA_NoSystemBackground, True) self.setAcceptDrops(True) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback) self.mediaPlayer.setVolume(80) self.videoWidget = QVideoWidget(self) self.videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.videoWidget.setMinimumSize(QSize(640, 360)) self.lbl = QLineEdit('00:00:00') self.lbl.setReadOnly(True) self.lbl.setFixedWidth(70) self.lbl.setUpdatesEnabled(True) self.lbl.setStyleSheet(stylesheet(self)) self.elbl = QLineEdit('00:00:00') self.elbl.setReadOnly(True) self.elbl.setFixedWidth(70) self.elbl.setUpdatesEnabled(True) self.elbl.setStyleSheet(stylesheet(self)) self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setFixedWidth(32) self.playButton.setStyleSheet("background-color: black") self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal, self) self.positionSlider.setStyleSheet(stylesheet(self)) self.positionSlider.setRange(0, 100) self.positionSlider.sliderMoved.connect(self.setPosition) self.positionSlider.sliderMoved.connect(self.handleLabel) self.positionSlider.setSingleStep(2) self.positionSlider.setPageStep(20) self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True) self.clip = QApplication.clipboard() self.process = QProcess(self) self.process.readyRead.connect(self.dataReady) self.process.finished.connect(self.playFromURL) self.myurl = "" # channel list self.channelList = QListView(self) self.channelList.setMinimumSize(QSize(150, 0)) self.channelList.setMaximumSize(QSize(150, 4000)) self.channelList.setFrameShape(QFrame.Box) self.channelList.setObjectName("channelList") self.channelList.setStyleSheet("background-color: black; color: #585858;") self.channelList.setFocus() # for adding items to list must create a model self.model = QStandardItemModel() self.channelList.setModel(self.model) self.controlLayout = QHBoxLayout() self.controlLayout.setContentsMargins(5, 0, 5, 0) self.controlLayout.addWidget(self.playButton) self.controlLayout.addWidget(self.lbl) self.controlLayout.addWidget(self.positionSlider) self.controlLayout.addWidget(self.elbl) self.mainLayout = QHBoxLayout() # contains video and cotrol widgets to the left side self.layout = QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.videoWidget) self.layout.addLayout(self.controlLayout) # adds channels list to the right self.mainLayout.addLayout(self.layout) self.mainLayout.addWidget(self.channelList) self.setLayout(self.mainLayout) self.myinfo = "©2020\nTIVOpy v1.0" self.widescreen = True #### shortcuts #### self.shortcut = QShortcut(QKeySequence("q"), self) self.shortcut.activated.connect(self.handleQuit) self.shortcut = QShortcut(QKeySequence("u"), self) self.shortcut.activated.connect(self.playFromURL) self.shortcut = QShortcut(QKeySequence(Qt.Key_Space), self) self.shortcut.activated.connect(self.play) self.shortcut = QShortcut(QKeySequence(Qt.Key_F), self) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self) self.shortcut.activated.connect(self.exitFullscreen) self.shortcut.activated.connect(self.handleFullscreen) self.shortcut = QShortcut(QKeySequence("i"), self) self.shortcut.activated.connect(self.handleInfo) self.shortcut = QShortcut(QKeySequence("s"), self) self.shortcut.activated.connect(self.toggleSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self) self.shortcut.activated.connect(self.forwardSlider) self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self) self.shortcut.activated.connect(self.backSlider) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) self.populateChannelList() self.selectChannel() self.initialPlay() def playFromURL(self): self.mediaPlayer.pause() self.myurl = self.clip.text() self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() print(self.myurl) def dataReady(self): self.myurl = str(self.process.readAll(), encoding='utf8').rstrip() ### self.myurl = self.myurl.partition("\n")[0] print(self.myurl) self.clip.setText(self.myurl) self.playFromURL() def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playButton.setIcon( self.style().standardIcon(QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) mtime = QTime(0, 0, 0, 0) mtime = mtime.addMSecs(self.mediaPlayer.duration()) self.elbl.setText(mtime.toString()) def setPosition(self, position): self.mediaPlayer.setPosition(position) def handleError(self): self.playButton.setEnabled(False) print("Error: ", self.mediaPlayer.errorString()) def handleQuit(self): self.mediaPlayer.stop() print("Goodbye ...") app.quit() def contextMenuRequested(self, point): menu = QMenu() actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)") menu.addSeparator() actionToggle = menu.addAction(QIcon.fromTheme("next"), "Show / Hide Channels (s)") actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)") menu.addSeparator() actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "About (i)") menu.addSeparator() actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)") actionQuit.triggered.connect(self.handleQuit) actionFull.triggered.connect(self.handleFullscreen) actionInfo.triggered.connect(self.handleInfo) actionToggle.triggered.connect(self.toggleSlider) actionURL.triggered.connect(self.playFromURL) menu.exec_(self.mapToGlobal(point)) def wheelEvent(self, event): mscale = event.angleDelta().y() / 13 self.mediaPlayer.setVolume(self.mediaPlayer.volume() + mscale) print("Volume: " + str(self.mediaPlayer.volume())) def mouseDoubleClickEvent(self, event): if event.buttons() == Qt.LeftButton: self.handleFullscreen() def handleFullscreen(self): if self.windowState() and Qt.WindowFullScreen: self.showNormal() else: self.showFullScreen() def exitFullscreen(self): self.showNormal() def handleInfo(self): QMessageBox.about(self, "About", self.myinfo) def toggleSlider(self): if self.positionSlider.isVisible(): self.hideSlider() else: self.showSlider() def hideSlider(self): self.channelList.hide() self.playButton.hide() self.lbl.hide() self.positionSlider.hide() self.elbl.hide() def showSlider(self): self.channelList.show() self.playButton.show() self.lbl.show() self.positionSlider.show() self.elbl.show() self.channelList.setFocus() def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60) def volumeUp(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() elif event.mimeData().hasText(): event.accept() else: event.ignore() def dropEvent(self, event): print("drop") if event.mimeData().hasUrls(): url = event.mimeData().urls()[0].toString() print("url = ", url) self.mediaPlayer.stop() self.mediaPlayer.setMedia(QMediaContent(QUrl(url))) self.playButton.setEnabled(True) self.mediaPlayer.play() elif event.mimeData().hasText(): mydrop = event.mimeData().text() print("generic url = ", mydrop) self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop))) self.playButton.setEnabled(True) self.mediaPlayer.play() self.hideSlider() def loadFilm(self, f): self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f))) self.playButton.setEnabled(True) self.mediaPlayer.play() def populateChannelList(self): # file must be in same directory as the script FILEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "canaletv.txt") # lines from file with "channel name" -- "link" channelArray = [] # split file by line and adding it to the array with open(FILEPATH) as f: for line in f: channelArray.append(line.rstrip()) # dictionary with key = channel name and value = link self.channelDict = dict(ch.split(" -- ") for ch in channelArray) for channel in self.channelDict.keys(): item = QStandardItem(channel) self.model.appendRow(item) def selectedItemBehavior(self, index): # gets the link for the selected channel and plays it itms = self.channelList.selectedIndexes() for it in itms: channel = it.data() link = self.channelDict[channel] self.mediaPlayer.setMedia(QMediaContent(QUrl(link))) self.play() def selectChannel(self): # selecting channel from sidebar calls selectedItemBehavior self.selModel = self.channelList.selectionModel() self.selModel.selectionChanged.connect(self.selectedItemBehavior) def initialPlay(self): # play somenting when app opens self.mediaPlayer.setMedia(QMediaContent(QUrl("https://vid.hls.protv.ro/proxhdn/proxhd_3_34/index.m3u8?1"))) self.play() def handleLabel(self): self.lbl.clear() mtime = QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.lbl.setText(self.time.toString())
class BasicVideoWidget(QVideoWidget): def __init__(self, *args, **kwargs): super(BasicVideoWidget, self).__init__(*args, **kwargs) self.mediaPlayer = QMediaPlayer(parent=self) self.setMediaObject(self.mediaPlayer) self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(QMediaPlaylist.Loop) self.mediaPlayer.setPlaylist(self.playlist) self.mediaPlayer.positionChanged.connect(self._positionChanged) self.mediaPlayer.mutedChanged.connect(self.mutedChanged) self.mediaPlayer.durationChanged.connect(self._durationChanged) self.mediaPlayer.stateChanged.connect(self.stateChanged) self.mediaPlayer.seekableChanged.connect(self.seekableChanged) def loadUrl(self, url): mc = QMediaContent(url) self.playlist.clear() self.playlist.addMedia(mc) def load(self, path): self.loadUrl(QUrl.fromLocalFile(os.path.abspath(path))) @Slot() def play(self): self.mediaPlayer.play() @Slot() def pause(self): self.mediaPlayer.pause() @Slot() def stop(self): self.mediaPlayer.stop() @Slot(bool) def setMuted(self, b): self.mediaPlayer.setMuted(b) mutedChanged = Signal(bool) @Slot() def playPause(self): if self.mediaPlayer.state() != QMediaPlayer.PlayingState: self.mediaPlayer.play() else: self.mediaPlayer.pause() def state(self): return self.mediaPlayer.state() stateChanged = Signal(QMediaPlayer.State) def duration(self): return self.mediaPlayer.duration() durationChanged = Signal(int) @Slot(int) def setPosition(self, p): self.mediaPlayer.setPosition(p) def position(self): return self.mediaPlayer.position() @Slot('qint64') def _positionChanged(self, p): self.positionChanged.emit(p) positionChanged = Signal(int) @Slot('qint64') def _durationChanged(self, p): self.durationChanged.emit(p) seekableChanged = Signal(bool) def isSeekable(self): return self.mediaPlayer.isSeekable()
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())
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)
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())
class videoPlayer(QVideoWidget): def __init__(self, parent): super(QVideoWidget, self).__init__(parent) self.player = QMediaPlayer(self) self.player.setVolume(50) self.player.setVideoOutput(self) self.player.mediaStatusChanged.connect(self.mediaStatusChanged) def update(self, path): if path: path = QUrl.fromLocalFile(path) self.player.setMedia(QMediaContent(path)) self.player.play() def rotate(self, path, sign): self.update(None) clip = VideoFileClip(path) clip.rotate(90 * sign) if path.endswith(('gif')): clip.write_gif(path) else: clip.write_videofile(path) clip.close() def pause(self): status = self.player.state() if status == QMediaPlayer.PlayingState: self.player.pause() elif status == QMediaPlayer.PausedState: self.player.play() def position(self, delta): self.player.setPosition(self.player.position() + delta) def volume(self, delta): if self.player.isAudioAvailable(): self.player.setVolume(self.player.volume() + delta) def mute(self): if self.player.isAudioAvailable(): self.player.setMuted(not self.player.isMuted()) def stop(self): self.player.stop() def mediaStatusChanged(self, status): if status == QMediaPlayer.EndOfMedia: self.player.play() elif status not in (2, 1): self.parent().setCurrentIndex(1) def wheelEvent(self, event): self.volume(event.angleDelta().y() // 12)
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()
class Player(QGraphicsVideoItem): isSubtitle = pyqtSignal(bool) subtitlePos = pyqtSignal(int) def __init__(self, parent=None): super().__init__() self.parent = parent self.player = QMediaPlayer() self.player.setVolume(int(settings().value("Player/volume") or 100)) self.player.setVideoOutput(self) self.timer = QTimer(self) self.timer.timeout.connect(self.timerPos) self.player.currentMediaChanged.connect(self.signalStart) self.player.currentMediaChanged.connect(self.parent.subtitleitem.subtitleControl) self.player.currentMediaChanged.connect(self.videoConfigure) """self.player.mediaStatusChanged.connect(self.metadata) def metadata(self, data): if data and self.player.isMetaDataAvailable(): print(self.player.metaData("VideoCodec"))""" def videoConfigure(self, media): video_name = os.path.basename(media.canonicalUrl().toLocalFile()) videos = settings().value("Player/video_names") or [] videos_time = settings().value("Player/videos_time") or [] try: self.player.setPosition(int(videos_time[videos.index(video_name)])) except ValueError: pass def timerStart(self): self.timer.start(200) def signalStart(self, content): srt = content.canonicalUrl().toLocalFile().split(".") srt.pop(-1) srt.append("srt") srt = ".".join(srt) if QFile.exists(srt): self.isSubtitle.emit(True) self.timer.start(100) else: self.isSubtitle.emit(False) self.timer.stop() def timerPos(self): self.subtitlePos.emit(self.player.position()) def playerPlayOrOpen(self, arg=None): if type(arg) == list and len(arg) > 1: content = QMediaContent(QUrl.fromLocalFile(arg[1])) self.player.setMedia(content) self.play() def addVideo(self, video): content = QMediaContent(QUrl.fromLocalFile(video)) self.player.setMedia(content) self.play() def addYoutubeVideo(self, video): dm = DownloadManager(self) content = QMediaContent(dm.addUrl(video)) self.player.setMedia(content) self.play() def sliderChanged(self, pos): self.player.setPosition(pos) def play(self): self.player.play() def stop(self): self.player.stop() def pause(self): self.player.pause() def setMuted(self, mute): self.player.setMuted(mute) def mutedState(self): if self.player.isMuted(): self.setMuted(False) else: self.setMuted(True) def isMuted(self): return self.player.isMuted() def setVolume(self, value): self.player.setVolume(value) def volume(self): return self.player.volume()
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())
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)
class MainWidget(QWidget): def __init__(self): super(MainWidget, self).__init__() self._blur = QGraphicsBlurEffect() self._blur.setBlurRadius(0) self.image = ImageView() self.image.setGraphicsEffect(self._blur) self.video = QVideoWidget() self.label = QLabel() self.label.setMaximumHeight(25) self.label.setStyleSheet('color: rgb(200, 200, 200);') font = QFont() font.setPixelSize(20) font.setWeight(QFont.Bold) self.label.setFont(font) self.setLayout(QVBoxLayout()) self.layout().addWidget(self.image) self.layout().addWidget(self.video) self.layout().addWidget(self.label) self.mplayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.mplayer.setVideoOutput(self.video) self.mplayer.error.connect( lambda: print("Video:", self.mplayer.errorString())) self.mplayer.mediaStatusChanged.connect(self.state_changed) self.overlay = QLabel(self) self.overlay.setFrameStyle(Qt.FramelessWindowHint) self.overlay.setStyleSheet( 'background-color: rgba(0,0,0,0.7); color: rgba(200,200,200,1);') self.overlay.setFont(font) self.overlay.setVisible(False) self.overlay.setWordWrap(True) def resize(self): self.overlay.setGeometry(0, 3 * self.height() // 4 - 50, self.width(), 100) def resizeEvent(self, event): super().resizeEvent(event) self.resize() def state_changed(self, state): if state == QMediaPlayer.EndOfMedia: self.mplayer.setPosition(0) self.mplayer.play() @property def blur(self): return self._blur.blurRadius() @blur.setter def blur(self, value): self._blur.setBlurRadius(value) def load(self, pic, *args, **kwargs): if isinstance(pic, str): still = path.splitext(pic)[1].lower()[1:] not in ('webm', 'mp4') else: still = pic.is_still if pic else True if still: self.image.load(pic, *args, **kwargs) self.video.hide() self.image.show() self.mplayer.stop() else: url = pic if isinstance(pic, str) else pic.filename self.mplayer.setMedia(QMediaContent(QUrl.fromLocalFile(url))) self.mplayer.setMuted(True) self.mplayer.play() self.image.hide() self.video.show() self.overlay.setVisible(False) def message(self, msg): self.label.setText('<div align="center">{}</div>'.format(msg)) def flash(self, msg): self.overlay.setText('<div align="center">{}</div>'.format(msg)) self.overlay.setVisible(True) def halt(self): self.mplayer.stop()
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 ""