class MyWin(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.ui = Ui_VideoPlayer() self.ui.setupUi(self) self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.media_player_widget = QVideoWidget(self.ui.mid_frame) self.ui.mid_frame_layout.addWidget(self.media_player_widget) self.media_player.setVideoOutput(self.media_player_widget) self.media_player.error.connect(self.handleError) # fileName="E:/Dropbox/Hobby/PRG/PyWork/FGet/view/qt_ui/files/1.mp4" # self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) # fileName="E:/exchange/DiskD/kl/1/road_to_abbi_big-1080.mp4.Epidemz.net_Triksa.com.mp4" # self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(fileName))) self.ui.bn_go.clicked.connect(self.go) self.media_player.bufferStatusChanged.connect(self.buf) self.media_player.mediaStatusChanged.connect(self.med) # url='http://tubedupe.com/get_file/1/693b07616d5019e3e266e772676e3048/56000/56102/56102.mp4' url = 'http://tubedupe.com/get_file/1/4b274e3f4027b13bf6d6ae5601dd7a09/50000/50768/50768.mp4' url = 'http://www.mypornovideo.net/video_file/2015/2/830/grudastaja_blondinka_ebetsja_s_kuchejj_muzhikov.flv' url = "http://im.50f9bc00.493dea4.cdn2b.movies.mxn.com/0/399/399060/NOWATERMARK_IPOD.mp4?s=1423689551&e=1423696751&ri=1227&rs=44&h=d0a58a04acc858983a202b5e8dea575a" self.media_player.setMedia(QMediaContent(QUrl(url))) self.media_player.play() self.media_player.setMuted(True) print(self.media_player.duration()) print('Done') def handleError(self): print('Error: ' + self.media_player.errorString()) def buf(self, percent): print(percent, '%') def med(self, media): print(media) def go(self): dur = self.media_player.duration() pos = self.media_player.position() print(dur // 1000, pos // 1000) print(self.media_player.bufferStatus()) # self.hide() self.media_player.stop()
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 MainWindow(QMainWindow): def __init__(self, app): super(MainWindow, self).__init__() self.app = app print('window created') self.setWindowIcon(QIcon('img/icon.png')) self.setWindowTitle('Kasino') self.setPalette(QPalette(Qt.darkGreen)) self.setup_music() self.statusbar = QStatusBar(self) self.statusbar.setStyleSheet('background: white') self.setStatusBar(self.statusbar) self.statusbar.showMessage('Welcome to the Cassino game!') self.menubar = QMenuBar(self) self.optionsMenu = self.menubar.addMenu('Options') self.music_toggle = QAction() self.music_toggle.setText('Music') self.music_toggle.setShortcut('Ctrl+m') self.music_toggle.setCheckable(True) self.music_toggle.setChecked(True) self.optionsMenu.addAction(self.music_toggle) self.music_toggle.triggered.connect(self.toggle_music) self.speedGroup = QActionGroup(self) self.speedGroup.triggered.connect(self.set_speed) self.slow_speed = QAction('Slow', self.speedGroup) self.slow_speed.setCheckable(True) self.normal_speed = QAction('Normal', self.speedGroup) self.normal_speed.setCheckable(True) self.fast_speed = QAction('Fast', self.speedGroup) self.fast_speed.setCheckable(True) self.vfast_speed = QAction('Very Fast', self.speedGroup) self.vfast_speed.setCheckable(True) self.normal_speed.setChecked(True) self.speed_menu = self.optionsMenu.addMenu('Speed') self.speed_menu.addActions(self.speedGroup.actions()) self.menubar.setMouseTracking(False) self.setMenuBar(self.menubar) self.play_widget = PlayWidget(self) self.main_menu = MainMenu(self) self.start_menu = StartMenu(self) self.widgets = QStackedWidget(self) self.widgets.addWidget(self.play_widget) self.widgets.addWidget(self.main_menu) self.widgets.addWidget(self.start_menu) self.widgets.setCurrentWidget(self.main_menu) self.setCentralWidget(self.widgets) self.setGeometry(25, 50, 1028, 720) self.main_menu.startbutton.clicked.connect(self.init_game) self.main_menu.loadbutton.clicked.connect(self.load_game) self.main_menu.quitbutton.clicked.connect(self.quit) self.play_widget.quit_button.clicked.connect(self.quit_to_menu) self.play_widget.save_button.clicked.connect(self.save_game) self.start_menu.startbutton.clicked.connect(self.start_game) def setup_music(self): self.music = QMediaPlayer() self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(QMediaPlaylist.Loop) file_name = "sound/bg.mp3" self.media = QMediaContent(QUrl.fromLocalFile(file_name)) self.playlist.addMedia(self.media) self.music.setPlaylist(self.playlist) self.music.setVolume(20) self.music.play() def toggle_music(self): if self.music.isMuted(): self.music.setMuted(False) self.statusbar.showMessage('Music on', 5000) else: self.music.setMuted(True) self.statusbar.showMessage('Music off', 5000) def set_speed(self, action): if action == self.slow_speed: self.play_widget.speed = 1 elif action == self.normal_speed: self.play_widget.speed = 3 elif action == self.fast_speed: self.play_widget.speed = 4 else: self.play_widget.speed = 6 def start_game(self): self.play_widget.init_game( self.start_menu.extract_info_and_init_game()) self.widgets.setCurrentWidget(self.play_widget) self.statusbar.showMessage('Game launched', 2000) def load_game(self): path = QFileDialog.getOpenFileName(self, 'Open save file', QDir.currentPath() + '/sav')[0] if path != '': game, msg, count = load(path) self.play_widget.resume_from_save(game, msg, count) self.widgets.setCurrentWidget(self.play_widget) self.statusbar.showMessage('Loaded save file', 5000) def save_game(self): path = QFileDialog.getSaveFileName(self, 'Create save file', QDir.currentPath() + '/sav')[0] if path != '': save(path, self.play_widget.game, self.play_widget.export_log(), self.play_widget.move_count) self.statusbar.showMessage('Game saved', 5000) def init_game(self): self.widgets.setCurrentWidget(self.start_menu) self.statusbar.showMessage('Starting new game') def quit_to_menu(self): #Reset playwidget self.widgets.removeWidget(self.play_widget) speed = self.play_widget.speed self.play_widget.setParent(None) self.play_widget = PlayWidget(self) self.play_widget.speed = speed self.widgets.addWidget(self.play_widget) self.play_widget.quit_button.clicked.connect(self.quit_to_menu) self.play_widget.save_button.clicked.connect(self.save_game) self.widgets.setCurrentWidget(self.main_menu) def closeEvent(self, *args, **kwargs): #for handling closing from 'x' button self.quit() def quit(self): print('Exited game. Thanks for playing!\n') self.app.exit()
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 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 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 QgsFmvPlayer(QMainWindow, Ui_PlayerWindow): """ Video Player Class """ def __init__(self, iface, path=None, parent=None): """ Constructor """ super(QgsFmvPlayer, self).__init__(parent) self.setupUi(self) self.parent = parent self.iface = iface self.fileName = None self.metadataDlg = None self.createingMosaic = False self.currentInfo = 0.0 self.RecGIF = QMovie(":/imgFMV/images/record.gif") self.videoWidget.customContextMenuRequested[QPoint].connect( self.contextMenuRequested) self.duration = 0 self.playerMuted = False self.HasFileAudio = False self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.player.setNotifyInterval(1000) # One second self.pass_time = 0.1 self.playlist = QMediaPlaylist() # self.player.setVideoOutput( # self.videoWidget) # Standar Surface self.player.setVideoOutput( self.videoWidget.videoSurface()) # Custom Surface self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.stateChanged.connect(self.setCurrentState) self.playerState = QMediaPlayer.StoppedState self.playFile(path) self.sliderDuration.setRange(0, self.player.duration() / 1000) self.volumeSlider.setValue(self.player.volume()) self.volumeSlider.enterEvent = self.showVolumeTip if self.metadataDlg is None: self.metadataDlg = QgsFmvMetadata(parent=self, player=self) self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg) self.metadataDlg.setMinimumWidth(500) self.metadataDlg.hide() def HasMetadata(self, videoPath): """ Check if video have Metadata or not """ try: p = _spawn([ '-i', videoPath, '-map', 'data-re', '-codec', 'copy', '-f', 'data', '-' ]) stdout_data, _ = p.communicate() if stdout_data == b'': qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", "This video don't have Metadata ! : "), level=QGis.Info) return False return True except Exception as e: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", "Metadata Callback Failed! : "), str(e), level=QGis.Info) def HasAudio(self, videoPath): """ Check if video have Metadata or not """ try: p = _spawn([ '-i', videoPath, '-show_streams', '-select_streams', 'a', '-loglevel', 'error' ], type="ffprobe") stdout_data, _ = p.communicate() if stdout_data == b'': qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", "This video don't have Audio ! : "), level=QGis.Info) return False return True except Exception as e: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", "Audio check Failed! : "), str(e), level=QGis.Info) def callBackMetadata(self, currentTime, nextTime): """ Metadata CallBack """ try: # TODO : Speed this function # stdout_data = _check_output(['-i', self.fileName, # '-ss', currentTime, # '-to', nextTime, # '-f', 'data', '-']) t = callBackMetadataThread(cmds=[ '-i', self.fileName, '-ss', currentTime, '-to', nextTime, '-map', 'data-re', '-f', 'data', '-' ]) t.start() t.join(1) if t.is_alive(): t.p.terminate() t.join() if t.stdout == b'': return for packet in StreamParser(t.stdout): try: self.addMetadata(packet.MetadataList()) UpdateLayers(packet, parent=self, mosaic=self.createingMosaic) self.iface.mapCanvas().refresh() QApplication.processEvents() return except Exception as e: None except Exception as e: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", "Metadata Callback Failed! : "), str(e), level=QGis.Info) def addMetadata(self, packet): ''' Add Metadata to List ''' self.clearMetadata() row = 0 for key in sorted(packet.keys()): self.metadataDlg.VManager.insertRow(row) self.metadataDlg.VManager.setItem(row, 0, QTableWidgetItem(str(key))) self.metadataDlg.VManager.setItem( row, 1, QTableWidgetItem(str(packet[key][0]))) self.metadataDlg.VManager.setItem( row, 2, QTableWidgetItem(str(packet[key][1]))) row += 1 self.metadataDlg.VManager.setVisible(False) self.metadataDlg.VManager.resizeColumnsToContents() self.metadataDlg.VManager.setVisible(True) self.metadataDlg.VManager.verticalScrollBar().setSliderPosition( self.sliderPosition) def clearMetadata(self): ''' Clear Metadata List ''' try: self.sliderPosition = self.metadataDlg.VManager.verticalScrollBar( ).sliderPosition() self.metadataDlg.VManager.setRowCount(0) except: None def saveInfoToJson(self): """ Save video Info to json """ if not self.KillAllProcessors(): return out_json, _ = QFileDialog.getSaveFileName(self, "Save File", "", "Json Files (*.json)") if out_json == "": return try: self.VPProbeToJson = Converter() self.VPTProbeToJson = QThread() self.VPProbeToJson.moveToThread(self.VPTProbeToJson) self.VPProbeToJson.finished.connect(self.QThreadFinished) self.VPProbeToJson.error.connect(self.QThreadError) self.VPProbeToJson.progress.connect( self.progressBarProcessor.setValue) self.VPTProbeToJson.start(QThread.LowPriority) QMetaObject.invokeMethod(self.VPProbeToJson, 'probeToJson', Qt.QueuedConnection, Q_ARG(str, self.fileName), Q_ARG(str, out_json)) except Exception as e: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Error saving Json")) self.QThreadFinished("probeToJson", "Closing ProbeToJson") def showVideoInfo(self): ''' Show default probe info ''' try: self.VPProbe = Converter() self.VPTProbe = QThread() self.VPProbe.moveToThread(self.VPTProbe) self.VPProbe.finishedJson.connect(self.QThreadFinished) self.VPProbe.error.connect(self.QThreadError) self.VPProbe.progress.connect(self.progressBarProcessor.setValue) self.VPTProbe.start(QThread.LowPriority) QMetaObject.invokeMethod(self.VPProbe, 'probeShow', Qt.QueuedConnection, Q_ARG(str, self.fileName)) except Exception as e: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Error Info Show")) self.QThreadFinished("probeShow", "Closing Probe") return def state(self): ''' Return Current State ''' return self.playerState def setCurrentState(self, state): ''' Set Current State ''' if state != self.playerState: self.playerState = state if state == QMediaPlayer.StoppedState: self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png")) return def showColorDialog(self): ''' Show Color dialog ''' self.ColorDialog = ColorDialog(parent=self) self.ColorDialog.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint) # Fail if not uncheked self.actionMagnifying_glass.setChecked(False) self.actionZoom_Rectangle.setChecked(False) self.ColorDialog.exec_() return def createMosaic(self, value): ''' Function for create Video Mosaic ''' home = os.path.expanduser("~") qgsu.createFolderByName(home, "QGIS_FMV") homefmv = os.path.join(home, "QGIS_FMV") root, ext = os.path.splitext(os.path.basename(self.fileName)) qgsu.createFolderByName(homefmv, root) self.createingMosaic = value # Create Group CreateGroupByName() return def contextMenuRequested(self, point): ''' Context Menu Video ''' menu = QMenu() # actionColors = menu.addAction( # QCoreApplication.translate("QgsFmvPlayer", "Color Options")) # actionColors.setShortcut("Ctrl+May+C") # actionColors.triggered.connect(self.showColorDialog) actionMute = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Mute/Unmute")) actionMute.setShortcut("Ctrl+May+U") actionMute.triggered.connect(self.setMuted) menu.addSeparator() actionAllFrames = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Extract All Frames")) actionAllFrames.setShortcut("Ctrl+May+A") actionAllFrames.triggered.connect(self.ExtractAllFrames) actionCurrentFrames = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Extract Current Frame")) actionCurrentFrames.setShortcut("Ctrl+May+Q") actionCurrentFrames.triggered.connect(self.ExtractCurrentFrame) menu.addSeparator() actionShowMetadata = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Show Metadata")) actionShowMetadata.setShortcut("Ctrl+May+M") actionShowMetadata.triggered.connect(self.OpenQgsFmvMetadata) menu.exec_(self.mapToGlobal(point)) # Start Snnipet FILTERS def grayFilter(self, value): self.UncheckFilters(self.sender(), value) self.videoWidget.SetGray(value) self.videoWidget.UpdateSurface() return def edgeFilter(self, value): self.UncheckFilters(self.sender(), value) self.videoWidget.SetEdgeDetection(value) self.videoWidget.UpdateSurface() return def invertColorFilter(self, value): self.UncheckFilters(self.sender(), value) self.videoWidget.SetInvertColor(value) self.videoWidget.UpdateSurface() return def autoContrastFilter(self, value): self.UncheckFilters(self.sender(), value) self.videoWidget.SetAutoContrastFilter(value) self.videoWidget.UpdateSurface() return def monoFilter(self, value): self.UncheckFilters(self.sender(), value) self.videoWidget.SetMonoFilter(value) self.videoWidget.UpdateSurface() return def magnifier(self, value): self.UncheckUtils(self.sender(), value) self.videoWidget.SetMagnifier(value) self.videoWidget.UpdateSurface() return def zoomRect(self, value): self.UncheckUtils(self.sender(), value) self.videoWidget.SetZoomRect(value) self.videoWidget.UpdateSurface() return def UncheckUtils(self, sender, value): # p = self.player.position() # self.player.setVideoOutput( # self.videoWidget.videoSurface()) # Custom surface # self.player.setPosition(p) QApplication.processEvents() name = sender.objectName() self.actionMagnifying_glass.setChecked( True if name == "actionMagnifying_glass" else False) self.actionZoom_Rectangle.setChecked(True if name == "actionZoom_Rectangle" else False) sender.setChecked(value) return def UncheckFilters(self, sender, value): # p = self.player.position() # self.player.setVideoOutput( # self.videoWidget.videoSurface()) # Custom surface # self.player.setPosition(p) # QApplication.processEvents() name = sender.objectName() self.actionGray.setChecked(True if name == "actionGray" else False) self.actionInvert_Color.setChecked(True if name == "actionInvert_Color" else False) self.actionMono_Filter.setChecked(True if name == "actionMono_Filter" else False) self.actionCanny_edge_detection.setChecked( True if name == "actionCanny_edge_detection" else False) self.actionAuto_Contrast_Filter.setChecked( True if name == "actionAuto_Contrast_Filter" else False) self.videoWidget.SetGray(True if name == "actionGray" else False) self.videoWidget.SetEdgeDetection( True if name == "actionCanny_edge_detection" else False) self.videoWidget.SetInvertColor(True if name == "actionInvert_Color" else False) self.videoWidget.SetMonoFilter(True if name == "actionMono_Filter" else False) self.videoWidget.SetAutoContrastFilter( True if name == "actionAuto_Contrast_Filter" else False) sender.setChecked(value) return # End Snnipet FILTERS def isMuted(self): ''' Is muted video property''' return self.playerMuted def setMuted(self): ''' Muted video ''' if self.player.isMuted(): self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png")) self.player.setMuted(False) self.volumeSlider.setEnabled(True) else: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png")) self.player.setMuted(True) self.volumeSlider.setEnabled(False) return def stop(self): ''' Stop video''' self.player.stop() self.videoWidget.update() return def volume(self): ''' Volume Slider ''' return self.volumeSlider.value() def setVolume(self, volume): ''' Tooltip and set value''' self.player.setVolume(volume) self.showVolumeTip(volume) if 0 < volume <= 30: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_30.png")) elif 30 < volume <= 60: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_60.png")) elif 60 < volume <= 100: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png")) elif volume == 0: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png")) def EndMedia(self): ''' Button end video position ''' if self.player.isVideoAvailable(): self.player.setPosition(self.player.duration()) self.videoWidget.update() return def StartMedia(self): ''' Button start video position ''' if self.player.isVideoAvailable(): self.player.setPosition(0) self.videoWidget.update() return def forwardMedia(self): ''' Button forward Video ''' forwardTime = int(self.player.position()) + 10 * 1000 if forwardTime > int(self.player.duration()): forwardTime = int(self.player.duration()) self.player.setPosition(forwardTime) def rewindMedia(self): ''' Button rewind Video ''' rewindTime = int(self.player.position()) - 10 * 1000 if rewindTime < 0: rewindTime = 0 self.player.setPosition(rewindTime) def AutoRepeat(self, checked): ''' Button AutoRepeat Video ''' if checked: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) else: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) return def showVolumeTip(self, _): ''' Volume Slider Tooltip Trick ''' self.style = self.volumeSlider.style() self.opt = QStyleOptionSlider() self.volumeSlider.initStyleOption(self.opt) rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt, self.style.SC_SliderHandle) self.tip_offset = QPoint(5, 15) pos_local = rectHandle.topLeft() + self.tip_offset pos_global = self.volumeSlider.mapToGlobal(pos_local) QToolTip.showText(pos_global, str(self.volumeSlider.value()) + " %", self) def showMoveTip(self, currentInfo): ''' Player Silder Move Tooptip Trick ''' self.style = self.sliderDuration.style() self.opt = QStyleOptionSlider() self.sliderDuration.initStyleOption(self.opt) rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt, self.style.SC_SliderHandle) self.tip_offset = QPoint(5, 15) pos_local = rectHandle.topLeft() + self.tip_offset pos_global = self.sliderDuration.mapToGlobal(pos_local) tStr = _seconds_to_time(currentInfo) QToolTip.showText(pos_global, tStr, self) def durationChanged(self, duration): ''' Duration video change signal ''' duration /= 1000 self.duration = duration self.sliderDuration.setMaximum(duration) def positionChanged(self, progress): ''' Current Video position change ''' progress /= 1000 if not self.sliderDuration.isSliderDown(): self.sliderDuration.setValue(progress) self.updateDurationInfo(progress) def updateDurationInfo(self, currentInfo): ''' Update labels duration Info and CallBack Metadata ''' duration = self.duration self.currentInfo = currentInfo if currentInfo or duration: totalTime = _seconds_to_time(duration) currentTime = _seconds_to_time(currentInfo) tStr = currentTime + " / " + totalTime nextTime = currentInfo + self.pass_time currentTimeInfo = _seconds_to_time_frac(currentInfo) nextTimeInfo = _seconds_to_time_frac(nextTime) # Metadata CallBack self.callBackMetadata(currentTimeInfo, nextTimeInfo) else: tStr = "" self.labelDuration.setText(tStr) def handleCursor(self, status): ''' Change cursor ''' if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia): self.setCursor(Qt.BusyCursor) else: self.unsetCursor() def statusChanged(self, status): ''' Signal Status video change ''' self.handleCursor(status) if status == QMediaPlayer.LoadingMedia: self.videoAvailableChanged(False) elif status == QMediaPlayer.StalledMedia: self.videoAvailableChanged(False) if status == QMediaPlayer.EndOfMedia: self.videoAvailableChanged(True) elif status == QMediaPlayer.InvalidMedia: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", self.player.errorString()), level=QGis.Warning) self.videoAvailableChanged(False) else: self.videoAvailableChanged(True) def playFile(self, videoPath): ''' Play file from path ''' try: RemoveVideoLayers() RemoveGroupByName() self.fileName = videoPath self.playlist = QMediaPlaylist() url = QUrl.fromLocalFile(videoPath) self.playlist.addMedia(QMediaContent(url)) self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.player.setPlaylist(self.playlist) self.setWindowTitle("Playing : " + os.path.basename(os.path.normpath(videoPath))) if self.HasMetadata(videoPath): CreateVideoLayers() self.clearMetadata() self.lb_cursor_coord.setText( "<span style='font-size:10pt; font-weight:bold;'>Lon :</span>" + "<span style='font-size:9pt; font-weight:normal;'>Null</span>" + "<span style='font-size:10pt; font-weight:bold;'> Lat :</span>" + "<span style='font-size:9pt; font-weight:normal;'>Null</span>" ) else: self.btn_GeoReferencing.setEnabled(False) self.HasFileAudio = True if not self.HasAudio(videoPath): self.actionAudio.setEnabled(False) self.actionSave_Audio.setEnabled(False) self.HasFileAudio = False self.playClicked(True) except Exception as e: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", 'Open Video File : '), str(e), level=QGis.Warning) def ReciconUpdate(self, frame): self.btn_Rec.setIcon(QIcon(self.RecGIF.currentPixmap())) def RecordVideo(self, value): ''' Cut Video ''' currentTime = _seconds_to_time(self.currentInfo) if value is False: self.endRecord = currentTime _, file_extension = os.path.splitext(self.fileName) out, _ = QFileDialog.getSaveFileName(self, "Save As", "", file_extension) if not out: self.RecGIF.frameChanged.disconnect(self.ReciconUpdate) self.RecGIF.stop() self.btn_Rec.setIcon(QIcon(":/imgFMV/images/record.png")) return False lfn = out.lower() if not lfn.endswith((file_extension)): out += file_extension p = _spawn([ '-i', self.fileName, '-ss', self.startRecord, '-to', self.endRecord, '-c', 'copy', out ]) p.communicate() qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Save file succesfully!")) self.RecGIF.frameChanged.disconnect(self.ReciconUpdate) self.RecGIF.stop() self.btn_Rec.setIcon(QIcon(":/imgFMV/images/record.png")) else: self.startRecord = currentTime self.RecGIF.frameChanged.connect(self.ReciconUpdate) self.RecGIF.start() return def videoAvailableChanged(self, available): ''' Buttons for video available ''' # self.btn_Color.setEnabled(available) self.btn_CaptureFrame.setEnabled(available) self.gb_PlayerControls.setEnabled(available) return def toggleGroup(self, state): ''' Toggle GroupBox ''' sender = self.sender() if state: sender.setFixedHeight(sender.sizeHint().height()) else: sender.setFixedHeight(15) def playClicked(self, state): ''' Stop and Play video ''' if self.playerState in (QMediaPlayer.StoppedState, QMediaPlayer.PausedState): self.btn_play.setIcon(QIcon(":/imgFMV/images/pause.png")) self.player.play() elif self.playerState == QMediaPlayer.PlayingState: self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png")) self.player.pause() def seek(self, seconds): '''Slider Move''' self.player.setPosition(seconds * 1000) self.showMoveTip(seconds) def convertVideo(self): '''Convert Video To Other Format ''' if not self.KillAllProcessors(): return sel = "mp4 Files (*.mp4)" out, _ = QFileDialog.getSaveFileName( self, "Save Video as...", None, "ogg files (*.ogg);;avi Files (*.avi);;mkv Files (*.mkv);;webm Files (*.webm);;flv Files (*.flv);;mov Files (*.mov);;mp4 Files (*.mp4);;mpg Files (*.mpg);;mp3 Files (*.mp3)", sel) if not out: return False lfn = out.lower() if not lfn.endswith(('.ogg', '.avi', '.mkv', '.webm', '.flv', '.mov', '.mp4', '.mp3', '.mpg')): # The default. out += '.mp4' try: self.VPConverter = Converter() self.VPTConverter = QThread() self.VPConverter.moveToThread(self.VPTConverter) self.VPConverter.finished.connect(self.QThreadFinished) self.VPConverter.error.connect(self.QThreadError) self.VPConverter.progress.connect( self.progressBarProcessor.setValue) self.VPTConverter.start(QThread.LowPriority) # TODO : Make Correct format Conversion and embebed metadata info = self.VPConverter.probeInfo(self.fileName) if info is not None: if self.HasFileAudio: audio_codec = info.audio.codec audio_samplerate = info.audio.audio_samplerate audio_channels = info.audio.audio_channels video_codec = info.video.codec video_width = info.video.video_width video_height = info.video.video_height video_fps = info.video.video_fps _, out_ext = os.path.splitext(out) if self.HasFileAudio: options = { 'format': out_ext[1:], 'audio': { 'codec': audio_codec, 'samplerate': audio_samplerate, 'channels': audio_channels }, 'video': { 'codec': video_codec, 'width': video_width, 'height': video_height, 'fps': video_fps } } else: options = { 'format': out_ext[1:], 'video': { 'codec': video_codec, 'width': video_width, 'height': video_height, 'fps': video_fps } } QMetaObject.invokeMethod(self.VPConverter, 'convert', Qt.QueuedConnection, Q_ARG(str, self.fileName), Q_ARG(str, out), Q_ARG(dict, options), Q_ARG(bool, False)) except Exception as e: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Error converting video ")) self.QThreadFinished("convert", "Closing convert") def ShowPlot(self, bitrate_data, frame_count, output=None): ''' Show plot,because show not work using threading ''' matplot.figure().canvas.set_window_title(self.fileName) matplot.title("Stream Bitrate vs Time") matplot.xlabel("Time (sec)") matplot.ylabel("Frame Bitrate (kbit/s)") matplot.grid(True) # map frame type to color frame_type_color = { # audio 'A': 'yellow', # video 'I': 'red', 'P': 'green', 'B': 'blue' } global_peak_bitrate = 0.0 global_mean_bitrate = 0.0 # render charts in order of expected decreasing size for frame_type in ['I', 'P', 'B', 'A']: # skip frame type if missing if frame_type not in bitrate_data: continue # convert list of tuples to numpy 2d array frame_list = bitrate_data[frame_type] frame_array = numpy.array(frame_list) # update global peak bitrate peak_bitrate = frame_array.max(0)[1] if peak_bitrate > global_peak_bitrate: global_peak_bitrate = peak_bitrate # update global mean bitrate (using piecewise mean) mean_bitrate = frame_array.mean(0)[1] global_mean_bitrate += mean_bitrate * \ (len(frame_list) / frame_count) # plot chart using gnuplot-like impulses matplot.vlines(frame_array[:, 0], [0], frame_array[:, 1], color=frame_type_color[frame_type], label="{} Frames".format(frame_type)) self.progressBarProcessor.setValue(90) # calculate peak line position (left 15%, above line) peak_text_x = matplot.xlim()[1] * 0.15 peak_text_y = global_peak_bitrate + \ ((matplot.ylim()[1] - matplot.ylim()[0]) * 0.015) peak_text = "peak ({:.0f})".format(global_peak_bitrate) # draw peak as think black line w/ text matplot.axhline(global_peak_bitrate, linewidth=2, color='black') matplot.text(peak_text_x, peak_text_y, peak_text, horizontalalignment='center', fontweight='bold', color='black') # calculate mean line position (right 85%, above line) mean_text_x = matplot.xlim()[1] * 0.85 mean_text_y = global_mean_bitrate + \ ((matplot.ylim()[1] - matplot.ylim()[0]) * 0.015) mean_text = "mean ({:.0f})".format(global_mean_bitrate) # draw mean as think black line w/ text matplot.axhline(global_mean_bitrate, linewidth=2, color='black') matplot.text(mean_text_x, mean_text_y, mean_text, horizontalalignment='center', fontweight='bold', color='black') matplot.legend() if output != "": matplot.savefig(output) else: matplot.show() self.progressBarProcessor.setValue(100) def CreateBitratePlot(self): ''' Create video Plot Bitrate Thread ''' if not self.KillAllProcessors(): return try: self.VPBitratePlot = CreatePlotsBitrate() self.VPTBitratePlot = QThread() self.VPBitratePlot.moveToThread(self.VPTBitratePlot) self.VPBitratePlot.finished.connect(self.QThreadFinished) self.VPBitratePlot.return_fig.connect(self.ShowPlot) self.VPBitratePlot.error.connect(self.QThreadError) self.VPBitratePlot.progress.connect( self.progressBarProcessor.setValue) self.VPTBitratePlot.start(QThread.LowPriority) sender = self.sender().objectName() if sender == "actionAudio": QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot', Qt.QueuedConnection, Q_ARG(str, self.fileName), Q_ARG(str, None), Q_ARG(str, 'audio')) elif sender == "actionVideo": QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot', Qt.QueuedConnection, Q_ARG(str, self.fileName), Q_ARG(str, None), Q_ARG(str, 'video')) elif sender == "actionSave_Audio": selfilter = "Portable Network Graphics (*.png)" fileaudio, _ = QFileDialog.getSaveFileName( self, "Save Audio Bitrate Plot", "", "EPS Encapsulated Postscript (*.eps);;" "PGF code for LaTex (*.pgf);;" "Portable document format(*pdf);;" "Portable Network Graphics (*.png);;" "Postscript (*.ps);;" "Raw RGBA bitmap (*.raw*.rgba);;" "Scalable vector graphics (*.svg*.svgz)", selfilter) if fileaudio == "": return QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot', Qt.QueuedConnection, Q_ARG(str, self.fileName), Q_ARG(str, fileaudio), Q_ARG(str, 'audio')) elif sender == "actionSave_Video": selfilter = "Portable Network Graphics (*.png)" filevideo, _ = QFileDialog.getSaveFileName( self, "Save Video Bitrate Plot", "", "EPS Encapsulated Postscript (*.eps);;" "PGF code for LaTex (*.pgf);;" "Portable document format(*pdf);;" "Portable Network Graphics (*.png);;" "Postscript (*.ps);;" "Raw RGBA bitmap (*.raw*.rgba);;" "Scalable vector graphics (*.svg*.svgz)", selfilter) if filevideo == "": return QMetaObject.invokeMethod(self.VPBitratePlot, 'CreatePlot', Qt.QueuedConnection, Q_ARG(str, self.fileName), Q_ARG(str, filevideo), Q_ARG(str, 'video')) except Exception as e: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Failed creating Plot Bitrate")) def ExtractAllFrames(self): """ Extract All Video Frames Thread """ if not self.KillAllProcessors(): return options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly directory = QFileDialog.getExistingDirectory( self, QCoreApplication.translate("QgsFmvPlayer", "Save images"), '', options=options) if directory: self.VPExtractFrames = ExtractFramesProcessor() self.VPTExtractAllFrames = QThread() self.VPExtractFrames.moveToThread(self.VPTExtractAllFrames) self.VPExtractFrames.finished.connect(self.QThreadFinished) self.VPExtractFrames.error.connect(self.QThreadError) self.VPExtractFrames.progress.connect( self.progressBarProcessor.setValue) self.VPTExtractAllFrames.start(QThread.LowPriority) QMetaObject.invokeMethod(self.VPExtractFrames, 'ExtractFrames', Qt.QueuedConnection, Q_ARG(str, directory), Q_ARG(str, self.fileName)) return def ExtractCurrentFrame(self): """ Extract Current Frame Thread """ image = self.videoWidget.GetCurrentFrame() out_image, _ = QFileDialog.getSaveFileName( self, "Save Current Frame", "", "Image File (*.png *.jpg *.bmp *.tiff)") if out_image == "": return if out_image: t = threading.Thread(target=self.SaveCapture, args=( image, out_image, )) t.start() return def SaveCapture(self, image, output): ''' Save Current Image ''' image.save(output) QApplication.processEvents() return def QThreadFinished(self, process, msg, outjson=None): ''' Finish Threads ''' if process == "ExtractFramesProcessor": self.VPExtractFrames.deleteLater() self.VPTExtractAllFrames.terminate() self.VPTExtractAllFrames.deleteLater() elif process == "CreatePlotsBitrate": self.VPBitratePlot.deleteLater() self.VPTBitratePlot.terminate() self.VPTBitratePlot.deleteLater() elif process == "convert": self.VPConverter.deleteLater() self.VPTConverter.terminate() self.VPTConverter.deleteLater() elif process == "probeToJson": self.VPProbeToJson.deleteLater() self.VPTProbeToJson.terminate() self.VPTProbeToJson.deleteLater() elif process == "probeShow": self.VPProbe.deleteLater() self.VPTProbe.terminate() self.VPTProbe.deleteLater() self.showVideoInfoDialog(outjson) QApplication.processEvents() self.progressBarProcessor.setValue(0) return def QThreadError(self, processor, e, exception_string): """ Threads Errors""" qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", processor), 'Failed!\n'.format(exception_string), level=QGis.Warning) self.QThreadFinished(processor, "Closing Processor") return def OpenQgsFmvMetadata(self): """ Open Metadata Dock """ if self.metadataDlg is None: self.metadataDlg = QgsFmvMetadata(parent=self, player=self) self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg) self.metadataDlg.show() else: self.metadataDlg.show() return def KillAllProcessors(self): """Kill All Processors""" """ Extract all frames Processors """ try: if self.VPTExtractAllFrames.isRunning(): ret = qgsu.CustomMessage( QCoreApplication.translate( "QgsFmvPlayer", "HEY...Active background process!"), QCoreApplication.translate("QgsFmvPlayer", "Do you really want close?")) if ret == QMessageBox.Yes: self.QThreadFinished("ExtractFramesProcessor", "Closing Extract Frames Processor") else: return False except: None """ Bitrates Processors""" try: if self.VPTBitratePlot.isRunning(): ret = qgsu.CustomMessage( QCoreApplication.translate( "QgsFmvPlayer", "HEY...Active background process!"), QCoreApplication.translate("QgsFmvPlayer", "Do you really want close?")) if ret == QMessageBox.Yes: self.QThreadFinished("CreatePlotsBitrate", "Closing Plot Bitrate") else: return False except: None """ Converter Processors """ try: if self.VPTConverter.isRunning(): ret = qgsu.CustomMessage( QCoreApplication.translate( "QgsFmvPlayer", "HEY...Active background process!"), QCoreApplication.translate("QgsFmvPlayer", "Do you really want close?")) if ret == QMessageBox.Yes: self.QThreadFinished("convert", "Closing convert") else: return False except: None """ probeToJson Processors """ try: if self.VPTProbeToJson.isRunning(): ret = qgsu.CustomMessage( QCoreApplication.translate( "QgsFmvPlayer", "HEY...Active background process!"), QCoreApplication.translate("QgsFmvPlayer", "Do you really want close?")) if ret == QMessageBox.Yes: self.QThreadFinished("probeToJson", "Closing Info to Json") else: return False except: None """ probeShow Processors """ try: if self.VPTProbe.isRunning(): ret = qgsu.CustomMessage( QCoreApplication.translate( "QgsFmvPlayer", "HEY...Active background process!"), QCoreApplication.translate("QgsFmvPlayer", "Do you really want close?")) if ret == QMessageBox.Yes: self.QThreadFinished("probeShow", "Closing Show Video Info") else: return False except: None return True def showVideoInfoDialog(self, outjson): """ Show Video Information Dialog """ view = QTreeView() model = QJsonModel() view.setModel(model) model.loadJsonFromConsole(outjson) self.VideoInfoDialog = QDialog(self) self.VideoInfoDialog.setWindowTitle("Video Information : " + self.fileName) self.VideoInfoDialog.setWindowIcon( QIcon(":/imgFMV/images/video_information.png")) self.verticalLayout = QVBoxLayout(self.VideoInfoDialog) self.verticalLayout.addWidget(view) view.expandAll() view.header().setSectionResizeMode(QHeaderView.ResizeToContents) self.VideoInfoDialog.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint) self.VideoInfoDialog.setObjectName("VideoInfoDialog") self.VideoInfoDialog.resize(500, 400) self.VideoInfoDialog.show() def closeEvent(self, evt): """ Close Event """ if self.KillAllProcessors() is False: evt.ignore() return self.player.stop() self.parent._PlayerDlg = None self.parent.ToggleActiveFromTitle() RemoveVideoLayers() RemoveGroupByName() # Restore Filters State self.videoWidget.RestoreFilters() # QApplication.processEvents() del self.player
class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(1200, 720) Form.setMinimumSize(QtCore.QSize(200, 199)) Form.setStyleSheet("background-color:black;") self.isOnline = False self.isMini = False self.isOnTop = True self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form) self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setSpacing(0) self.verticalLayout_2.setObjectName("verticalLayout_2") self.mainFrame = QtWidgets.QFrame(Form) self.mainFrame.setMinimumSize(QtCore.QSize(200, 82)) self.mainFrame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.mainFrame.setFrameShadow(QtWidgets.QFrame.Raised) self.mainFrame.setObjectName("mainFrame") self.verticalLayout = QtWidgets.QVBoxLayout(self.mainFrame) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setSpacing(0) self.verticalLayout.setObjectName("verticalLayout") self.frame_3 = QtWidgets.QFrame(self.mainFrame) sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.frame_3.sizePolicy().hasHeightForWidth()) self.frame_3.setSizePolicy(sizePolicy) self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_3.setObjectName("frame_3") self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.frame_3) self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_6.setObjectName("horizontalLayout_6") self.Player_name = QtWidgets.QLabel(self.frame_3) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.Player_name.sizePolicy().hasHeightForWidth()) self.Player_name.setSizePolicy(sizePolicy) self.Player_name.setStyleSheet("QLabel\n" " {\n" " font: 12pt \"Helvetica\";\n" " color: white;\n" " border: 0px solid #076100;\n" " }") self.Player_name.setObjectName("status_label") self.horizontalLayout_6.addWidget(self.Player_name) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_6.addItem(spacerItem) self.minimize_button = QtWidgets.QPushButton(self.frame_3) self.minimize_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.minimize_button.setText("") icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("icon_sets/minimize.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.minimize_button.setIconSize(QSize(25, 17)) self.minimize_button.setMaximumSize(QSize(25, 17)) self.minimize_button.setIcon(icon) self.minimize_button.setIconSize(QtCore.QSize(27, 20)) # self.minimize_button.setFlat(True) self.minimize_button.setObjectName("minimize_button") self.horizontalLayout_6.addWidget(self.minimize_button) self.maximize_button = QtWidgets.QPushButton(self.frame_3) self.maximize_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.maximize_button.setText("") icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap("icon_sets/maximize.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.maximize_button.setIcon(icon1) self.maximize_button.setIconSize(QSize(25, 17)) self.maximize_button.setMaximumSize(QSize(25, 17)) self.maximize_button.setIconSize(QtCore.QSize(27, 20)) # self.maximize_button.setFlat(True) self.maximize_button.setObjectName("maximize_button") self.horizontalLayout_6.addWidget(self.maximize_button) self.cross_button = QtWidgets.QPushButton(self.frame_3) self.cross_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.cross_button.setText("") self.cross_button.setIconSize(QSize(25, 17)) self.cross_button.setMaximumSize(QSize(25, 17)) icon2 = QtGui.QIcon() icon2.addPixmap(QtGui.QPixmap("icon_sets/cross.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.cross_button.setIcon(icon2) self.cross_button.setIconSize(QtCore.QSize(27, 20)) # self.cross_button.setFlat(True) self.cross_button.setObjectName("cross_button") self.horizontalLayout_6.addWidget(self.cross_button) self.verticalLayout.addWidget(self.frame_3) self.video_playback = Videowidget(self.frame_3) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(200) sizePolicy.setHeightForWidth( self.video_playback.sizePolicy().hasHeightForWidth()) self.video_playback.setSizePolicy(sizePolicy) self.video_playback.setMinimumSize(QtCore.QSize(200, 100)) self.video_playback.setMouseTracking(False) self.video_playback.setTabletTracking(False) self.video_playback.setAcceptDrops(False) self.video_playback.setAutoFillBackground(False) self.video_playback.setObjectName("video_playback") self.video_playback.setStyleSheet("background-color:grey") self.verticalLayout.addWidget(self.video_playback) self.pos_frame = QtWidgets.QFrame(self.mainFrame) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(10) sizePolicy.setHeightForWidth( self.pos_frame.sizePolicy().hasHeightForWidth()) self.pos_frame.setSizePolicy(sizePolicy) self.pos_frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.pos_frame.setFrameShadow(QtWidgets.QFrame.Raised) self.pos_frame.setObjectName("pos_frame") self.horizontalLayout = QtWidgets.QHBoxLayout(self.pos_frame) self.horizontalLayout.setObjectName("horizontalLayout") self.position_slider = PosSlider(self.pos_frame) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(100) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.position_slider.sizePolicy().hasHeightForWidth()) self.position_slider.setSizePolicy(sizePolicy) self.position_slider.setMouseTracking(True) self.position_slider.setAutoFillBackground(False) self.position_slider.setStyleSheet( "QSlider::handle:horizontal \n" " {\n" " background: transparent;\n" " width: 8px;\n" " }\n" "QSlider::groove:horizontal {\n" " border: 1px solid white;\n" " height: 8px;\n" " background: qlineargradient(y1: 0, y2: 1,stop: 0 #2e3436, stop: 1.0 #000000);\n" "}\n" " QSlider::sub-page:horizontal {\n" " background:qlineargradient( y1: 0, y2: 1,\n" " stop: 0 #42a6db, stop: 1 #0074e0); \n" " border: 1px solid white;\n" " height: 8px;\n" "}\n" "QSlider::handle:horizontal:hover {\n" " background: black;\n" " height: 8px;\n" " width: 8px;\n" " border: 1px solid white;\n" " }\n" "") self.position_slider.setOrientation(QtCore.Qt.Horizontal) self.position_slider.setInvertedAppearance(False) self.position_slider.setInvertedControls(False) self.position_slider.setObjectName("position_slider") self.horizontalLayout.addWidget(self.position_slider) self.time_status = QtWidgets.QLabel(self.pos_frame) font = QtGui.QFont() font.setFamily("Arial Rounded MT Bold") font.setPointSize(8) font.setBold(False) font.setItalic(False) font.setWeight(50) self.time_status.setFont(font) self.time_status.setStyleSheet( "QLabel\n" " {\n" " \n" " font: 8pt \"Arial Rounded MT Bold\";\n" " color: white;\n" " border: 0px solid #076100;\n" "\n" " }") self.time_status.setObjectName("time_status") self.horizontalLayout.addWidget(self.time_status) self.backslash = QtWidgets.QLabel(self.pos_frame) font = QtGui.QFont() font.setFamily("Arial Rounded MT Bold") font.setPointSize(8) font.setBold(False) font.setItalic(False) font.setWeight(50) self.backslash.setFont(font) self.backslash.setStyleSheet( "QLabel\n" " {\n" " \n" " font: 8pt \"Arial Rounded MT Bold\";\n" " color: white;\n" " border: 0px solid #076100;\n" "\n" " }") self.backslash.setObjectName("backslash") self.horizontalLayout.addWidget(self.backslash) self.duration_status = QtWidgets.QLabel(self.pos_frame) font = QtGui.QFont() font.setFamily("Arial Rounded MT Bold") font.setPointSize(8) font.setBold(False) font.setItalic(False) font.setWeight(50) self.duration_status.setFont(font) self.duration_status.setStyleSheet( "QLabel\n" " {\n" " \n" " font: 8pt \"Arial Rounded MT Bold\";\n" " color: white;\n" " border: 0px solid #076100;\n" "\n" " }") self.duration_status.setObjectName("duration_status") self.horizontalLayout.addWidget(self.duration_status) self.verticalLayout.addWidget(self.pos_frame) self.frame_2 = QtWidgets.QFrame(self.mainFrame) sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(22) # sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth()) self.frame_2.setSizePolicy(sizePolicy) self.frame_2.setContentsMargins(0, 0, 0, 0) self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) self.frame_2.setObjectName("frame_2") self.frame_2.setStyleSheet("") self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame_2) self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.play_button = QtWidgets.QPushButton(self.frame_2) self.play_button.setEnabled(False) self.play_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.play_button.setStyleSheet( "QPushButton[play=true]{image:url(icon_sets/play/play.png);width:22px;height:22px}\n" "QPushButton[play=false]{image:url(icon_sets/pause/pause.png);width:22px;height:22px }\n" ) self.play_button.setProperty("play", True) self.play_button.setText("") self.play_button.setObjectName("play_button") self.horizontalLayout_4.addWidget(self.play_button) self.playback_button = QtWidgets.QPushButton(self.frame_2) self.playback_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.playback_button.setStyleSheet( "QPushButton{image:url(icon_sets/playback/playback.png);width:22px;height:22px }\n" ) self.playback_button.setText("") self.playback_button.setObjectName("playback_button") self.horizontalLayout_4.addWidget(self.playback_button) self.always_on_top_button = QtWidgets.QPushButton(self.frame_2) self.always_on_top_button.setCursor( QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.always_on_top_button.setStyleSheet( "QPushButton[top=false]{image : url(icon_sets/always_on_top/top_off.png) }\n" "QPushButton[top=true]{image : url(icon_sets/always_on_top/top_on.png) }\n" ) self.always_on_top_button.setProperty("top", True) self.always_on_top_button.setText("") self.always_on_top_button.setObjectName("always_on_top_button") self.horizontalLayout_4.addWidget(self.always_on_top_button) self.miniplayer_button = QtWidgets.QPushButton(self.frame_2) self.miniplayer_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.miniplayer_button.setStyleSheet( "QPushButton[mini=false]{image : url(icon_sets/standard_player/standard.png) }\n" # "QPushButton[mini=false]:hover{ image:url(icon_sets/standard_player/.png) }\n" "QPushButton[mini=true]{image : url(icon_sets/mini_player/mini.png) }\n" # "QPushButton[mini=true]:hover{ image:url(icon_sets/mini_player/.png) }\n" ) self.miniplayer_button.setProperty("mini", False) self.miniplayer_button.setContentsMargins(0, 0, 0, 0) self.miniplayer_button.setText("") self.miniplayer_button.setObjectName("miniplayer_button") self.horizontalLayout_4.addWidget(self.miniplayer_button) self.open_File_button = QtWidgets.QPushButton(self.frame_2) self.open_File_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.open_File_button.setStyleSheet( "QPushButton{image:url(icon_sets/new_file/new_file.png);width:22px;height:22px }\n" ) self.open_File_button.setText("") self.open_File_button.setObjectName("playback_button") self.horizontalLayout_4.addWidget(self.open_File_button) spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.horizontalLayout_4.addItem(spacerItem1) self.screenshot_button = QtWidgets.QPushButton(self.frame_2) self.screenshot_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.screenshot_button.setStyleSheet( "QPushButton{image : url(icon_sets/snapshot/snapshot.png);width:22px;height:22px} \n" ) self.screenshot_button.setText("") self.screenshot_button.setObjectName("screenshot_button") self.horizontalLayout_4.addWidget(self.screenshot_button) ''' Video Setting button for Video subs and dubs''' # self.video_setting_button = QtWidgets.QPushButton(self.frame_2) # self.video_setting_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) # self.video_setting_button.setText("") # self.video_setting_button.setIconSize(QtCore.QSize(22, 22)) # self.video_setting_button.setStyleSheet("QPushButton{image : url(icon_sets/video_setting/video_settings.png) }\n" # ) # self.video_setting_button.setObjectName("video_setting_button") # self.horizontalLayout_4.addWidget(self.video_setting_button) self.setting_button = QtWidgets.QPushButton(self.frame_2) self.setting_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.setting_button.setStyleSheet( "QPushButton{image : url(icon_sets/settings/settings.png) }\n") self.setting_button.setText("") self.setting_button.setObjectName("setting_button") self.horizontalLayout_4.addWidget(self.setting_button) self.Quality_box = QtWidgets.QComboBox(self.frame_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.Quality_box.sizePolicy().hasHeightForWidth()) self.Quality_box.setSizePolicy(sizePolicy) self.Quality_box.setStyleSheet( "QComboBox\n" " {\n" " border-image :url(icon_sets/quality/border.png);\n" " color: #fcffff;\n" " font-size: 8pt;\n" " font-weight: bold;\n" # " width: 41px;\n" " background-color: #000000;\n" " }\n" " QComboBox QAbstractItemView \n" " {\n" " background: #fcffff;\n" " border: 2px solid darkgray;\n" " selection-background-color: #000000;\n" " }\n" "QComboBox::drop-down {\n" " border: 0px;\n" " subcontrol-origin: padding;\n" " subcontrol-position: top right;\n" "\n" " border-top-right-radius: 3px;\n" " border-bottom-right-radius: 3px;\n" "}\n") self.Quality_box.setIconSize(QtCore.QSize(0, 0)) self.Quality_box.setDuplicatesEnabled(False) self.Quality_box.setObjectName("comboBox") self.Quality_box.addItem(" -") self.horizontalLayout_4.addWidget(self.Quality_box) self.volume_button = QtWidgets.QPushButton(self.frame_2) self.volume_button.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.volume_button.setText("") icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.volume_button.setIcon(icon9) self.volume_button.setIconSize(QtCore.QSize(22, 22)) self.volume_button.setCheckable(True) # self.volume_button.setFlat(True) self.volume_button.setObjectName("volume_button") self.horizontalLayout_4.addWidget(self.volume_button) self.volumeslider = VolSlider(self.frame_2) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.volumeslider.sizePolicy().hasHeightForWidth()) self.volumeslider.setSizePolicy(sizePolicy) self.volumeslider.setAutoFillBackground(False) self.volumeslider.setStyleSheet( "QSlider::handle:horizontal \n" " {\n" " background: transparent;\n" " width: 5px;\n" " }\n" "QSlider::groove:horizontal {\n" " border: 1px solid #444444;\n" " height: 5px;\n" " background: qlineargradient(y1: 0, y2: 1,stop: 0 grey, stop: 1.0 grey);\n" "}\n" " QSlider::sub-page:horizontal {\n" " background:qlineargradient( y1: 0, y2: 1,\n" " stop: 0 #42a6db, stop: 1 #0074e0); \n" " border: 1px solid #777;\n" " height: 5px;\n" "}\n" "QSlider::handle:horizontal:hover {\n" " background: black;\n" " height: 5px;\n" " width: 5px;\n" " border: 1px solid #0074e0;\n" " }\n" "QSlider::sub-page:horizontal:disabled{background:qlineargradient( y1: 0, y2: 1,\n" " stop: 0 #909090, stop: 1 #A8A8A8 );}\n" "") self.volumeslider.setOrientation(QtCore.Qt.Horizontal) self.volumeslider.setObjectName("volume_slider") self.horizontalLayout_4.addWidget(self.volumeslider) self.volume_percentage = QtWidgets.QLabel(self.frame_2) self.volume_percentage.setStyleSheet( "QLabel\n" " {\n" " font: 7pt \"Arial Rounded MT Bold\";\n" " color: white;\n" " border: 0px solid #076100;\n" " }") self.volume_percentage.setObjectName("volume_status") self.volume_percentage.setMinimumWidth(35) self.volume_percentage.setText(" 75 %") self.horizontalLayout_4.addWidget(self.volume_percentage) self.verticalLayout.addWidget(self.frame_2) self.frame = QtWidgets.QFrame(self.mainFrame) font = QtGui.QFont() font.setFamily("Lucida Console") self.frame.setFont(font) self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.frame.setObjectName("frame") self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.frame) self.horizontalLayout_5.setObjectName("horizontalLayout_5") sizegrip_2 = QtWidgets.QSizeGrip(Form) sizegrip_2.setStyleSheet("image:url(icon_sets/.png)") self.horizontalLayout_5.addWidget( sizegrip_2, 0, QtCore.Qt.AlignBottom | QtCore.Qt.AlignLeft) # self.enter_url_label = QtWidgets.QLabel(self.frame) # font = QtGui.QFont() # font.setFamily("Arial Rounded MT Bold") # font.setPointSize(8) # font.setBold(False) # font.setItalic(False) # font.setWeight(50) # self.enter_url_label.setFont(font) # self.enter_url_label.setStyleSheet("QLabel\n" # " {\n" # " \n" # " font: 8pt \"Arial Rounded MT Bold\";\n" # " color: white;\n" # " border: 0px solid #076100;\n" # " }") # self.enter_url_label.setObjectName("enter_url_label") # self.horizontalLayout_5.addWidget(self.enter_url_label) self.url_box = QtWidgets.QComboBox(self.frame) sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(200) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.url_box.sizePolicy().hasHeightForWidth()) self.url_box.setSizePolicy(sizePolicy) self.url_box.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) self.url_box.setMouseTracking(False) self.url_box.setAcceptDrops(False) self.url_box.setWhatsThis("") self.url_box.setAccessibleDescription("") self.url_box.setAutoFillBackground(True) self.url_box.setStyleSheet("QComboBox\n" " {\n" " border: 2px solid #0074e0;\n" " color: #fcffff;\n" " font-size: 8pt;\n" " font-weight: bold;\n" " background-color: #000000;\n" " border-radius: 6px;\n" " }\n" " QComboBox QAbstractItemView \n" " {\n" " background: #fcffff;\n" " border: 2px solid darkgray;\n" " selection-background-color: #000000;\n" " }\n" "QComboBox::down-arrow {\n" " image: url(icon_sets/url/url4.png)\n" "}\n" "QComboBox::drop-down {\n" " subcontrol-origin: padding;\n" " subcontrol-position: top right;\n" " width: 20px;\n" " \n" " border-top-right-radius: 3px;\n" " border-bottom-right-radius: 3px;\n" "}") self.url_box.setInputMethodHints(QtCore.Qt.ImhUrlCharactersOnly) self.url_box.setEditable(True) self.url_box.setCurrentText("") self.url_box.setMaxVisibleItems(100) self.url_box.setMaxCount(100) self.url_box.setInsertPolicy(QtWidgets.QComboBox.InsertAtCurrent) self.url_box.setSizeAdjustPolicy( QtWidgets.QComboBox.AdjustToContentsOnFirstShow) self.url_box.setMinimumContentsLength(2) self.url_box.setIconSize(QtCore.QSize(20, 20)) self.url_box.setDuplicatesEnabled(False) self.url_box.setFrame(True) self.url_box.setObjectName("url_box") self.horizontalLayout_5.addWidget(self.url_box) self.verticalLayout.addWidget(self.frame) sizegrip_1 = QtWidgets.QSizeGrip(Form) sizegrip_1.setStyleSheet( "image:url(icon_sets/size.png);width:15; height:18;") self.horizontalLayout_5.addWidget( sizegrip_1, 0, QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight) self.verticalLayout_2.addWidget(self.mainFrame) self.retranslateUi(Form) self.url_box.setCurrentIndex(-1) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Q-Stream Player")) self.Player_name.setText(_translate("Form", "Q-Stream Player")) self.time_status.setText(_translate("Form", "00:00:00")) self.backslash.setText(_translate("Form", "/")) self.duration_status.setText(_translate("Form", "00:00:00")) # self.enter_url_label.setText(_translate("Form", statusList[4])) # Set intial Volume self.volumeslider.setRange(0, 100) self.volumeslider.setValue(75) self.mediaPlayer.setVolume(75) self.position_slider.setRange(0, 100) # connecting buttons self.miniplayer_button.clicked.connect(self.setupMiniPlayer) self.position_slider.sliderMoved.connect(self.setPosition) self.position_slider.sliderMoved.connect(self.handleLabel) self.volume_button.clicked.connect(self.mute) self.volumeslider.valueChanged.connect(self.setVolume) self.screenshot_button.clicked.connect(self.screenshot) self.playback_button.clicked.connect(self.stopplayback) self.always_on_top_button.clicked.connect(self.checkOnTop) self.play_button.clicked.connect(self.play) self.open_File_button.clicked.connect(self.openFile) # self.video_setting_button.clicked.connect(self.handleQuality) self.setting_button.clicked.connect(self.handleSetting) self.Quality_box.currentTextChanged.connect(self.handleQuality) self.cross_button.clicked.connect(self.exit) self.maximize_button.clicked.connect(self.max) self.minimize_button.clicked.connect(self.min) # Shortcuts shortcut = QShortcut(QKeySequence('Esc'), self.video_playback) shortcut.activated.connect(self.EscFun) shortcut = QShortcut(QKeySequence('Space'), self.video_playback) shortcut.activated.connect(self.play) shortcut = QShortcut(QKeySequence('f'), self.video_playback) shortcut.activated.connect(self.fullscreen_video) shortcut = QShortcut(QKeySequence('c'), self.video_playback) shortcut.activated.connect(self.setupMiniPlayer) shortcut = QShortcut(QKeySequence('o'), self.video_playback) shortcut.activated.connect(self.openFile) shortcut = QShortcut(QKeySequence('a'), self.video_playback) shortcut.activated.connect(self.checkOnTop) shortcut = QShortcut(QKeySequence("Return"), self.video_playback) shortcut.activated.connect(self.playOnline) shortcut = QShortcut(QKeySequence('m'), self.video_playback) shortcut.activated.connect(self.mute) shortcut = QShortcut(QKeySequence(Qt.Key_Right), self.video_playback) shortcut.activated.connect(self.forwardSlider) shortcut = QShortcut(QKeySequence(Qt.Key_Left), self.video_playback) shortcut.activated.connect(self.backSlider) self.volupshortcut = QShortcut(QKeySequence(Qt.Key_Up), self.video_playback) self.volupshortcut.activated.connect(self.volumeUp) self.voldownshortcut = QShortcut(QKeySequence(Qt.Key_Down), self.video_playback) self.voldownshortcut.activated.connect(self.volumeDown) shortcut = QShortcut(QKeySequence(Qt.ControlModifier + Qt.Key_Right), self.video_playback) shortcut.activated.connect(self.forwardSlider10) shortcut = QShortcut(QKeySequence(Qt.ControlModifier + Qt.Key_Left), self.video_playback) shortcut.activated.connect(self.backSlider10) shortcut = QShortcut(QKeySequence(Qt.AltModifier + Qt.Key_Left), self.video_playback) shortcut.activated.connect(self.backSlider5) shortcut = QShortcut(QKeySequence(Qt.AltModifier + Qt.Key_Right), self.video_playback) shortcut.activated.connect(self.forwardSlider5) # loading history to Url Box items = self.load() self.url_box.addItems(items) self.url_box.setCurrentIndex(-1) # icon size # iconSize = QSize(5,5) # self.play_button.setIconSize(iconSize) # self.playback_button.setIconSize(iconSize) # self.screenshot_button.setIconSize(iconSize) # self.always_on_top_button.setIconSize(iconSize) # self.miniplayer_button.setIconSize(iconSize) # self.setting_button.setIconSize(iconSize) # self.volume_button.setIconSize(iconSize) # button size btnSize = QSize(22, 22) self.play_button.setMaximumSize(btnSize) self.playback_button.setMaximumSize(btnSize) self.screenshot_button.setMaximumSize(btnSize) self.always_on_top_button.setMaximumSize(btnSize) self.miniplayer_button.setMaximumSize(btnSize) # self.video_setting_button.setMaximumSize(btnSize) self.setting_button.setMaximumSize(btnSize) self.volume_button.setMaximumSize(btnSize) # set margin self.horizontalLayout.setContentsMargins(10, 5, 9, 0) self.horizontalLayout_4.setContentsMargins(9, 0, 9, 0) self.horizontalLayout_4.setSpacing(4) self.horizontalLayout_5.setContentsMargins(0, 5, 5, 5) self.horizontalLayout_6.setContentsMargins(9, 0, 9, 0) # Media player settings self.mediaPlayer.setVideoOutput(self.video_playback) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.positionChanged.connect(self.handleLabel) self.mediaPlayer.durationChanged.connect(self.durationChanged) def handleLabel(self): self.time_status.clear() mtime = QtCore.QTime(0, 0, 0, 0) self.time = mtime.addMSecs(self.mediaPlayer.position()) self.time_status.setText(self.time.toString()) def hide_all(self): self.frame_3.close() # self.frame.close() self.url_box.close() self.playback_button.close() self.screenshot_button.close() self.Quality_box.close() self.volume_button.close() # self.video_setting_button.close() # self.setting_button.close() def show_all(self): self.frame_3.show() # self.frame.show() self.url_box.show() self.playback_button.show() self.screenshot_button.show() self.Quality_box.show() self.volume_button.show() # self.video_setting_button.show() self.setting_button.show() def checkOnTop(self): self.isOnTop = not self.isOnTop if self.isOnTop: self.always_on_top_button.setProperty("top", True) self.always_on_top_button.setStyle( self.always_on_top_button.style()) Form.setWindowFlags(Form.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) else: self.always_on_top_button.setProperty("top", False) self.always_on_top_button.setStyle( self.always_on_top_button.style()) Form.setWindowFlags(Form.windowFlags() & ~QtCore.Qt.WindowStaysOnTopHint) Form.show() def miniProperty(self): self.video_playback.setMinimumSize(QSize(200, 100)) self.video_playback.resize(QSize(550, 270)) Form.resize(QSize(550, 270)) Form.setMinimumSize(QSize(200, 175)) self.mainFrame.setMinimumSize(QSize(200, 60)) self.mainFrame.resize(QSize(200, 53)) def standardProperty(self): self.video_playback.setMinimumSize(QSize(200, 100)) self.mainFrame.setMinimumSize(QSize(200, 82)) Form.setMinimumSize(QSize(200, 202)) Form.resize(550, 369) def setupMiniPlayer(self): self.isMini = not self.isMini if self.isMini: self.miniplayer_button.setProperty("mini", True) self.miniplayer_button.setStyle(self.miniplayer_button.style()) self.hide_all() self.miniProperty() else: self.miniplayer_button.setProperty("mini", False) self.miniplayer_button.setStyle(self.miniplayer_button.style()) self.standardProperty() self.show_all() def load(self): scorefile = "db.bat" if os.path.exists(scorefile): with open(scorefile, 'rb') as sf: scores = pickle.load(sf) else: scores = [] with open(scorefile, "wb") as sf: pickle.dump(scores, sf) return scores def scor_func(self, url): scorefile = "db.bat" if os.path.exists(scorefile): with open(scorefile, 'rb') as sf: scores = pickle.load(sf) else: scores = [] scores.append(url) with open(scorefile, "wb") as sf: if len(scores) > 100: print("here", scores) scores = scores[1:] pickle.dump(scores, sf) return scores def mute(self): if self.mediaPlayer.isMuted(): print('[ ! Full Volume]') self.mediaPlayer.setMuted(False) icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.volume_button.setIcon(icon9) self.volume_button.setIconSize(QSize(22, 22)) self.volumeslider.setEnabled(True) # shortcut Enable self.volupshortcut.setEnabled(True) self.voldownshortcut.setEnabled(True) else: print('[ ! Mute Volume]') self.mediaPlayer.setMuted(True) icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.volume_button.setIcon(icon9) self.volume_button.setIconSize(QSize(22, 22)) self.volumeslider.setEnabled(False) # shrotcut disable self.volupshortcut.setEnabled(False) self.voldownshortcut.setEnabled(False) def play(self): if self.mediaPlayer.isVideoAvailable(): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: print("[ ! PAUSE PRESSED ]") self.mediaPlayer.pause() else: print("[ ! PLAY PRESSED ]") self.mediaPlayer.play() def playOnline(self): if self.url_box.currentText() != '': print('[ ! GETTING VIDEO ONLINE ]') fileName = self.url_box.currentText() res = requests.get('https://mediaplayerserver.herokuapp.com/', params={"key": fileName}) try: self.streams = json.loads(res.text) try: self.mediaPlayer.setMedia( QMediaContent(QUrl(self.streams['best']))) self.play_video() self.isOnline = True self.addQuality() if self.url_box.findText(fileName, Qt.MatchExactly) < 0: self.url_box.addItem(fileName) self.scor_func(fileName) except KeyError: print("[ ! Error Video Not Supported By platform]") except json.JSONDecodeError: print("[ ! Error NoPluginError]") finally: self.url_box.setCurrentText("") def openFile(self): print('[ ! OPEN FILE ]') username = getpass.getuser() if sys.platform == 'win32': path = 'C:/Users/' + username + '/Videos/' elif sys.platform == 'linux' or sys.platform == 'Darwin': path = '/home/' + username + '/Videos/' formats = str.join(' ', [ '*.%s' % str(fmt).strip('b').strip("'") for fmt in QtGui.QMovie.supportedFormats() ]) fileName, _ = QFileDialog.getOpenFileName( self.video_playback, "Select media file", path, "Video Files (*.mp4 *.flv *.ts *.mts *.avi *.mkv)") if fileName != '': self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(fileName))) self.play_video() # def decodeLink(self,url): # try: # streams = streamlink.streams(url) # keys = [k for k in streams.keys()] # data = dict() # for k in keys: # data[k] = streams[k].url # return data # except streamlink.NoPluginError: # return None # def playOnline(self): # if self.url_box.currentText() != '': # print('[ ! GETTING VIDEO ONLINE ]') # fileName = self.url_box.currentText() # self.streams = self.decodeLink(fileName) # try: # self.mediaPlayer.setMedia(QMediaContent(QUrl(self.streams['best']))) # self.play_video() # self.isOnline = True # self.addQuality() # if self.url_box.findText(fileName, Qt.MatchExactly) < 0: # self.url_box.addItem(fileName) # self.scor_func(fileName) # except KeyError: # print("[ ! Error Video Not Supported By platform]") # finally: # self.url_box.setCurrentText("") def play_video(self): print('[ ! PLAYING VIDEO ]') self.play_button.setEnabled(True) if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): print('[ ! CHANGING MEDIA STATE ]') if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.play_button.setProperty('play', False) self.play_button.setStyle(self.play_button.style()) else: self.play_button.setProperty('play', True) self.play_button.setStyle(self.play_button.style()) def stopplayback(self): print('[ ! STOP PLAYBACK VIDEO ]') self.mediaPlayer.stop() self.play_video() def positionChanged(self, position): print('[ ! POSITION CHANGED ]') self.position_slider.setValue(position) def durationChanged(self, duration): print('[ ! DURATION CHANGED ]') self.position_slider.setRange(0, duration) self.duration_status.clear() mtime = QtCore.QTime(0, 0, 0, 0) time = mtime.addMSecs(self.mediaPlayer.duration()) self.duration_status.setText(time.toString()) def setPosition(self, position): print('[ ! POSITION SET ]') self.mediaPlayer.setPosition(position) def setVolumePos(self, remain): print('[ ! REMANING VOLUME ]') print(remain) self.volumeslider.setRange(remain, 100) def setVolume(self, vol): print('[ ! SET VOLUME ]') print("set volume = " + str(vol)) if vol >= 0 and vol <= 100: self.volume_percentage.setText(" " + str(vol) + " %") if vol <= 0: icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.volume_button.setIcon(icon9) else: icon9 = QtGui.QIcon() icon9.addPixmap(QtGui.QPixmap("icon_sets/volume/volume1.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.volume_button.setIcon(icon9) self.volumeslider.setValue(vol) self.mediaPlayer.setVolume(vol) def screenshot(self): print('[ ! SCREENSHOT ]') wincen = Form.geometry() topX = wincen.topLeft().x() topY = wincen.topLeft().y() geo = self.video_playback.geometry() image = pyautogui.screenshot(region=(topX, topY + 38, geo.width(), geo.height() - 35)) filename = "screenshot" + str(uuid.uuid4()) + ".png" username = getpass.getuser() if sys.platform == 'win32': path = 'C:/Users/' + username + '/Pictures/' + filename elif sys.platform == 'linux' or sys.platform == 'Darwin': path = '/home/' + username + '/Pictures/' + filename image.save(path) def EscFun(self): if self.video_playback.isFullScreen(): Form.show() self.video_playback.setFullScreen(False) def fullscreen_video(self): if self.mediaPlayer.isVideoAvailable(): if self.video_playback.isFullScreen(): self.video_playback.setFullScreen(False) print('[ ! Normal Screen ]') Form.show() else: print('[ ! Full Screen ]') self.video_playback.setFullScreen(True) Form.hide() def getFormat(self): li = [k for k in self.streams.keys()] for q in li: if q.startswith('audio'): li.remove(q) try: li.remove('audio_opus') except ValueError: pass return li def changeQuality(self, quality): pos = self.mediaPlayer.position() try: self.mediaPlayer.setMedia( QMediaContent(QUrl(self.streams[quality]))) except KeyError: pass self.setPosition(pos) self.mediaPlayer.play() def handleSetting(self): from setting import SettingDialog dlg = SettingDialog() dlg.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) dlg.exec_() def addQuality(self): self.Quality_box.clear() self.Quality_box.addItems(self.getFormat()) def handleQuality(self): if self.isOnline: self.changeQuality(self.Quality_box.currentText()) def forwardSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000) def forwardSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10000) def forwardSlider5(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 5000) def backSlider(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000) def backSlider10(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10000) def backSlider5(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 5000) def volumeUp(self): self.setVolume(self.mediaPlayer.volume() + 10) print("Volume: " + str(self.mediaPlayer.volume())) def volumeDown(self): self.setVolume(self.mediaPlayer.volume() - 10) print("Volume: " + str(self.mediaPlayer.volume())) def max(self): if not Form.isMaximized(): print("[! Window is Maximized]") Form.showMaximized() else: print("[! Window is Normal]") Form.showNormal() def min(self): if not Form.isMinimized(): print("[! Window is Minimized]") Form.showMinimized() else: print("[! Window is Normal]") Form.showNormal() def exit(self): self.mediaPlayer.stop() sys.exit()
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 Ui_Form(QWidget): def __init__(self): super().__init__() self.points_CAM1 = [] self.points_CAM2 = [] self.points_CAM3 = [] def setupUi(self, Form): Form.setObjectName("Form") self.tabWidget = QtWidgets.QTabWidget(Form) self.tabWidget.setObjectName("tabWidget") self.multiTab = QtWidgets.QWidget() self.multiTab.setObjectName("multiTab") # cam1 self.cam_1 = QtWidgets.QWidget(self.multiTab) self.cam_1.setObjectName("cam_1") self.CAM1 = QtWidgets.QLabel(self.cam_1) self.CAM1.setFrameShape(QtWidgets.QFrame.Box) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.CAM1.sizePolicy().hasHeightForWidth()) self.CAM1.setSizePolicy(sizePolicy) self.CAM1.setMinimumSize(QtCore.QSize(320, 240)) self.CAM1.setMaximumSize(QtCore.QSize(400, 320)) self.CAM1.setSizeIncrement(QtCore.QSize(3, 2)) self.CAM1.setScaledContents(True) self.CAM1.setObjectName("CAM1") self.startCAM1 = QtWidgets.QPushButton(self.cam_1) self.startCAM1.setObjectName("startCAM1") self.stopCAM1 = QtWidgets.QPushButton(self.cam_1) self.stopCAM1.setObjectName("stopCAM1") self.reIDBtn_1 = QtWidgets.QPushButton(self.cam_1) self.reIDBtn_1.setObjectName("reIDBtn_1") self.falldetectionBtn_1 = QtWidgets.QPushButton(self.cam_1) self.falldetectionBtn_1.setObjectName("falldetectionBtn_1") self.peoplecntBtn_1 = QtWidgets.QPushButton(self.cam_1) self.peoplecntBtn_1.setObjectName("peoplecntBtn_1") self.areaprotectionBtn_1 = QtWidgets.QPushButton(self.cam_1) self.areaprotectionBtn_1.setObjectName("areaprotectionBtn_1") layoutCam_1 = QGridLayout(self.cam_1) layoutCam_1.addWidget(self.CAM1, 0, 0, 7, 3) layoutCam_1.addWidget(self.startCAM1, 8, 0) layoutCam_1.addWidget(self.stopCAM1, 9, 0) layoutCam_1.addWidget(self.reIDBtn_1, 8, 1) layoutCam_1.addWidget(self.falldetectionBtn_1, 8, 2) layoutCam_1.addWidget(self.peoplecntBtn_1, 9, 1) layoutCam_1.addWidget(self.areaprotectionBtn_1, 9, 2) self.cam_1.setLayout(layoutCam_1) # Setting Multi_tab Cam 2 self.cam_2 = QtWidgets.QWidget(self.multiTab) self.cam_2.setObjectName("cam_2") self.CAM2 = QtWidgets.QLabel(self.cam_2) self.CAM2.setFrameShape(QtWidgets.QFrame.Box) self.CAM2.setSizePolicy(sizePolicy) self.CAM2.setMinimumSize(QtCore.QSize(320, 240)) self.CAM2.setMaximumSize(QtCore.QSize(400, 320)) self.CAM2.setSizeIncrement(QtCore.QSize(3, 2)) self.CAM2.setObjectName("CAM2") self.CAM2.setScaledContents(True) self.peoplecntBtn_2 = QtWidgets.QPushButton(self.cam_2) self.peoplecntBtn_2.setObjectName("peoplecntBtn_2") self.falldetectionBtn_2 = QtWidgets.QPushButton(self.cam_2) self.falldetectionBtn_2.setObjectName("falldetectionBtn_2") self.reIDBtn_2 = QtWidgets.QPushButton(self.cam_2) self.reIDBtn_2.setObjectName("reIDBtn_2") self.stop_CAM2 = QtWidgets.QPushButton(self.cam_2) self.stop_CAM2.setObjectName("stop_CAM2") self.start_CAM2 = QtWidgets.QPushButton(self.cam_2) self.start_CAM2.setObjectName("start_CAM2") self.areaprotectionBtn_2 = QtWidgets.QPushButton(self.cam_2) self.areaprotectionBtn_2.setObjectName("areaprotectionBtn_2") layoutCam_2 = QGridLayout(self.cam_2) layoutCam_2.addWidget(self.CAM2, 0, 0, 7, 3) layoutCam_2.addWidget(self.start_CAM2, 8, 0) layoutCam_2.addWidget(self.stop_CAM2, 9, 0) layoutCam_2.addWidget(self.reIDBtn_2, 8, 1) layoutCam_2.addWidget(self.falldetectionBtn_2, 8, 2) layoutCam_2.addWidget(self.peoplecntBtn_2, 9, 1) layoutCam_2.addWidget(self.areaprotectionBtn_2, 9, 2) self.cam_2.setLayout(layoutCam_2) # Setting Multi_tab Cam 3 self.cam_3 = QtWidgets.QWidget(self.multiTab) self.cam_3.setObjectName("cam_3") self.CAM3 = QtWidgets.QLabel(self.cam_3) self.CAM3.setFrameShape(QtWidgets.QFrame.Box) self.CAM3.setSizePolicy(sizePolicy) self.CAM3.setMinimumSize(QtCore.QSize(320, 240)) self.CAM3.setMaximumSize(QtCore.QSize(400, 320)) self.CAM3.setSizeIncrement(QtCore.QSize(3, 2)) self.CAM3.setObjectName("CAM3") self.CAM3.setScaledContents(True) self.peoplecntBtn_3 = QtWidgets.QPushButton(self.cam_3) self.peoplecntBtn_3.setObjectName("peoplecntBtn_3") self.falldetectionBtn_3 = QtWidgets.QPushButton(self.cam_3) self.falldetectionBtn_3.setObjectName("falldetectionBtn_3") self.reIDBtn_3 = QtWidgets.QPushButton(self.cam_3) self.reIDBtn_3.setObjectName("reIDBtn_3") self.stop_CAM3 = QtWidgets.QPushButton(self.cam_3) self.stop_CAM3.setObjectName("stop_CAM3") self.start_CAM3 = QtWidgets.QPushButton(self.cam_3) self.start_CAM3.setObjectName("start_CAM3") self.areaprotectionBtn_3 = QtWidgets.QPushButton(self.cam_3) self.areaprotectionBtn_3.setObjectName("areaprotectionBtn_3") layoutCam_3 = QGridLayout(self.cam_3) layoutCam_3.addWidget(self.CAM3, 0, 0, 7, 3) layoutCam_3.addWidget(self.start_CAM3, 8, 0) layoutCam_3.addWidget(self.stop_CAM3, 9, 0) layoutCam_3.addWidget(self.reIDBtn_3, 8, 1) layoutCam_3.addWidget(self.falldetectionBtn_3, 8, 2) layoutCam_3.addWidget(self.peoplecntBtn_3, 9, 1) layoutCam_3.addWidget(self.areaprotectionBtn_3, 9, 2) self.cam_3.setLayout(layoutCam_3) # Setting layout multi_tab layoutMultitab = QGridLayout(self.multiTab) layoutMultitab.addWidget(self.cam_1, 0, 0) layoutMultitab.addWidget(self.cam_2, 0, 1) layoutMultitab.addWidget(self.cam_3, 0, 2) self.multiTab.setLayout(layoutMultitab) self.tabWidget.addTab(self.multiTab, "") # Media Player self.playRec = QtWidgets.QWidget() self.playRec.setObjectName("playRec") self.tabWidget.addTab(self.playRec, "") self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videowidget = QVideoWidget() self.openBtn = QtWidgets.QPushButton('Open Video') self.playBtn = QtWidgets.QPushButton() self.playBtn.setEnabled(False) self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.stopBtn = QtWidgets.QPushButton() self.stopBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.slowBtn = QtWidgets.QPushButton() self.slowBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekBackward)) self.fastBtn = QtWidgets.QPushButton() self.fastBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekForward)) self.volumeBtn = QtWidgets.QPushButton() self.volumeBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume)) self.fullscreenBtn = QPushButton("Full Screen") self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 0) self.volume_slider = QSlider(Qt.Horizontal) self.volume_slider.setRange(0, 100) self.volume_slider.setValue(100) self.label_2_1 = QLabel() self.label_2_1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.label_2_2 = QLabel() hboxLayout_2_1 = QHBoxLayout() hboxLayout_2_2 = QHBoxLayout() hboxLayout_2_3 = QHBoxLayout() hboxLayout_2_1.addWidget(self.slider) hboxLayout_2_2.addWidget(self.openBtn) hboxLayout_2_2.addWidget(self.stopBtn) hboxLayout_2_2.addWidget(self.slowBtn) hboxLayout_2_2.addWidget(self.playBtn) hboxLayout_2_2.addWidget(self.fastBtn) hboxLayout_2_2.addWidget(self.volumeBtn) hboxLayout_2_2.addWidget(self.volume_slider) hboxLayout_2_2.addStretch(1) hboxLayout_2_2.addWidget(self.fullscreenBtn) hboxLayout_2_3.addWidget(videowidget) vboxLayout_2_1 = QVBoxLayout() vboxLayout_2_1.addLayout(hboxLayout_2_3) vboxLayout_2_1.addLayout(hboxLayout_2_1) vboxLayout_2_1.addLayout(hboxLayout_2_2) vboxLayout_2_1.addWidget(self.label_2_1) self.playRec.setLayout(vboxLayout_2_1) #Tab Setting self.setting = QtWidgets.QWidget() self.setting.setObjectName("setting") self.tabWidget.addTab(self.setting, "") # Cam 1 self.camSetting_1 = QtWidgets.QWidget(self.setting) self.camSetting_1.setObjectName("camSetting_1") self.CAM1_Draw = QtWidgets.QLabel(self.camSetting_1) self.CAM1_Draw.setFrameShape(QtWidgets.QFrame.Box) self.CAM1_Draw.setSizePolicy(sizePolicy) self.CAM1_Draw.setMinimumSize(QtCore.QSize(320, 240)) self.CAM1_Draw.setMaximumSize(QtCore.QSize(400, 320)) self.CAM1_Draw.setSizeIncrement(QtCore.QSize(3, 2)) self.CAM1_Draw.setObjectName("CAM1_Draw") self.draw_CAM1 = QtWidgets.QPushButton(self.camSetting_1) self.draw_CAM1.setObjectName("draw_CAM1") self.remove_CAM1 = QtWidgets.QPushButton(self.camSetting_1) self.remove_CAM1.setObjectName("remove_CAM1") layoutCamSetting_1 = QGridLayout() layoutCamSetting_1.addWidget(self.CAM1_Draw, 0, 0, 7, 4) layoutCamSetting_1.addWidget(self.draw_CAM1, 8, 1) layoutCamSetting_1.addWidget(self.remove_CAM1, 8, 2) self.camSetting_1.setLayout(layoutCamSetting_1) #camSetting 2 self.camSetting_2 = QtWidgets.QWidget(self.setting) self.camSetting_2.setObjectName("camSetting_2") self.CAM2_Draw = QtWidgets.QLabel(self.camSetting_2) self.CAM2_Draw.setFrameShape(QtWidgets.QFrame.Box) self.CAM2_Draw.setSizePolicy(sizePolicy) self.CAM2_Draw.setMinimumSize(QtCore.QSize(320, 240)) self.CAM2_Draw.setMaximumSize(QtCore.QSize(400, 320)) self.CAM2_Draw.setSizeIncrement(QtCore.QSize(3, 2)) self.CAM2_Draw.setObjectName("CAM2_Draw") self.draw_CAM2 = QtWidgets.QPushButton(self.camSetting_2) self.draw_CAM2.setObjectName("draw_CAM2") self.remove_CAM2 = QtWidgets.QPushButton(self.camSetting_2) self.remove_CAM2.setObjectName("remove_CAM2") layoutCamSetting_2 = QGridLayout() layoutCamSetting_2.addWidget(self.CAM2_Draw, 0, 0, 7, 4) layoutCamSetting_2.addWidget(self.draw_CAM2, 8, 1) layoutCamSetting_2.addWidget(self.remove_CAM2, 8, 2) self.camSetting_2.setLayout(layoutCamSetting_2) #camSeting 3 self.camSetting_3 = QtWidgets.QWidget(self.setting) self.camSetting_3.setObjectName("camSetting_3") self.CAM3_Draw = QtWidgets.QLabel(self.camSetting_3) self.CAM3_Draw.setFrameShape(QtWidgets.QFrame.Box) self.CAM3_Draw.setSizePolicy(sizePolicy) self.CAM3_Draw.setMinimumSize(QtCore.QSize(320, 240)) self.CAM3_Draw.setMaximumSize(QtCore.QSize(400, 320)) self.CAM3_Draw.setSizeIncrement(QtCore.QSize(3, 2)) self.CAM3_Draw.setObjectName("CAM3_Draw") self.draw_CAM3 = QtWidgets.QPushButton(self.camSetting_3) self.draw_CAM3.setObjectName("draw_CAM3") self.remove_CAM3 = QtWidgets.QPushButton(self.camSetting_3) self.remove_CAM3.setObjectName("remove_CAM3") layoutCamSetting_3 = QGridLayout() layoutCamSetting_3.addWidget(self.CAM3_Draw, 0, 0, 7, 4) layoutCamSetting_3.addWidget(self.draw_CAM3, 8, 1) layoutCamSetting_3.addWidget(self.remove_CAM3, 8, 2) self.camSetting_3.setLayout(layoutCamSetting_3) #layout Setting layoutSetting = QGridLayout() layoutSetting.addWidget(self.camSetting_1, 0, 0) layoutSetting.addWidget(self.camSetting_2, 0, 1) layoutSetting.addWidget(self.camSetting_3, 0, 2) self.setting.setLayout(layoutSetting) self.mediaPlayer.setVideoOutput(videowidget) self.openBtn.clicked.connect(self.open_file) self.playBtn.clicked.connect(self.play_video) self.stopBtn.clicked.connect(self.stop_video) self.fastBtn.clicked.connect(self.fast) self.slowBtn.clicked.connect(self.slow) self.volumeBtn.clicked.connect(self.mute) self.fullscreenBtn.clicked.connect(self.fullscreen) self.volume_slider.sliderMoved.connect(self.set_volume) self.slider.sliderMoved.connect(self.set_position) self.mediaPlayer.stateChanged.connect(self.mediastate_changed) self.mediaPlayer.positionChanged.connect(self.position_changed) self.mediaPlayer.durationChanged.connect(self.duration_changed) self.startCAM1.setEnabled(True) self.start_CAM2.setEnabled(True) self.start_CAM3.setEnabled(True) self.stopCAM1.setEnabled(False) self.stop_CAM2.setEnabled(False) self.stop_CAM3.setEnabled(False) # create a timer self.timer = QTimer() self.timer2 = QTimer() self.timer3 = QTimer() # set timer timeout callback function self.timer.timeout.connect(self.viewCam) self.startCAM1.clicked.connect(self.start_view) self.stopCAM1.clicked.connect(self.stop_view) self.timer2.timeout.connect(self.viewCam2) self.start_CAM2.clicked.connect(self.start_view2) self.stop_CAM2.clicked.connect(self.stop_view2) self.timer3.timeout.connect(self.viewCam3) self.start_CAM3.clicked.connect(self.start_view3) self.stop_CAM3.clicked.connect(self.stop_view3) self.CAM1_Draw.mousePressEvent = self.mouseEventCAM1 self.CAM2_Draw.mousePressEvent = self.mouseEventCAM2 self.CAM3_Draw.mousePressEvent = self.mouseEventCAM3 self.draw_CAM1.clicked.connect(self.startDrawAreaCAM1) self.remove_CAM1.clicked.connect(self.removeAreaCAM1) self.draw_CAM2.clicked.connect(self.startDrawAreaCAM2) self.remove_CAM2.clicked.connect(self.removeAreaCAM2) self.draw_CAM3.clicked.connect(self.startDrawAreaCAM3) self.remove_CAM3.clicked.connect(self.removeAreaCAM3) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) a = QVBoxLayout() a.addWidget(self.tabWidget) Form.setLayout(a) # all function def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.CAM1.setText(_translate("Form", "Cam 1")) self.peoplecntBtn_1.setText(_translate("Form", "People Counting")) self.falldetectionBtn_1.setText(_translate("Form", "Fall Detection")) self.reIDBtn_1.setText(_translate("Form", "Person Re-ID")) self.stopCAM1.setText(_translate("Form", "Stop")) self.startCAM1.setText(_translate("Form", "Start")) self.areaprotectionBtn_1.setText(_translate("Form", "Area Protection")) self.CAM2.setText(_translate("Form", "cam 2")) self.peoplecntBtn_2.setText(_translate("Form", "People Counting")) self.falldetectionBtn_2.setText(_translate("Form", "Fall Detection")) self.reIDBtn_2.setText(_translate("Form", "Person Re-ID")) self.stop_CAM2.setText(_translate("Form", "Stop")) self.start_CAM2.setText(_translate("Form", "Start")) self.areaprotectionBtn_2.setText(_translate("Form", "Area Protection")) self.CAM3.setText(_translate("Form", "cam 3")) self.peoplecntBtn_3.setText(_translate("Form", "People Counting")) self.falldetectionBtn_3.setText(_translate("Form", "Fall Detection")) self.reIDBtn_3.setText(_translate("Form", "Person Re-ID")) self.stop_CAM3.setText(_translate("Form", "Stop")) self.start_CAM3.setText(_translate("Form", "Start")) self.areaprotectionBtn_3.setText(_translate("Form", "Area Protection")) self.CAM1_Draw.setText(_translate("Form", "cam 1")) self.draw_CAM1.setText(_translate("Form", "Draw")) self.remove_CAM1.setText(_translate("Form", "Clean")) self.CAM2_Draw.setText(_translate("Form", "cam 2")) self.draw_CAM2.setText(_translate("Form", "Draw")) self.remove_CAM2.setText(_translate("Form", "Clean")) self.CAM3_Draw.setText(_translate("Form", "cam 3")) self.draw_CAM3.setText(_translate("Form", "Draw")) self.remove_CAM3.setText(_translate("Form", "Clean")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.multiTab), _translate("Form", "Multi_IPCam")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.playRec), _translate("Form", "Play Record")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.setting), _translate("Form", "Setting")) def open_file(self): filename, _ = QFileDialog.getOpenFileName(self, "Open Video") if filename != '': self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.playBtn.setEnabled(True) def play_video(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def stop_video(self): self.mediaPlayer.stop() def mediastate_changed(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def position_changed(self, position): self.slider.setValue(position) def duration_changed(self, duration): self.slider.setRange(0, duration) def set_position(self, position): self.mediaPlayer.setPosition(position) print(position) def set_volume(self, volume): self.mediaPlayer.setVolume(volume) def mute(self): if not self.mediaPlayer.isMuted(): self.mediaPlayer.setMuted(True) self.volumeBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaVolumeMuted)) else: self.mediaPlayer.setMuted(False) self.volumeBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume)) def handle_errors(self): self.playBtn.setEnabled(False) self.label.setText("Error: " + self.mediaPlayer.errorString()) self.startCAM1.clicked.connect(self.start) self.stopCAM1.clicked.connect(self.stop) def fullscreen(self): if self.windowState() & Qt.WindowFullScreen: QApplication.setOverrideCursor(Qt.ArrowCursor) self.showNormal() print("no Fullscreen") else: Form.showFullScreen() QApplication.setOverrideCursor(Qt.BlankCursor) print("Fullscreen entered") def fast(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10 * 60) def slow(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10 * 60) def image_to_QImage(self, image, label): # print(label.width(), label.height()) # image = cv2.resize(image, (label.width(), label.height())) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) height, width, channel = image.shape # print(height, width, channel) step = channel * width return QImage(image.data, width, height, step, QImage.Format_RGB888) def viewCam(self): ret, image = self.cap.read() self.outVivdeo.write(image) self.CAM1_Draw.setPixmap( QPixmap.fromImage( self.image_to_QImage( self.drawArea(image, self.points_CAM1, self.CAM1_Draw), self.CAM1_Draw))) self.CAM1.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) def start_view(self): if not self.timer.isActive(): self.stopCAM1.setEnabled(True) self.startCAM1.setEnabled(False) self.cap = cv2.VideoCapture(IP_CAM_ADDRESS['CAM1']) self.flag_CAM1 = self.cap.isOpened() if self.cap.isOpened(): now = datetime.now() self.savePath1 = self.createDir('IP_CAM_1') self.startTime1 = str(now.day) + ' - ' + str( now.hour) + 'h' + str(now.minute) + ' - ' # fourcc = cv2.VideoWriter_fourcc(*'mp4v') fourcc = cv2.VideoWriter_fourcc(*'XVID') self.outVivdeo = cv2.VideoWriter( self.savePath1 + 'output.avi', fourcc, 30, (int(self.cap.get(3)), int(self.cap.get(4)))) self.timer.start(0) else: self.startCAM1.setEnabled(True) self.stopCAM1.setEnabled(False) image = cv2.imread('no-connection.jpg') self.CAM1.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) def stop_view(self): self.startCAM1.setEnabled(True) self.stopCAM1.setEnabled(False) self.timer.stop() self.cap.release() self.outVivdeo.release() print("ok") image = cv2.imread('stopVideo.png') self.CAM1.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) print('ok2') now = datetime.now() fileName = self.startTime1 + str(now.hour) + 'h' + str( now.minute) + '.avi' os.rename(self.savePath1 + 'output.avi', self.savePath1 + fileName) def viewCam2(self): ret, image = self.cap2.read() self.outVivdeo2.write(image) self.CAM2_Draw.setPixmap( QPixmap.fromImage( self.image_to_QImage( self.drawArea(image, self.points_CAM2, self.CAM2_Draw), self.CAM2_Draw))) self.CAM2.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) def start_view2(self): if not self.timer2.isActive(): self.stop_CAM2.setEnabled(True) self.start_CAM2.setEnabled(False) self.cap2 = cv2.VideoCapture(IP_CAM_ADDRESS['CAM2']) self.flag_CAM2 = self.cap2.isOpened() if self.cap2.isOpened(): now = datetime.now() self.savePath2 = self.createDir('IP_CAM_2') self.startTime2 = str(now.day) + ' - ' + str( now.hour) + 'h' + str(now.minute) + ' - ' # fourcc = cv2.VideoWriter_fourcc(*'mp4v') fourcc = cv2.VideoWriter_fourcc(*'XVID') self.outVivdeo2 = cv2.VideoWriter( self.savePath2 + 'output2.avi', fourcc, 30, (int(self.cap2.get(3)), int(self.cap2.get(4)))) self.timer2.start(0) else: self.start_CAM2.setEnabled(True) self.stop_CAM2.setEnabled(False) image = cv2.imread('no-connection.jpg') self.CAM2.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) def stop_view2(self): self.start_CAM2.setEnabled(True) self.stop_CAM2.setEnabled(False) self.timer2.stop() self.outVivdeo2.release() image = cv2.imread('stopVideo.png') self.CAM2.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) self.cap2.release() now = datetime.now() fileName = self.startTime2 + str(now.hour) + 'h' + str( now.minute) + '.avi' os.rename(self.savePath2 + 'output2.avi', self.savePath2 + fileName) def viewCam3(self): ret, image = self.cap3.read() self.outVivdeo3.write(image) self.CAM3_Draw.setPixmap( QPixmap.fromImage( self.image_to_QImage( self.drawArea(image, self.points_CAM3, self.CAM3_Draw), self.CAM3_Draw))) self.CAM3.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM3))) def start_view3(self): if not self.timer3.isActive(): self.stop_CAM3.setEnabled(True) self.start_CAM3.setEnabled(False) self.cap3 = cv2.VideoCapture(IP_CAM_ADDRESS['CAM3']) self.flag_CAM3 = self.cap3.isOpened() if self.cap3.isOpened(): now = datetime.now() self.savePath3 = self.createDir('IP_CAM_3') self.startTime3 = str(now.day) + ' - ' + str( now.hour) + 'h' + str(now.minute) + ' - ' # fourcc = cv2.VideoWriter_fourcc(*'mp4v') fourcc = cv2.VideoWriter_fourcc(*'XVID') self.outVivdeo3 = cv2.VideoWriter( self.savePath3 + 'output3.avi', fourcc, 30, (int(self.cap3.get(3)), int(self.cap3.get(4)))) self.timer3.start(0) else: self.start_CAM3.setEnabled(True) self.stop_CAM3.setEnabled(False) image = cv2.imread('no-connection.jpg') self.CAM3.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM3))) def stop_view3(self): self.start_CAM3.setEnabled(True) self.stop_CAM3.setEnabled(False) self.timer3.stop() self.outVivdeo3.release() image = cv2.imread('stopVideo.png') self.CAM3.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM3))) self.cap3.release() now = datetime.now() fileName = self.startTime3 + str(now.hour) + 'h' + str( now.minute) + '.avi' os.rename(self.savePath3 + 'output3.avi', self.savePath3 + fileName) def createDir(self, IP_CAM_Number: str): now = datetime.now() year = now.year month = MONTH[now.month] curPath = os.getcwd() if not path.exists(curPath + '/IVA'): os.mkdir(curPath + '/IVA') if not path.exists(curPath + '/IVA/' + IP_CAM_Number): os.mkdir(curPath + '/IVA/' + IP_CAM_Number) # check path exists if path.exists(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year)): if path.exists(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month): return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' else: os.mkdir(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month) return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' else: os.mkdir(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year)) if path.exists(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month): return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' else: os.mkdir(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month) return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' # Create Mouse Event for draw protected area def mouseEventCAM1(self, event): if self.remove_CAM1.isEnabled() and ( not self.startCAM1.isEnabled()) and self.flag_CAM1 == True: x = event.pos().x() y = event.pos().y() self.points_CAM1.append([x, y]) print("Position clicked is ({}, {})".format(x, y)) def mouseEventCAM2(self, event): if self.remove_CAM2.isEnabled() and ( not self.start_CAM2.isEnabled()) and self.flag_CAM2 == True: x = event.pos().x() y = event.pos().y() self.points_CAM2.append([x, y]) print("Position clicked is ({}, {})".format(x, y)) def mouseEventCAM3(self, event): if self.remove_CAM3.isEnabled() and ( not self.start_CAM3.isEnabled()) and self.flag_CAM3 == True: x = event.pos().x() y = event.pos().y() self.points_CAM3.append([x, y]) print("Position clicked is ({}, {})".format(x, y)) def startDrawAreaCAM1(self): self.draw_CAM1.setEnabled(False) self.remove_CAM1.setEnabled(True) def removeAreaCAM1(self): while len(self.points_CAM1): self.points_CAM1.pop() self.draw_CAM1.setEnabled(True) self.remove_CAM1.setEnabled(False) def startDrawAreaCAM2(self): self.draw_CAM2.setEnabled(False) self.remove_CAM2.setEnabled(True) def removeAreaCAM2(self): while len(self.points_CAM2): self.points_CAM2.pop() self.draw_CAM2.setEnabled(True) self.remove_CAM2.setEnabled(False) def startDrawAreaCAM3(self): self.draw_CAM3.setEnabled(False) self.remove_CAM3.setEnabled(True) def removeAreaCAM3(self): while len(self.points_CAM3): self.points_CAM3.pop() self.draw_CAM3.setEnabled(True) self.remove_CAM3.setEnabled(False) def drawArea(self, image, points: list, qlabel: QtWidgets.QLabel): image_draw = image.copy() image_draw = cv2.resize(image_draw, (qlabel.width(), qlabel.height())) if len(points) > 1: cv2.polylines(image_draw, np.array([points]), 1, (255, 0, 0), 1) b, g, r = cv2.split(image_draw) cv2.fillPoly(b, np.array([points]), (0, 255, 0)) cv2.fillPoly(r, np.array([points]), (0, 255, 0)) image_draw = cv2.merge([b, g, r]) return image_draw
class Ui_MainWindow(QWidget): def __init__(self, feature=feature): super().__init__() self.feature = feature self.points_CAM1 = [] self.points_CAM2 = [] self.points_CAM3 = [] self.numWarning = 0 def setupUi(self, Form): Form.setObjectName("Form") Form.resize(1048, 375) self.verticalLayout_4 = QtWidgets.QVBoxLayout(Form) self.verticalLayout_4.setObjectName("verticalLayout_4") self.tabWidget = QtWidgets.QTabWidget(Form) self.tabWidget.setObjectName("tabWidget") self.tab = QtWidgets.QWidget() self.tab.setObjectName("tab") # View CAM 1 self.gridLayout = QtWidgets.QGridLayout(self.tab) self.gridLayout.setHorizontalSpacing(20) self.gridLayout.setObjectName("gridLayout") self.verticalLayout_3 = QtWidgets.QVBoxLayout() self.verticalLayout_3.setSpacing(10) self.verticalLayout_3.setObjectName("verticalLayout_3") self.CAM1 = QtWidgets.QLabel(self.tab) self.CAM1.setMinimumSize(QtCore.QSize(320, 240)) self.CAM1.setMaximumSize(QtCore.QSize(426, 400)) self.CAM1.setFrameShape(QtWidgets.QFrame.Box) self.CAM1.setObjectName("CAM1") self.verticalLayout_3.addWidget(self.CAM1) self.horizontalLayout_6 = QtWidgets.QHBoxLayout() self.horizontalLayout_6.setObjectName("horizontalLayout_6") self.startCAM1 = QtWidgets.QPushButton(self.tab) self.startCAM1.setObjectName("startCAM1") self.horizontalLayout_6.addWidget(self.startCAM1) self.carProtectionCAM1 = QtWidgets.QPushButton(self.tab) self.carProtectionCAM1.setObjectName("carProtectionCAM1") self.horizontalLayout_6.addWidget(self.carProtectionCAM1) self.monitorAreaCAM1 = QtWidgets.QPushButton(self.tab) self.monitorAreaCAM1.setObjectName("monitorAreaCAM1") self.horizontalLayout_6.addWidget(self.monitorAreaCAM1) self.verticalLayout_3.addLayout(self.horizontalLayout_6) self.horizontalLayout_7 = QtWidgets.QHBoxLayout() self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.stopCAM1 = QtWidgets.QPushButton(self.tab) self.stopCAM1.setEnabled(False) self.stopCAM1.setObjectName("stopCAM1") self.horizontalLayout_7.addWidget(self.stopCAM1) self.personSearchingCAM1 = QtWidgets.QPushButton(self.tab) self.personSearchingCAM1.setObjectName("personSearchingCAM1") self.horizontalLayout_7.addWidget(self.personSearchingCAM1) self.illegalCAM1 = QtWidgets.QPushButton(self.tab) self.illegalCAM1.setObjectName("illegalCAM1") self.horizontalLayout_7.addWidget(self.illegalCAM1) self.verticalLayout_3.addLayout(self.horizontalLayout_7) self.gridLayout.addLayout(self.verticalLayout_3, 0, 0, 1, 1) self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setSpacing(10) self.verticalLayout.setObjectName("verticalLayout") # View CAM 2 self.CAM2 = QtWidgets.QLabel(self.tab) self.CAM2.setMinimumSize(QtCore.QSize(320, 240)) self.CAM2.setMaximumSize(QtCore.QSize(426, 400)) self.CAM2.setFrameShape(QtWidgets.QFrame.Box) self.CAM2.setObjectName("CAM2") self.verticalLayout.addWidget(self.CAM2) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.startCAM2 = QtWidgets.QPushButton(self.tab) self.startCAM2.setObjectName("startCAM2") self.horizontalLayout_2.addWidget(self.startCAM2) self.carProtectionCAM2 = QtWidgets.QPushButton(self.tab) self.carProtectionCAM2.setObjectName("carProtectionCAM2") self.horizontalLayout_2.addWidget(self.carProtectionCAM2) self.monitorAreaCAM2 = QtWidgets.QPushButton(self.tab) self.monitorAreaCAM2.setObjectName("monitorAreaCAM2") self.horizontalLayout_2.addWidget(self.monitorAreaCAM2) self.verticalLayout.addLayout(self.horizontalLayout_2) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.stopCAM2 = QtWidgets.QPushButton(self.tab) self.stopCAM2.setEnabled(False) self.stopCAM2.setObjectName("stopCAM2") self.horizontalLayout_3.addWidget(self.stopCAM2) self.personSearchingCAM2 = QtWidgets.QPushButton(self.tab) self.personSearchingCAM2.setObjectName("personSearchingCAM2") self.horizontalLayout_3.addWidget(self.personSearchingCAM2) self.illegalCAM2 = QtWidgets.QPushButton(self.tab) self.illegalCAM2.setObjectName("illegalCAM2") self.horizontalLayout_3.addWidget(self.illegalCAM2) self.verticalLayout.addLayout(self.horizontalLayout_3) self.gridLayout.addLayout(self.verticalLayout, 0, 1, 1, 1) self.verticalLayout_2 = QtWidgets.QVBoxLayout() self.verticalLayout_2.setSpacing(10) self.verticalLayout_2.setObjectName("verticalLayout_2") # View CAM 3 self.CAM3 = QtWidgets.QLabel(self.tab) self.CAM3.setMinimumSize(QtCore.QSize(320, 240)) self.CAM3.setMaximumSize(QtCore.QSize(426, 400)) self.CAM3.setFrameShape(QtWidgets.QFrame.Box) self.CAM3.setObjectName("CAM3") self.verticalLayout_2.addWidget(self.CAM3) self.horizontalLayout_4 = QtWidgets.QHBoxLayout() self.horizontalLayout_4.setObjectName("horizontalLayout_4") self.startCAM3 = QtWidgets.QPushButton(self.tab) self.startCAM3.setObjectName("startCAM3") self.horizontalLayout_4.addWidget(self.startCAM3) self.carProtectionCAM3 = QtWidgets.QPushButton(self.tab) self.carProtectionCAM3.setObjectName("carProtectionCAM3") self.horizontalLayout_4.addWidget(self.carProtectionCAM3) self.monitorAreaCAM3 = QtWidgets.QPushButton(self.tab) self.monitorAreaCAM3.setObjectName("monitorAreaCAM3") self.horizontalLayout_4.addWidget(self.monitorAreaCAM3) self.verticalLayout_2.addLayout(self.horizontalLayout_4) self.horizontalLayout_5 = QtWidgets.QHBoxLayout() self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.stopCAM3 = QtWidgets.QPushButton(self.tab) self.stopCAM3.setEnabled(False) self.stopCAM3.setObjectName("stopCAM3") self.horizontalLayout_5.addWidget(self.stopCAM3) self.personSearchingCAM3 = QtWidgets.QPushButton(self.tab) self.personSearchingCAM3.setObjectName("personSearchingCAM3") self.horizontalLayout_5.addWidget(self.personSearchingCAM3) self.illegalCAM3 = QtWidgets.QPushButton(self.tab) self.illegalCAM3.setObjectName("illegalCAM3") self.horizontalLayout_5.addWidget(self.illegalCAM3) self.verticalLayout_2.addLayout(self.horizontalLayout_5) self.gridLayout.addLayout(self.verticalLayout_2, 0, 2, 1, 1) self.tabWidget.addTab(self.tab, "") # Media Tab self.tab_2 = QtWidgets.QWidget() self.tab_2.setObjectName("tab_2") self.tabWidget.addTab(self.tab_2, "") self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videowidget = QVideoWidget() self.openBtn = QtWidgets.QPushButton('Open Video') self.playBtn = QtWidgets.QPushButton() self.playBtn.setEnabled(False) self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.stopBtn = QtWidgets.QPushButton() self.stopBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.slowBtn = QtWidgets.QPushButton() self.slowBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekBackward)) self.fastBtn = QtWidgets.QPushButton() self.fastBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekForward)) self.volumeBtn = QtWidgets.QPushButton() self.volumeBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume)) self.fullscreenBtn = QPushButton("Full Screen") self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 0) self.volume_slider = QSlider(Qt.Horizontal) self.volume_slider.setRange(0, 100) self.volume_slider.setValue(100) self.label_2_1 = QLabel() self.label_2_1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.label_2_2 = QLabel() hboxLayout_2_1 = QHBoxLayout() hboxLayout_2_2 = QHBoxLayout() hboxLayout_2_3 = QHBoxLayout() hboxLayout_2_1.addWidget(self.slider) hboxLayout_2_2.addWidget(self.openBtn) hboxLayout_2_2.addWidget(self.stopBtn) hboxLayout_2_2.addWidget(self.slowBtn) hboxLayout_2_2.addWidget(self.playBtn) hboxLayout_2_2.addWidget(self.fastBtn) hboxLayout_2_2.addWidget(self.volumeBtn) hboxLayout_2_2.addWidget(self.volume_slider) hboxLayout_2_2.addStretch(1) hboxLayout_2_2.addWidget(self.fullscreenBtn) hboxLayout_2_3.addWidget(videowidget) vboxLayout_2_1 = QVBoxLayout() vboxLayout_2_1.addLayout(hboxLayout_2_3) vboxLayout_2_1.addLayout(hboxLayout_2_1) vboxLayout_2_1.addLayout(hboxLayout_2_2) vboxLayout_2_1.addWidget(self.label_2_1) self.tab_2.setLayout(vboxLayout_2_1) # Setting CAM 1 self.tab_3 = QtWidgets.QWidget() self.tab_3.setObjectName("tab_3") self.gridLayout_2 = QtWidgets.QGridLayout(self.tab_3) self.gridLayout_2.setHorizontalSpacing(20) self.gridLayout_2.setObjectName("gridLayout_2") self.verticalLayout_5 = QtWidgets.QVBoxLayout() self.verticalLayout_5.setSpacing(10) self.verticalLayout_5.setObjectName("verticalLayout_5") self.CAM1_draw = QtWidgets.QLabel(self.tab_3) self.CAM1_draw.setMinimumSize(QtCore.QSize(320, 240)) self.CAM1_draw.setMaximumSize(QtCore.QSize(426, 400)) self.CAM1_draw.setFrameShape(QtWidgets.QFrame.Box) self.CAM1_draw.setObjectName("CAM1_draw") self.verticalLayout_5.addWidget(self.CAM1_draw) self.horizontalLayout_8 = QtWidgets.QHBoxLayout() self.horizontalLayout_8.setObjectName("horizontalLayout_8") self.drawCAM1 = QtWidgets.QPushButton(self.tab_3) self.drawCAM1.setObjectName("drawCAM1") self.horizontalLayout_8.addWidget(self.drawCAM1) self.removeCAM1 = QtWidgets.QPushButton(self.tab_3) self.removeCAM1.setObjectName("removeCAM1") self.horizontalLayout_8.addWidget(self.removeCAM1) self.verticalLayout_5.addLayout(self.horizontalLayout_8) self.gridLayout_2.addLayout(self.verticalLayout_5, 0, 0, 1, 1) self.verticalLayout_6 = QtWidgets.QVBoxLayout() self.verticalLayout_6.setSpacing(10) self.verticalLayout_6.setObjectName("verticalLayout_6") # Setting CAM 2 self.CAM2_draw = QtWidgets.QLabel(self.tab_3) self.CAM2_draw.setMinimumSize(QtCore.QSize(320, 240)) self.CAM2_draw.setMaximumSize(QtCore.QSize(426, 400)) self.CAM2_draw.setFrameShape(QtWidgets.QFrame.Box) self.CAM2_draw.setObjectName("CAM2_draw") self.verticalLayout_6.addWidget(self.CAM2_draw) self.horizontalLayout_10 = QtWidgets.QHBoxLayout() self.horizontalLayout_10.setObjectName("horizontalLayout_10") self.drawCAM2 = QtWidgets.QPushButton(self.tab_3) self.drawCAM2.setObjectName("drawCAM2") self.horizontalLayout_10.addWidget(self.drawCAM2) self.removeCAM2 = QtWidgets.QPushButton(self.tab_3) self.removeCAM2.setObjectName("removeCAM2") self.horizontalLayout_10.addWidget(self.removeCAM2) self.verticalLayout_6.addLayout(self.horizontalLayout_10) self.gridLayout_2.addLayout(self.verticalLayout_6, 0, 1, 1, 1) self.verticalLayout_7 = QtWidgets.QVBoxLayout() self.verticalLayout_7.setSpacing(10) self.verticalLayout_7.setObjectName("verticalLayout_7") # Setting CAM 3 self.CAM3_draw = QtWidgets.QLabel(self.tab_3) self.CAM3_draw.setMinimumSize(QtCore.QSize(320, 240)) self.CAM3_draw.setMaximumSize(QtCore.QSize(426, 400)) self.CAM3_draw.setFrameShape(QtWidgets.QFrame.Box) self.CAM3_draw.setObjectName("CAM3_draw") self.verticalLayout_7.addWidget(self.CAM3_draw) self.horizontalLayout_12 = QtWidgets.QHBoxLayout() self.horizontalLayout_12.setObjectName("horizontalLayout_12") self.drawCAM3 = QtWidgets.QPushButton(self.tab_3) self.drawCAM3.setObjectName("drawCAM3") self.horizontalLayout_12.addWidget(self.drawCAM3) self.removeCAM3 = QtWidgets.QPushButton(self.tab_3) self.removeCAM3.setObjectName("removeCAM3") self.horizontalLayout_12.addWidget(self.removeCAM3) self.verticalLayout_7.addLayout(self.horizontalLayout_12) self.gridLayout_2.addLayout(self.verticalLayout_7, 0, 2, 1, 1) self.tabWidget.addTab(self.tab_3, "") self.verticalLayout_4.addWidget(self.tabWidget) # Setup Connect # Setup enable self.removeCAM1.setEnabled(False) self.removeCAM2.setEnabled(False) self.removeCAM3.setEnabled(False) # Setup choosing feature self.carProtectionCAM1.setVisible(self.feature['car1']) self.carProtectionCAM2.setVisible(self.feature['car2']) self.carProtectionCAM3.setVisible(self.feature['car3']) self.illegalCAM1.setVisible(self.feature['illegal1']) self.illegalCAM2.setVisible(self.feature['illegal2']) self.illegalCAM3.setVisible(self.feature['illegal3']) self.monitorAreaCAM1.setVisible(self.feature['mpa1']) self.monitorAreaCAM1.toggle() self.monitorAreaCAM1.setCheckable(True) self.monitorAreaCAM2.setVisible(self.feature['mpa2']) self.monitorAreaCAM3.setVisible(self.feature['mpa3']) self.personSearchingCAM1.setVisible(self.feature['person1']) self.personSearchingCAM2.setVisible(self.feature['person2']) self.personSearchingCAM3.setVisible(self.feature['person3']) # setup media player self.mediaPlayer.setVideoOutput(videowidget) self.openBtn.clicked.connect(self.open_file) self.playBtn.clicked.connect(self.play_video) self.stopBtn.clicked.connect(self.stop_video) self.fastBtn.clicked.connect(self.fast) self.slowBtn.clicked.connect(self.slow) self.volumeBtn.clicked.connect(self.mute) self.fullscreenBtn.clicked.connect(self.fullscreen) self.volume_slider.sliderMoved.connect(self.set_volume) self.slider.sliderMoved.connect(self.set_position) self.mediaPlayer.stateChanged.connect(self.mediastate_changed) self.mediaPlayer.positionChanged.connect(self.position_changed) self.mediaPlayer.durationChanged.connect(self.duration_changed) # setup image processing # create a timer self.timer = QTimer() self.timer2 = QTimer() self.timer3 = QTimer() # set timer timeout callback function self.timer.timeout.connect(self.viewCam1) self.startCAM1.clicked.connect(self.start_view1) self.stopCAM1.clicked.connect(self.stop_view1) self.timer2.timeout.connect(self.viewCam2) self.startCAM2.clicked.connect(self.start_view2) self.stopCAM2.clicked.connect(self.stop_view2) self.timer3.timeout.connect(self.viewCam3) self.startCAM3.clicked.connect(self.start_view3) self.stopCAM3.clicked.connect(self.stop_view3) self.CAM1_draw.mousePressEvent = self.mouseEventCAM1 self.CAM2_draw.mousePressEvent = self.mouseEventCAM2 self.CAM3_draw.mousePressEvent = self.mouseEventCAM3 self.drawCAM1.clicked.connect(self.startDrawAreaCAM1) self.removeCAM1.clicked.connect(self.removeAreaCAM1) self.drawCAM2.clicked.connect(self.startDrawAreaCAM2) self.removeCAM2.clicked.connect(self.removeAreaCAM2) self.drawCAM3.clicked.connect(self.startDrawAreaCAM3) self.removeCAM3.clicked.connect(self.removeAreaCAM3) self.retranslateUi(Form) self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(Form) # All function # Function retranslateUI def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.CAM1.setText(_translate("Form", "IP CAM 1")) self.startCAM1.setText(_translate("Form", "Start")) self.carProtectionCAM1.setText(_translate("Form", "Car protection")) self.monitorAreaCAM1.setText( _translate("Form", "Monitor prohibited area")) self.stopCAM1.setText(_translate("Form", "Stop")) self.personSearchingCAM1.setText(_translate("Form", "Person searching")) self.illegalCAM1.setText(_translate("Form", "Illegal access action")) self.CAM2.setText(_translate("Form", "IP CAM 2")) self.startCAM2.setText(_translate("Form", "Start")) self.carProtectionCAM2.setText(_translate("Form", "Car protection")) self.monitorAreaCAM2.setText( _translate("Form", "Monitor prohibited area")) self.stopCAM2.setText(_translate("Form", "Stop")) self.personSearchingCAM2.setText(_translate("Form", "Person searching")) self.illegalCAM2.setText(_translate("Form", "Illegal access action")) self.CAM3.setText(_translate("Form", "IP CAM 3")) self.startCAM3.setText(_translate("Form", "Start")) self.carProtectionCAM3.setText(_translate("Form", "Car protection")) self.monitorAreaCAM3.setText( _translate("Form", "Monitor prohibited area")) self.stopCAM3.setText(_translate("Form", "Stop")) self.personSearchingCAM3.setText(_translate("Form", "Person searching")) self.illegalCAM3.setText(_translate("Form", "Illegal access action")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "3 IP CAMs")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "PLAY RECORD")) self.CAM1_draw.setText(_translate("Form", "TextLabel")) self.drawCAM1.setText(_translate("Form", "Draw")) self.removeCAM1.setText(_translate("Form", "Clear")) self.CAM2_draw.setText(_translate("Form", "TextLabel")) self.drawCAM2.setText(_translate("Form", "Draw")) self.removeCAM2.setText(_translate("Form", "Clear")) self.CAM3_draw.setText(_translate("Form", "TextLabel")) self.drawCAM3.setText(_translate("Form", "Draw")) self.removeCAM3.setText(_translate("Form", "Clear")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("Form", "SETTING")) # Function for media player def open_file(self): filename, _ = QFileDialog.getOpenFileName(self, "Open Video") if filename != '': self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.playBtn.setEnabled(True) def play_video(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def stop_video(self): self.mediaPlayer.stop() def mediastate_changed(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def position_changed(self, position): self.slider.setValue(position) def duration_changed(self, duration): self.slider.setRange(0, duration) def set_position(self, position): self.mediaPlayer.setPosition(position) print(position) def set_volume(self, volume): self.mediaPlayer.setVolume(volume) def mute(self): if not self.mediaPlayer.isMuted(): self.mediaPlayer.setMuted(True) self.volumeBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaVolumeMuted)) else: self.mediaPlayer.setMuted(False) self.volumeBtn.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume)) def handle_errors(self): self.playBtn.setEnabled(False) self.label.setText("Error: " + self.mediaPlayer.errorString()) self.startCAM1.clicked.connect(self.start) self.stopCAM1.clicked.connect(self.stop) def fullscreen(self): if self.windowState() & Qt.WindowFullScreen: QApplication.setOverrideCursor(Qt.ArrowCursor) self.showNormal() print("no Fullscreen") else: Form.showFullScreen() QApplication.setOverrideCursor(Qt.BlankCursor) print("Fullscreen entered") def fast(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() + 10 * 60) def slow(self): self.mediaPlayer.setPosition(self.mediaPlayer.position() - 10 * 60) # Function for image processing def image_to_QImage(self, image, label: QLabel): image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = cv2.resize(image, (label.width(), label.height())) height, width, channel = image.shape step = channel * width return QImage(image.data, width, height, step, QImage.Format_RGB888) def start_view1(self): self.stopCAM1.setEnabled(True) self.startCAM1.setEnabled(False) self.vs1 = VideoStream(src=IP_CAM_ADDRESS['CAM1']) self.flag_CAM1 = self.vs1.flag if self.vs1.flag: self.vs1.start() now = datetime.now() self.savePath1 = self.createDir('IP_CAM_1') self.startTime1 = str(now.day) + ' - ' + str(now.hour) + 'h' + str( now.minute) + ' - ' fourcc = cv2.VideoWriter_fourcc(*'XVID') self.outVivdeo = cv2.VideoWriter( self.savePath1 + 'output.avi', fourcc, 30, (int(self.vs1.stream.get(3)), int(self.vs1.stream.get(4)))) self.timer.start(20) else: self.startCAM1.setEnabled(True) self.stopCAM1.setEnabled(False) image = cv2.imread('no-connection.jpg') self.CAM1.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) def viewCam1(self): image = self.vs1.read() self.outVivdeo.write(image) self.CAM1.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) if self.feature['mpa1'] and self.monitorAreaCAM1.isChecked(): image, self.numWarning = detectObject(image, self.points_CAM1, flag_Warning=1, numWarning=self.numWarning) self.CAM1_draw.setPixmap( QPixmap.fromImage( self.image_to_QImage( self.drawArea(image, self.points_CAM1, self.CAM1_draw), self.CAM1_draw))) def stop_view1(self): self.startCAM1.setEnabled(True) self.stopCAM1.setEnabled(False) self.timer.stop() self.vs1.stop() image = cv2.imread('stopVideo.png') self.CAM1.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) now = datetime.now() fileName = self.startTime1 + str(now.hour) + 'h' + str( now.minute) + '.avi' os.rename(self.savePath1 + 'output.avi', self.savePath1 + fileName) def start_view2(self): self.stopCAM2.setEnabled(True) self.startCAM2.setEnabled(False) self.vs2 = VideoStream(src=IP_CAM_ADDRESS['CAM2']) print('ok') if self.vs2.flag: self.vs2.start() now = datetime.now() self.savePath2 = self.createDir('IP_CAM_2') self.startTime2 = str(now.day) + ' - ' + str(now.hour) + 'h' + str( now.minute) + ' - ' fourcc = cv2.VideoWriter_fourcc(*'XVID') self.outVivdeo2 = cv2.VideoWriter( self.savePath2 + 'output2.avi', fourcc, 30, (int(self.vs2.stream.get(3)), int(self.vs2.stream.get(4)))) self.timer2.start(20) else: self.startCAM2.setEnabled(True) self.stopCAM2.setEnabled(False) image = cv2.imread('no-connection.jpg') self.CAM2.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) def viewCam2(self): image = self.vs2.read() self.outVivdeo2.write(image) self.CAM2.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) def stop_view2(self): self.startCAM2.setEnabled(True) self.stopCAM2.setEnabled(False) self.timer2.stop() self.vs2.stop() image = cv2.imread('stopVideo.png') self.CAM2.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) now = datetime.now() fileName = self.startTime2 + str(now.hour) + 'h' + str( now.minute) + '.avi' os.rename(self.savePath2 + 'output2.avi', self.savePath2 + fileName) # def viewCam(self): # # while True: # ret, image = self.cap.read() # self.outVivdeo.write(image) # self.CAM1.setPixmap(QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) # if self.feature['mpa1'] and self.monitorAreaCAM1.isChecked(): # image, self.numWarning = detectObject(image, self.points_CAM1, flag_Warning=1, numWarning=self.numWarning) # self.CAM1_draw.setPixmap(QPixmap.fromImage(self.image_to_QImage(self.drawArea(image, self.points_CAM1, self.CAM1_draw), self.CAM1_draw))) # def start_view(self): # self.stopCAM1.setEnabled(True) # self.startCAM1.setEnabled(False) # self.cap = cv2.VideoCapture(IP_CAM_ADDRESS['CAM1']) # self.flag_CAM1 = self.cap.isOpened() # if self.cap.isOpened(): # now = datetime.now() # self.savePath1 = self.createDir('IP_CAM_1') # self.startTime1 = str(now.day)+' - '+str(now.hour)+'h'+str(now.minute)+ ' - ' # fourcc = cv2.VideoWriter_fourcc(*'XVID') # self.outVivdeo = cv2.VideoWriter(self.savePath1+'output.avi', fourcc, 30, (int(self.cap.get(3)), int(self.cap.get(4)))) # self.timer.start(0) # else: # self.startCAM1.setEnabled(True) # self.stopCAM1.setEnabled(False) # image = cv2.imread('no-connection.jpg') # self.CAM1.setPixmap(QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) # def stop_view(self): # self.startCAM1.setEnabled(True) # self.stopCAM1.setEnabled(False) # self.timer.stop() # self.cap.release() # self.outVivdeo.release() # print("ok") # image = cv2.imread('stopVideo.png') # self.CAM1.setPixmap(QPixmap.fromImage(self.image_to_QImage(image, self.CAM1))) # print('ok2') # now = datetime.now() # fileName = self.startTime1+str(now.hour)+'h'+str(now.minute)+'.avi' # os.rename(self.savePath1+'output.avi', self.savePath1+fileName) # def viewCam2(self): # ret, image = self.cap2.read() # self.outVivdeo2.write(image) # self.CAM2_draw.setPixmap(QPixmap.fromImage(self.image_to_QImage(self.drawArea(image, self.points_CAM2, self.CAM2_draw), self.CAM2_draw))) # self.CAM2.setPixmap(QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) # def start_view2(self): # if not self.timer2.isActive(): # self.stopCAM2.setEnabled(True) # self.startCAM2.setEnabled(False) # self.cap2 = cv2.VideoCapture(IP_CAM_ADDRESS['CAM2']) # self.flag_CAM2 = self.cap2.isOpened() # if self.cap2.isOpened(): # now = datetime.now() # self.savePath2 = self.createDir('IP_CAM_2') # self.startTime2 = str(now.day)+' - '+str(now.hour)+'h'+str(now.minute)+ ' - ' # # fourcc = cv2.VideoWriter_fourcc(*'mp4v') # fourcc = cv2.VideoWriter_fourcc(*'XVID') # self.outVivdeo2 = cv2.VideoWriter(self.savePath2+'output2.avi', fourcc, 30, (int(self.cap2.get(3)), int(self.cap2.get(4)))) # self.timer2.start(0) # else: # self.startCAM2.setEnabled(True) # self.stopCAM2.setEnabled(False) # image = cv2.imread('no-connection.jpg') # self.CAM2.setPixmap(QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) # def stop_view2(self): # self.startCAM2.setEnabled(True) # self.stopCAM2.setEnabled(False) # self.timer2.stop() # self.outVivdeo2.release() # image = cv2.imread('stopVideo.png') # self.CAM2.setPixmap(QPixmap.fromImage(self.image_to_QImage(image, self.CAM2))) # self.cap2.release() # now = datetime.now() # fileName = self.startTime2+str(now.hour)+'h'+str(now.minute)+'.avi' # os.rename(self.savePath2+'output2.avi', self.savePath2+fileName) def viewCam3(self): ret, image = self.cap3.read() self.outVivdeo3.write(image) self.CAM3_draw.setPixmap( QPixmap.fromImage( self.image_to_QImage( self.drawArea(image, self.points_CAM3, self.CAM3_draw), self.CAM3_draw))) self.CAM3.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM3))) def start_view3(self): if not self.timer3.isActive(): self.stopCAM3.setEnabled(True) self.startCAM3.setEnabled(False) self.cap3 = cv2.VideoCapture(IP_CAM_ADDRESS['CAM3']) self.flag_CAM3 = self.cap3.isOpened() if self.cap3.isOpened(): now = datetime.now() self.savePath3 = self.createDir('IP_CAM_3') self.startTime3 = str(now.day) + ' - ' + str( now.hour) + 'h' + str(now.minute) + ' - ' # fourcc = cv2.VideoWriter_fourcc(*'mp4v') fourcc = cv2.VideoWriter_fourcc(*'XVID') self.outVivdeo3 = cv2.VideoWriter( self.savePath3 + 'output3.avi', fourcc, 30, (int(self.cap3.get(3)), int(self.cap3.get(4)))) self.timer3.start(0) else: self.startCAM3.setEnabled(True) self.stopCAM3.setEnabled(False) image = cv2.imread('no-connection.jpg') self.CAM3.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM3))) def stop_view3(self): self.startCAM3.setEnabled(True) self.stopCAM3.setEnabled(False) self.timer3.stop() self.outVivdeo3.release() image = cv2.imread('stopVideo.png') self.CAM3.setPixmap( QPixmap.fromImage(self.image_to_QImage(image, self.CAM3))) self.cap3.release() now = datetime.now() fileName = self.startTime3 + str(now.hour) + 'h' + str( now.minute) + '.avi' os.rename(self.savePath3 + 'output3.avi', self.savePath3 + fileName) def createDir(self, IP_CAM_Number: str): now = datetime.now() year = now.year month = MONTH[now.month] curPath = os.getcwd() if not path.exists(curPath + '/IVA'): os.mkdir(curPath + '/IVA') if not path.exists(curPath + '/IVA/' + IP_CAM_Number): os.mkdir(curPath + '/IVA/' + IP_CAM_Number) # check path exists if path.exists(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year)): if path.exists(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month): return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' else: os.mkdir(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month) return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' else: os.mkdir(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year)) if path.exists(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month): return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' else: os.mkdir(curPath + '/IVA/' + IP_CAM_Number + '/' + str(year) + '/' + month) return curPath + '/IVA/' + IP_CAM_Number + '/' + str( year) + '/' + month + '/' # Create Mouse Event for draw protected area def mouseEventCAM1(self, event): if self.removeCAM1.isEnabled() and ( not self.startCAM1.isEnabled()) and self.flag_CAM1 == True: # print(self.CAM1_draw.width(), self.CAM1_draw.height()) x = event.pos().x() y = event.pos().y() print(x, y) x = round((x / self.CAM1_draw.width()), 10) y = round((y / self.CAM1_draw.height()), 10) self.points_CAM1.append([x, y]) print("Position clicked is ({}, {})".format( int(x * self.CAM1_draw.width()), int(y * self.CAM1_draw.height()))) # print(self.points_CAM1) def mouseEventCAM2(self, event): if self.removeCAM2.isEnabled() and ( not self.startCAM2.isEnabled()) and self.flag_CAM2 == True: x = event.pos().x() y = event.pos().y() self.points_CAM2.append([x, y]) print("Position clicked is ({}, {})".format(x, y)) def mouseEventCAM3(self, event): if self.removeCAM3.isEnabled() and ( not self.startCAM3.isEnabled()) and self.flag_CAM3 == True: x = event.pos().x() y = event.pos().y() self.points_CAM3.append([x, y]) print("Position clicked is ({}, {})".format(x, y)) def startDrawAreaCAM1(self): self.drawCAM1.setEnabled(False) self.removeCAM1.setEnabled(True) def removeAreaCAM1(self): while len(self.points_CAM1): self.points_CAM1.pop() self.drawCAM1.setEnabled(True) self.removeCAM1.setEnabled(False) def startDrawAreaCAM2(self): self.drawCAM2.setEnabled(False) self.removeCAM2.setEnabled(True) def removeAreaCAM2(self): while len(self.points_CAM2): self.points_CAM2.pop() self.drawCAM2.setEnabled(True) self.removeCAM2.setEnabled(False) def startDrawAreaCAM3(self): self.drawCAM3.setEnabled(False) self.removeCAM3.setEnabled(True) def removeAreaCAM3(self): while len(self.points_CAM3): self.points_CAM3.pop() self.drawCAM3.setEnabled(True) self.removeCAM3.setEnabled(False) def drawArea(self, image, points: list, qlabel: QtWidgets.QLabel): image_draw = image.copy() (width, height) = image.shape[:2] image_draw = cv2.resize(image_draw, (qlabel.width(), qlabel.height())) if len(points) > 1: point1 = [] for point in points: x = int(point[0] * qlabel.width()) y = int(point[1] * qlabel.height()) point1.append((x, y)) cv2.polylines(image_draw, np.array([point1]), 1, (255, 0, 0), 1) b, g, r = cv2.split(image_draw) cv2.fillPoly(b, np.array([point1]), (0, 255, 0)) cv2.fillPoly(r, np.array([point1]), (0, 255, 0)) image_draw = cv2.merge([b, g, r]) return image_draw # Function for IVA tasks def monitorProhibitedArea(self, frame, points: list, flag_Warning: int): pass
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 EventAction(): def __init__(self): #self.parent = parent self.isLoop = 0 #0循环列表,1单曲循环 self.isRandom = 0 #0不随机,1随机 self.fileList = [] #曲目名称列表 self.randomList =[] #播放列表 self.soundID = 0 #当前歌曲ID self.playStat = False #当前播放状态 (0未播放,1播放) self.openPath = "F:/mp3/" #歌曲目录 self.isPreview = 0 #试用开关,0正常播放,1列表中的歌曲每首歌曲放10秒 self.currentVolume = 0.1#默认的起始音量 self.isInitPlay = 1 #是否是初始播放 #==>>打开目录 self.config=configparser.ConfigParser() self.config.read('config.ini') self.openDir() #打开目录<<== self.playObj = QMediaPlayer() self.currentImg = "" #当前图片 self.songText = {} #歌词 self.songTextKey=[] #歌词KEY #打开歌曲目录 def openDir(self): self.openPath = self.config.get('Save','musicPath') isMusicDir = os.path.isdir(self.openPath)#检查是否为目录 if isMusicDir: dirFile = os.listdir(self.openPath)#目录中的所有文件 #遍历有效音乐文件 i=0; for file in dirFile: fileName,fileType=os.path.splitext(file) if fileType==".mp3" or fileType==".wav": self.fileList.append(file) self.randomList.append(i) i+=1 if self.isRandom==1: self.shuffleMusic(1) #随机(打乱播放顺序) def shuffleMusic(self,isshuffle): if isshuffle: random.shuffle(self.randomList)#乱序 else: self.randomList.sort()#排序 #初始化播放 def initPlay(self): self.soundID = int(self.config.get('Save','soundID')) self.playStat = self.config.get('Save','playStat') self.pastTime = self.config.getint('Save','pastTime') self.currentVolume = self.config.getint('Save','volume') self.isRandom = self.config.getint('Save','isRandom') self.isLoop = self.config.getint('Save','isLoop') if self.soundID!="": self.play(self.soundID) if self.isRandom:#打乱列表 self.shuffleMusic(1) self.playObj.setVolume(self.currentVolume) #播放 def play(self,i): source = self.openPath + self.fileList[i] self.playObj.setMedia(QMediaContent(QUrl.fromLocalFile(source))) #解析文件中的ID3V2 self.currentImg = "" f = QFile(source) if f.open(QIODevice.ReadOnly): #读取标签 headData = f.read(10) data = headData[:0] if self.id3v2(headData):#检测是否有ID3 #标签的大小计算 tag = headData[6:10] tagSize = (tag[0]&0x7f)*0x200000+(tag[1]&0x7f)*0x4000+(tag[2]&0x7f)*0x80+(tag[3]&0x7f) data =f.read(tagSize) while len(data)>10: data = self.resolve(data) f.close() self.playObj.play() def testPlay(self): #ps =QMediaMetaData() #print("QMediaMetaData",ps) #print("metaData",self.playObj.metaData(QMediaMetaData.Title)) #print("position",self.playObj.position()) #print("playlist",self.playObj.playlist) #print("availability",self.playObj.availability()) #print("bufferStatus",self.playObj.bufferStatus()) #print("currentMedia",self.playObj.currentMedia()) #print("currentNetworkConfiguration",self.playObj.currentNetworkConfiguration()) #print("duration",self.playObj.duration()) #print("error",self.playObj.error()) #print("errorString",self.playObj.errorString()) #print("isAudioAvailable",self.playObj.isAudioAvailable()) #print("isMuted",self.playObj.isMuted()) #print("isSeekable",self.playObj.isSeekable()) #print("media",self.playObj.media()) #print("media:::::::A",self.playObj.media().canonicalResource().audioBitRate()) #print("media:::::::B",self.playObj.media().canonicalResource().audioCodec()) #print("media:::::::C",self.playObj.media().canonicalResource().channelCount()) #print("media:::::::D",self.playObj.media().canonicalResource().dataSize()) #print("media:::::::e",self.playObj.media().canonicalResource().isNull()) #print("media:::::::f",self.playObj.media().canonicalResource().language()) #print("media:::::::g",self.playObj.media().canonicalResource().mimeType()) #print("media:::::::h",self.playObj.media().canonicalResource().request()) #print("isVideoAvailable",self.playObj.isVideoAvailable()) #print("mediaStatus",self.playObj.mediaStatus()) #print("mediaStream",self.playObj.mediaStream()) #print("playbackRate",self.playObj.playbackRate()) #print("state",self.playObj.state()) #print("volume",self.playObj.volume()) # print("volume",self.playObj.filename) pass #换歌之前先停止,释放内存 def stopPlay(self): self.playObj.pause() #上一首 def prevPlay(self): self.stopPlay() if self.isRandom: key = self.searchID(self.soundID)-1 if key<0: key=0 self.soundID = self.randomList[key] else: self.soundID-=1 if self.soundID< 0: self.soundID = len(self.randomList)-1 self.play(self.soundID) #下一首 def nextPlay(self): self.stopPlay() if self.isRandom: key = self.searchID(self.soundID)+1 if key>(len(self.randomList)-1): key=len(self.randomList)-1 self.soundID = self.randomList[key] else: self.soundID+=1 if self.soundID > (len(self.randomList)-1): self.soundID = 0 #print("next:::",self.soundID) self.play(self.soundID) #快退 def rewindPlay(self): #print("<<") rewindTime = int(self.playObj.position()) - 10*1000 if rewindTime < 0: rewindTime = 0 self.playObj.setPosition(rewindTime) #快进 def forwardPlay(self): #print(">>") forwardTime = int(self.playObj.position()) + 10*1000 if forwardTime > int(self.playObj.duration()): forwardTime = int(self.playObj.duration()) self.playObj.setPosition(forwardTime) #播放/暂停 def playORpause(self): if self.playObj.state()==1: self.playObj.pause() else: self.playObj.play() #音量加 def raisevolPlay(self): self.playObj.setVolume(self.playObj.volume()+10) self.currentVolume = self.playObj.volume() #音量减 def lowervolPlay(self): self.playObj.setVolume(self.playObj.volume()-10) self.currentVolume = self.playObj.volume() #静音 def mutePlay(self): if self.playObj.isMuted(): self.playObj.setMuted(False) else: self.playObj.setMuted(True) #volume #跟据v找K def searchID(self,v): for index, item in enumerate(self.randomList): if item ==v: return index return 0 #解析文件中是否有id3v2 def id3v2(self,headData): if str(headData[:3],encoding=("utf-8")) != "ID3": return False return True #解析文件中的歌词与图片 def resolve(self,data): tagName = str(data[:4],encoding=("utf-8")) size = data[4:8] #sizeS = size[0]*0x1000000 + size[1]*0x10000 + size[2]*0x100 + size[3] sizeS=int.from_bytes(size, byteorder='big') flags = data[8:10] tagContent = data[10:sizeS+10] if tagName=="TEXT":#歌词 #print("歌词") condingType=int.from_bytes(tagContent[:1], byteorder='big') if condingType == 0:#0代表字符使用ISO-8859-1编码方式; try: content = str(tagContent[1:],encoding="gbk") except: content ="" elif condingType == 1:#1代表字符使用UTF-16编码方式; try: content = str(tagContent[1:],encoding="UTF-16") except: content ="" elif condingType == 2:#2代表字符使用 UTF-16BE编码方式; content ="" elif condingType == 3:#3代表字符使用UTF-8编码方式。 try: content = str(tagContent[1:],encoding="UTF-8") except: content ="" if content!="": temp={} self.songTextKey=[] contentSplit = content.splitlines() for k in range(len(contentSplit)): if contentSplit[k][1].isdigit(): xxx = contentSplit[k].split("]") tempKey = "%d" %(int(xxx[0][1:3])*60 +int(xxx[0][4:6]) ) temp[str(tempKey)] = xxx[1] self.songTextKey.append(tempKey) else: endKey = contentSplit[k].find("]",0) self.songTextKey.append(k) temp[str(k)] = contentSplit[k][1:endKey] self.songText = temp else: self.songText = {} elif tagName=="APIC":#图片 #print("图片") self.currentImg = tagContent[17:] return data[10+sizeS:]
class videoPlayer(QWidget): # 视频播放类 def __init__(self, parent=None): # 构造函数 super(videoPlayer, self).__init__(parent=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 MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setupUi(self) self.player = QMediaPlayer() self.player.error.connect(self.erroralert) self.player.play() self.player.stateChanged.connect(self.Set_Icons) # self.player.volumeChanged.connect(self.prev_volume) # Connect control buttons/slides for media player. self.playButton.pressed.connect(self.play_pause) self.stopButton.pressed.connect(self.player.stop) self.showButton.pressed.connect(self.playlist_toggle) self.equalizerButton.pressed.connect(self.ShowEqualizer) self.volumeButton.pressed.connect(self.mute) self.volumeSlider.valueChanged.connect(self.volumeChanged) self.currentVolume = self.volumeSlider.value() self.timeSlider.valueChanged.connect(self.player.setPosition) # Setup the playlist. self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.model = PlaylistModel(self.playlist) self.listWidget.setModel(self.model) self.playlist.currentIndexChanged.connect( self.playlist_position_changed) selection_model = self.listWidget.selectionModel() selection_model.selectionChanged.connect( self.playlist_selection_changed) self.player.durationChanged.connect(self.update_duration) self.player.positionChanged.connect(self.update_position) self.actionOpen_File.triggered.connect(self.open_file) self.files = [] self.setAcceptDrops(True) self.graphWidget.setBackground((60, 60, 60)) self.graphWidget.GetViewBox().setMenuEnabled(False) self.graphWidget.GetViewBox().setMouseEnabled(x=False, y=False) self.graphWidget.setPlotEQ((42, 130, 218)) self.Visualizer = FFTAnalyser(self.player) self.Visualizer.calculated_visual.connect(self.draw) self.Visualizer.start() self.Equalizer = QWidget() self.visdata = np.array([]) self.show() def draw(self, visdata): self.visdata = np.array(visdata) self.graphWidget.UpdatePlotEQ(self.visdata) def dragEnterEvent(self, e): if e.mimeData().hasUrls(): e.acceptProposedAction() def play_pause(self): if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def Set_Icons(self, state): if state == QMediaPlayer.StoppedState: self.stopButton.setIcon( qta.icon('fa5s.stop-circle', active='fa5s.stop-circle', color='white', color_active='grey')) self.playButton.setIcon(qta.icon('fa5s.play-circle', color='white')) self.playButton.setToolTip('Play') elif state == QMediaPlayer.PlayingState: self.playButton.setIcon( qta.icon('fa5s.pause-circle', color='white')) self.playButton.setToolTip('Pause') elif state == QMediaPlayer.PausedState: self.playButton.setIcon(qta.icon('fa5s.play-circle', color='white')) self.playButton.setToolTip('Play') def playlist_toggle(self): if self.listWidget.isHidden(): self.listWidget.setHidden(False) self.listWidget.setProperty("showDropIndicator", True) self.showButton.setIcon(qta.icon('fa5s.eye-slash', color='white')) self.showButton.setToolTip('Hide Playlist') else: self.listWidget.setHidden(True) self.listWidget.setProperty("showDropIndicator", False) self.showButton.setIcon(qta.icon('fa5s.list-ul', color='white')) self.showButton.setToolTip('Show Playlist') def dropEvent(self, e): for url in e.mimeData().urls(): self.playlist.addMedia(QMediaContent(url)) self.model.layoutChanged.emit() # If not playing, seeking to first of newly added + play. if self.player.state() != QMediaPlayer.PlayingState: i = self.playlist.mediaCount() - len(e.mimeData().urls()) self.playlist.setCurrentIndex(i) self.player.play() def open_file(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "Music Files (*.mp3 *.wav)", options=options) if path: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(path))) self.files.append(QMediaContent(QUrl.fromLocalFile(path))) self.model.layoutChanged.emit() # def contextMenuEvent(self, event): # contextMenu = QMenu(self) # graph = contextMenu.addAction("Show Graph") def update_duration(self, duration): print("!", duration) print("?", self.player.duration()) self.timeSlider.setMaximum(duration) if duration >= 0: self.totalTimeLabel.setText(hhmmss(duration)) def update_position(self, position): if position >= 0: self.currentTimeLabel.setText(hhmmss(position)) self.timeSlider.blockSignals(True) self.timeSlider.setValue(position) self.timeSlider.blockSignals(False) def playlist_selection_changed(self, ix): i = ix.indexes()[0].row() self.playlist.setCurrentIndex(i) def playlist_position_changed(self, i): if i > -1: ix = self.model.index(i) self.listWidget.setCurrentIndex(ix) def erroralert(self, *args): print(args) def ShowEqualizer(self): if self.player.currentMedia().canonicalUrl().path() != "": self.Equalizer = WindowingWidget( self.player.currentMedia().canonicalUrl().path()) self.Equalizer.SendPath.connect(self.AddPathToPlaylist) self.Equalizer.show() def AddPathToPlaylist(self, path): if path: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(path))) self.files.append(path) self.model.layoutChanged.emit() def volumeChanged(self): self.currentVolume = self.volumeSlider.value() self.player.setVolume(self.volumeSlider.value()) def mute(self): if self.player.isMuted(): self.player.setMuted(False) self.volumeButton.setIcon(qta.icon('fa5s.volume-up', color='white')) self.volumeButton.setToolTip('Mute') self.volumeSlider.setEnabled(True) else: self.player.setMuted(True) self.volumeButton.setIcon( qta.icon('fa5s.volume-mute', color='white')) self.volumeButton.setToolTip('Unmute') self.volumeSlider.setEnabled(False) def closeEvent(self, event): self.Visualizer.terminate() if self.Equalizer.isVisible(): self.Equalizer.close()
class Player(QMediaPlayer): player = None # 播放器 playList = None # 播放列表 source = None # 音频路径 content = None # 音频内容 musicSource = [] # 音频路劲列表 MUSIC_PATH = './BackgroundMusic' def __init__(self, parent=None): super(Player, self).__init__(parent) self.getMusicSource() self.initPlayer() self.createPlayList() self.player.play() def getMusicSource(self): """获取音乐文件路径""" for src in os.listdir(self.MUSIC_PATH): self.musicSource.append('{}/{}'.format(self.MUSIC_PATH, src)) def initPlayer(self): """初始化播放器""" self.player = QMediaPlayer(self) # 创建播放器 self.playList = QMediaPlaylist(self.player) # 播放列表 self.playList.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) # 播放模式 """ QMediaPlaylist.CurrentItemOnce 0->播放一次 QMediaPlaylist.CurrentItemInLoop 1->单曲循环 QMediaPlaylist.Sequential 2->顺序播放 QMediaPlaylist.Loop 3->列表循环 QMediaPlaylist.Random 4->随机播放 """ def createPlayList(self): """创建播放列表""" self.playList.clear() for path in self.musicSource: self.content = QMediaContent(QUrl.fromLocalFile(path)) self.playList.addMedia(self.content) self.player.setPlaylist(self.playList) # 创建播放列表 # print(self.player.currentMedia().canonicalUrl().path()) # 输出音乐文件路径 def nextMusic(self): """播放下一首音乐""" if self.playList.currentIndex() == len(self.musicSource) - 1: index = 0 else: index = self.playList.currentIndex() + 1 self.playList.setCurrentIndex(index) self.player.play() def previousMusic(self): """播放前一首音乐""" if self.playList.currentIndex() == 0: index = len(self.musicSource) - 1 else: index = self.playList.currentIndex() - 1 self.playList.setCurrentIndex(index) self.player.play() def mute(self): """静音""" self.player.setMuted(True) def cancelMute(self): """取消静音""" self.player.setMuted(False)
class MusicPlayer(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.options = self.parent().options self.ffmpeg = self.options['paths']['ffmpeg_bin'] self.thumbnails = self.options['paths']['thumbnails'] self.thumb_width = self.options['thumbnail']['width'] self.thumb_height = self.options['thumbnail']['height'] self.jumping = False self.blocked = False self.durations = {} self.playback_value = 0 self.text = ["None", "Repeat", "Random"] self.playlist_list = [] self.values = [ QMediaPlaylist.Loop, QMediaPlaylist.CurrentItemInLoop, QMediaPlaylist.Random ] # Thumbnail widget self.image_label = QLabel() # Control widgets self.playButton = QToolButton(clicked=self.play) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.stopButton = QToolButton(clicked=self.stop) self.stopButton.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.stopButton.setEnabled(False) self.playbackButton = QToolButton(clicked=self.playback_mode) self.playbackButton.setText(self.text[0]) self.nextButton = QToolButton(clicked=self.next_song) self.nextButton.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipForward)) self.previousButton = QToolButton(clicked=self.previous_song) self.previousButton.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipBackward)) self.muteButton = QToolButton(clicked=self.mute_clicked) self.muteButton.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume)) self.volumeSlider = QSlider(Qt.Horizontal, sliderMoved=self.change_volume) self.volumeSlider.setRange(0, 100) self.volumeSlider.setPageStep(1) self.volumeSlider.setValue(50) # Player and playlist setup self.player = QMediaPlayer() self.player.setVolume(50) self.player.stateChanged.connect(self.waveform) self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(self.values[0]) self.playlist.setCurrentIndex(1) self.player.setPlaylist(self.playlist) 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.playlistView.setContextMenuPolicy(Qt.CustomContextMenu) self.playlistView.customContextMenuRequested.connect( self.list_view_menu) self.playlist.currentIndexChanged.connect( lambda position: self.change_thumbnail(position)) song_search = QLineEdit() song_search.textChanged.connect(self.search) song_search.setClearButtonEnabled(True) # Playlist self.playlist_name = QComboBox() self.playlist_name.currentTextChanged.connect(self.switch_playlist) self.refresh_lists() self.up_button = QToolButton(clicked=self.move_up) self.up_button.setIcon(self.style().standardIcon(QStyle.SP_ArrowUp)) self.down_button = QToolButton(clicked=self.move_down) self.down_button.setIcon(self.style().standardIcon( QStyle.SP_ArrowDown)) # Sound wave widget self.wave_graphic = WaveGraphic(self) #self.wave_graphic.hide() # Testing slider again self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, self.player.duration() / 1000) self.slider.sliderMoved.connect(self.seek) self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) # Shortcuts QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self, song_search.setFocus) # Layouts setup playlist_layout = QHBoxLayout() playlist_layout.addWidget(self.playlist_name) playlist_layout.addWidget(self.up_button) playlist_layout.addWidget(self.down_button) control_layout = QHBoxLayout() control_layout.setContentsMargins(0, 0, 0, 0) control_layout.addWidget(self.stopButton) control_layout.addWidget(self.previousButton) control_layout.addWidget(self.playButton) control_layout.addWidget(self.nextButton) control_layout.addWidget(self.muteButton) control_layout.addWidget(self.volumeSlider) control_layout.addWidget(self.playbackButton) display_layout = QVBoxLayout() display_layout.addWidget(song_search) display_layout.addWidget(self.playlistView) display_layout.addLayout(playlist_layout) music_layout = QVBoxLayout() music_layout.addWidget(self.image_label) music_layout.addWidget(self.slider) music_layout.addLayout(control_layout) main_layout = QHBoxLayout() main_layout.addLayout(music_layout) main_layout.addLayout(display_layout) main_2_layout = QVBoxLayout() main_2_layout.addLayout(main_layout) main_2_layout.addWidget(self.wave_graphic) self.setLayout(main_2_layout) def waveform(self, status): if status == QMediaPlayer.PlayingState: self.wave_graphic.start() elif status == QMediaPlayer.PausedState: self.wave_graphic.pause() else: self.wave_graphic.stop() def list_view_menu(self, point): menu = QMenu("Menu", self) recommend_action = QAction('&Recommend Songs', self) menu.addAction(recommend_action) # TODO: [FEATURE] add rename song recommend_action.triggered.connect( lambda: self.parent().call_download_manager(self.get_links())) rename_action = QAction('&Rename', self) menu.addAction(rename_action) # TODO: [FEATURE] add rename song rename_action.triggered.connect(lambda: print("rename")) # Show the context menu. menu.exec_(self.playlistView.mapToGlobal(point)) def get_links(self): title = self.playlistView.selectedIndexes()[0].data() link = getYoutubeURLFromSearch(title) if len(link) > 1: return youtube_recommendations(link) def move_up(self): index = self.playlistView.currentIndex().row() if index - 1 >= 0: item, above = self.playlist.media(index), self.playlist.media( index - 1) self.playlist.removeMedia(index) self.playlist.removeMedia(index - 1) self.playlist.insertMedia(index - 1, item) self.playlist.insertMedia(index, above) self.blocked = True self.playlistView.setCurrentIndex( self.playlistModel.index(index - 1, 0)) self.blocked = False self.stop() def move_down(self): index = self.playlistView.currentIndex().row() if index + 1 <= self.playlistModel.rowCount(): item, below = self.playlist.media(index), self.playlist.media( index + 1) self.playlist.removeMedia(index + 1) self.playlist.removeMedia(index) self.playlist.insertMedia(index, below) self.playlist.insertMedia(index + 1, item) self.blocked = True self.playlistView.setCurrentIndex( self.playlistModel.index(index + 1, 0)) self.blocked = False self.stop() def search(self, part_of_song): for index in range(self.playlistModel.rowCount()): item = self.playlistModel.data(self.playlistModel.index( index, 0)).lower() self.playlistView.setRowHidden(index, part_of_song.lower() not in item) def change_thumbnail(self, position=0): self.playlistView.setCurrentIndex(self.playlistModel.index( position, 0)) song = self.playlistView.selectedIndexes()[0].data() if self.wave_graphic.is_song_cached(song): self.wave_graphic.load_waves(song) else: wc_ = WaveConverter(song, self.wave_graphic.set_wav) wc_.convert() if self.playlistView.currentIndex().data() is None or self.blocked: return max_ratio = 0 img = None for item in listdir(self.thumbnails): if item.endswith('.jpg'): ratio = similar( item, self.playlistView.currentIndex().data().replace( '.mp3', '.jpg')) if ratio > max_ratio: max_ratio = ratio img = item if img: p = QPixmap(self.thumbnails + img) self.image_label.setPixmap( p.scaled(self.thumb_width, self.thumb_height, Qt.KeepAspectRatio)) def switch_playlist(self, current_text): self.playlist.clear() if current_text == "No Playlist": self.refresh() else: if read_playlist(current_text): songs = read_playlist(current_text).split('\n') for song in songs: self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(song))) def refresh(self): # Change it so it will go to same song. if self.playlist_name.currentText() != "No Playlist": return paths = fetch_options()['paths']['music_path'].split(';') current_songs = [ self.playlistModel.data(self.playlistModel.index(row, 0)) for row in range(self.playlistModel.rowCount()) ] for path in paths: if not path: continue for item in listdir(path): if isfile(join(path, item)) and item.endswith(".mp3") and ( item not in current_songs): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(join(path, item)))) def refresh_lists(self): path = fetch_options()['paths']['playlist'] self.playlist_name.clear() self.playlist_list = ["No Playlist"] self.playlist_name.addItem("No Playlist") for item in listdir(path): if isfile(join(path, item)) and item.endswith(".lst"): self.playlist_list.append(item.split('.')[0]) self.playlist_name.addItem(item.split('.')[0]) def playback_mode(self): # Normal -> Loop -> Random def up_value(value, max_value=3): if value + 1 == max_value: return 0 return value + 1 self.playback_value = up_value(self.playback_value) self.playlist.setPlaybackMode(self.values[self.playback_value]) self.playbackButton.setText(self.text[self.playback_value]) def jump(self, index): if index.isValid() and not self.blocked: self.playlist.setCurrentIndex(index.row()) self.jumping = True self.play() def play(self): if self.blocked: return if self.player.state() != QMediaPlayer.PlayingState or self.jumping: self.player.play() self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.jumping = False else: self.player.pause() self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.stopButton.setEnabled(True) def change_volume(self, value): self.player.setVolume(value) def stop(self): if self.player.state() != QMediaPlayer.StoppedState: self.player.stop() self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.stopButton.setEnabled(False) def next_song(self): self.playlist.next() self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) def previous_song(self): self.playlist.previous() self.playlistView.setCurrentIndex( self.playlistModel.index(self.playlist.currentIndex(), 0)) def mute_clicked(self): self.player.setMuted(not self.player.isMuted()) self.muteButton.setIcon(self.style().standardIcon( QStyle.SP_MediaVolume if not self.player.isMuted() else QStyle. SP_MediaVolumeMuted)) def durationChanged(self, duration): duration /= 1000 self.slider.setMaximum(duration) def positionChanged(self, progress): progress /= 1000 if not self.slider.isSliderDown(): self.slider.setValue(progress) def seek(self, seconds): self.player.setPosition(seconds * 1000)
class IntroWindow(QMainWindow, Form): def __init__(self): Form.__init__(self) QMainWindow.__init__(self) self.setWindowIcon(QIcon("logo.png")) p = self.palette() p.setColor(QPalette.Window, Qt.gray) self.setPalette(p) self.setupUi(self) self.a = 1 self.videowidget = QVideoWidget() self.vertical.addWidget(self.videowidget) self.videoplayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoplayer.setVideoOutput(self.videowidget) self.sliderfilm.setRange(0, 0) self.volume.setRange(0, 100) self.videoplayer.setVolume(100) self.volume.setValue(100) self.play.setEnabled(False) self.increaseRate.setEnabled(False) self.decreaseRate.setEnabled(False) self.sliderfilm.installEventFilter(self) self.volume.installEventFilter(self) self.frames.installEventFilter(self) self.frame_2.installEventFilter(self) self.frames.installEventFilter(self) # putting Icons on buttons self.increaseRate.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekForward)) self.decreaseRate.setIcon(self.style().standardIcon( QStyle.SP_MediaSeekBackward)) self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.open.setIcon(self.style().standardIcon(QStyle.SP_DirHomeIcon)) self.skipforward.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipForward)) self.skipback.setIcon(self.style().standardIcon( QStyle.SP_MediaSkipBackward)) self.stop.setIcon(self.style().standardIcon(QStyle.SP_MediaStop)) self.sliderfilm.sliderMoved.connect(self.setpos) self.videoplayer.positionChanged.connect(self.position) self.videoplayer.durationChanged.connect(self.changed) self.videoplayer.volumeChanged.connect(self.setvolpos) self.volume.sliderMoved.connect(self.setvolpos) self.actionOpen.triggered.connect(self.Loadvideo) self.actionSearch_By_Tag.triggered.connect(self.opensecond) self.actionFullscreen.triggered.connect(self.screen) self.skipforward.clicked.connect(self.skipforw) self.skipback.clicked.connect(self.skipbac) self.increaseRate.clicked.connect(self.incRate) self.decreaseRate.clicked.connect(self.decRate) self.play.clicked.connect(self.play_video) self.open.clicked.connect(lambda: self.Loadvideo(self.videoplayer)) self.stop.clicked.connect(self.stopp) self.listView.hide() self.tolfilm = 0 self.listviewstatus = 0 self.listbtn.clicked.connect(lambda: self.list()) self.listView.itemClicked.connect(self.listwidgetclicked) self.theme1.triggered.connect(lambda: self.theme01()) self.theme2.triggered.connect(lambda: self.theme02()) self.theme3.triggered.connect(lambda: self.theme03()) self.theme4.triggered.connect(lambda: self.theme04()) self.actionFarsi.triggered.connect(lambda: self.farsi()) self.actionEnglish.triggered.connect(lambda: self.english()) self.filename = "" self.x = 0 self.videowidget3 = QVideoWidget() self.verticalLayout_8.addWidget(self.videowidget3) self.videoplayer3 = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoplayer3.setVideoOutput(self.videowidget3) self.widget.hide() self.stop.setEnabled(False) self.m = 0 self.dataL = [] with open("config.txt") as f: self.config = f.read() if int(self.config) == 11: self.theme01() self.farsi() if int(self.config) == 12: self.theme01() self.english() elif int(self.config) == 21: self.farsi() self.theme02() elif int(self.config) == 22: self.english() self.theme02() elif int(self.config) == 31: self.farsi() self.theme03() elif int(self.config) == 32: self.english() self.theme03() elif int(self.config) == 41: self.farsi() self.theme04() elif int(self.config) == 42: self.english() self.theme04() def farsi(self): self.menuLanguage.setTitle("زبان") self.menuView.setTitle("نمایش") self.theme1.setText("تم ۱") self.theme2.setText("تم ۲") self.theme3.setText("تم ۳") self.theme4.setText("تم ۴") self.menuFile.setTitle("فایل") self.actionOpen.setText("باز کردن ویدیو") self.actionSearch_By_Tag.setText("پنل تگ ها") self.actionFullscreen.setText("تمام صفحه") self.actionEnglish.setText("انگلیسی") self.actionFarsi.setText("فارسی") self.decreaseRate.setStatusTip("کاهش سرعت") self.decreaseRate.setToolTip("کاهش سرعت") self.increaseRate.setStatusTip("افزایش سرعت") self.increaseRate.setToolTip("افزایش سرعت") self.open.setStatusTip("باز کردن ویدیو") self.open.setToolTip("باز کردن ویدیو") self.stop.setStatusTip("توقف") self.stop.setToolTip("توقف") self.skipback.setStatusTip("عقب رفتن") self.skipback.setToolTip("عقب رفتن") self.play.setStatusTip("شروع/ایست") self.play.setToolTip("شروع/ایست") self.skipforward.setStatusTip("جلو رفتن") self.skipforward.setToolTip("جلو رفتن") self.volume.setStatusTip("صدا") self.volume.setToolTip("صدا") self.listbtn.setStatusTip("دسترسی آسان") self.listbtn.setToolTip( "پنلی شامل تگ ها و پنجره ای برای پیش نمایش را نمایان/پنهان میکند که با کلیک کردن بر روی هر کدام ویدیو به آن لحظه میرود" ) with open("config.txt") as f: self.config = f.read() if int(self.config) // 10 == 1: with open("config.txt", "w") as f2: f2.write("11") if int(self.config) // 10 == 2: with open("config.txt", "w") as f2: f2.write("21") if int(self.config) // 10 == 3: with open("config.txt", "w") as f2: f2.write("31") if int(self.config) // 10 == 4: with open("config.txt", "w") as f2: f2.write("41") def english(self): self.menuLanguage.setTitle("Language") self.menuView.setTitle("View") self.theme1.setText("Theme1") self.theme2.setText("Theme2") self.theme3.setText("Theme3") self.theme4.setText("Theme4") self.menuFile.setTitle("File") self.actionOpen.setText("Open Video") self.actionSearch_By_Tag.setText("Tags Panel") self.actionFullscreen.setText("Fullscreen") self.actionEnglish.setText("English") self.actionFarsi.setText("Persian") self.decreaseRate.setStatusTip("Decrease Play Speed") self.decreaseRate.setToolTip("Decrease Play Speed") self.increaseRate.setStatusTip("Increase Play Speed") self.increaseRate.setToolTip("Increase Play Speed") self.open.setStatusTip("Open Video") self.open.setToolTip("Open Video") self.stop.setStatusTip("Stop") self.stop.setToolTip("Stop") self.skipback.setStatusTip("Previous") self.skipback.setToolTip("Previous") self.play.setStatusTip("Play/Pause") self.play.setToolTip("Play/Pause") self.skipforward.setStatusTip("Next") self.skipforward.setToolTip("Next") self.volume.setStatusTip("Volume") self.volume.setToolTip("Volume") self.listbtn.setStatusTip("Easy Access") self.listbtn.setToolTip( "Shows/Hides a panel for the tags that can be clicked on to take the video to its moment and also a preview window" ) with open("config.txt") as f: self.config = f.read() if self.config == "": with open("config.txt", w) as f2: f2.write("11") self.config = "11" if int(self.config) // 10 == 1: with open("config.txt", "w") as f2: f2.write("12") if int(self.config) // 10 == 2: with open("config.txt", "w") as f2: f2.write("22") if int(self.config) // 10 == 3: with open("config.txt", "w") as f2: f2.write("32") if int(self.config) // 10 == 4: with open("config.txt", "w") as f2: f2.write("42") def moviess(self): x = self.filename.split("/") file_name = self.filename[:self.filename.find(x[len(x) - 1])] png = "" png2 = "" folders = os.listdir(file_name + r"/") for file in folders: if file.find(".mp4") > 0: png = png + ";" + file_name + file png2 = ";" + file_name + file + png2 png = png + ";" self.png = png png2 = png2 + ";" self.png2 = png2 def hoverleave(self): self.widget.hide() def gotovolume(self): x, _ = win32api.GetCursorPos() self.videoplayer.setVolume( int((x - self.mapToGlobal(self.volume.pos()).x()) / self.volume.width() * 100)) self.volume.setValue( int((x - self.mapToGlobal(self.volume.pos()).x()) / self.volume.width() * 100)) if self.m % 2 == 1: self.m += 1 self.videoplayer.setMuted(False) def goto(self): x, _ = win32api.GetCursorPos() if self.filename != "": self.videoplayer.setPosition( (x - self.mapToGlobal(self.sliderfilm.pos()).x()) / self.sliderfilm.width() * self.dur * 1000) def onHovered(self): x, _ = win32api.GetCursorPos() if self.filename != "": if self.listviewstatus % 2 == 1: self.videoplayer3.setPosition( (x - self.mapToGlobal(self.sliderfilm.pos()).x()) / self.sliderfilm.width() * self.dur * 1000) self.widget.show() def eventFilter(self, obj, event): if obj == self.sliderfilm and event.type() == QtCore.QEvent.HoverMove: self.onHovered() elif (obj == self.frames or obj == self.frame_2) and event.type() == QtCore.QEvent.Enter: self.hoverleave() elif obj == self.sliderfilm and event.type( ) == QtCore.QEvent.MouseButtonPress: self.goto() elif obj == self.volume and event.type( ) == QtCore.QEvent.MouseButtonPress: self.gotovolume() elif obj == self.frames and event.type( ) == QtCore.QEvent.MouseButtonDblClick: if not self.isFullScreen(): self.fulls() else: self.unfull() return super(QMainWindow, self).eventFilter(obj, event) def stopp(self): self.stop.setEnabled(False) self.videoplayer.stop() self.videoplayer.setPosition(0) self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) def listwidgetclicked(self, item): t = item.text() t = t[t.find(">") + 1:] pt = datetime.strptime(t, "%H:%M:%S") total_seconds = pt.second + pt.minute * 60 + pt.hour * 3600 if self.a == 0: self.videoplayer.setPosition(total_seconds * 1000) def list(self): if self.listviewstatus % 2 == 1: self.listView.hide() self.widget.hide() self.listbtn.setText("^") self.listviewstatus += 1 else: self.listbtn.setText("v") self.listviewstatus += 1 self.listView.show() def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: if self.isFullScreen(): self.unfull() elif e.key() == Qt.Key_6: if self.filename != "": self.videoplayer.setPosition(self.videoplayer.position() + 5000) elif e.key() == Qt.Key_4: if self.filename != "": self.videoplayer.setPosition(self.videoplayer.position() - 5000) elif e.key() == Qt.Key_Space: if self.filename != "": self.play_video() elif e.key() == Qt.Key_M: if self.m % 2 == 0: self.m += 1 self.videoplayer.setMuted(True) self.volume.setEnabled(False) self.vvv = self.volume.value() self.volume.setValue(0) else: self.m += 1 self.volume.setValue(self.vvv) self.volume.setEnabled(True) self.videoplayer.setMuted(False) def screen(self): if not self.isFullScreen(): self.fulls() else: self.unfull() # forward media 5s def skipforw(self): a = self.png.find(self.filename) aa = self.png.find(";", a + 1) filename = self.png[aa + 1:self.png.find(";", aa + 1)] if filename != "": self.filename = filename self.videoplayer.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.videoplayer3.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) title = filename.split("/") title = title[len(title) - 1] self.setWindowTitle(f"Taz Player openning{title}") self.videoplayer3.play() self.videoplayer3.pause() self.widget.hide() self.videoplayer.setPosition(0) self.videoplayer.play() self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) clip = VideoFileClip(filename) self.dur = clip.duration def skipbac(self): a = self.png2.find(self.filename) aa = self.png2.find(";", a + 1) filename = self.png2[aa + 1:self.png2.find(";", aa + 1)] if filename != "": self.filename = filename self.videoplayer.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.videoplayer3.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) title = filename.split("/") title = title[len(title) - 1] self.setWindowTitle(f"Taz Player openning{title}") self.videoplayer3.play() self.videoplayer3.pause() self.widget.hide() self.videoplayer.setPosition(0) self.videoplayer.play() self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) clip = VideoFileClip(filename) self.dur = clip.duration # set increase rate def incRate(self): if self.videoplayer.playbackRate() == 0: x = self.videoplayer.playbackRate() + 1 else: x = self.videoplayer.playbackRate() self.videoplayer.setPlaybackRate(x + 0.25) # set decrease rate def decRate(self): if self.videoplayer.playbackRate() == 0: x = self.videoplayer.playbackRate() + 1 else: x = self.videoplayer.playbackRate() self.videoplayer.setPlaybackRate(x - 0.25) # Handling Tags def fillListView(self): for i in range(len(self.dataL)): self.listView.addItem(self.dataL[i][0] + "->" + self.dataL[i][1]) def updateTagFile(self): fname = self.fileName.split(".") fname = fname[0] with open(fname + ".csv", mode="w") as f: writer = csv.writer( f, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL, lineterminator="\n", ) for line in self.dataL: writer.writerow(line) def giveTime(self): vidPos = self.videoplayer.position() h = int(vidPos / 1000 // 3600) m = int((vidPos / 1000 - h * 3600) // 60) s = int(((vidPos / 1000 - h * 3600 - m * 60) % 60) % 60) * 100 // 100 if h < 10: h = "0" + str(h) if m < 10: m = "0" + str(m) if s < 10: s = "0" + str(s) return f"{h}:{m}:{s}" def insertTag(self, tableWidget): t = tableWidget tag = "New Tag" tagTime = self.giveTime() l = len(self.dataL) i = 0 flag = False while tagTime > self.dataL[i][1]: i += 1 if i >= l: break if i < l: if tagTime == self.dataL[i][1]: flag = True if not flag: self.dataL.insert(i, [tag, tagTime]) t.insertRow(i) t.setItem( i, 0, QTableWidgetItem(tag), ) t.setItem( i, 1, QTableWidgetItem(tagTime), ) t.editItem(t.item(i, 0)) def removeRow(self, tableWidget): if len(self.dataL) > 0: self.dataL.remove(self.dataL[tableWidget.currentRow()]) tableWidget.removeRow(tableWidget.currentRow()) def updateList(self, tableWidget): for i in range(tableWidget.rowCount()): self.dataL[i] = [ tableWidget.item(i, 0).text(), tableWidget.item(i, 1).text(), ] def undoChanges(self): fname = self.fileName.split(".") fname = fname[0] with open(fname + ".csv", mode="r+") as f: data = csv.reader(f) self.dataL = list(data) def fillTable(self, tableWidget): tableWidget.setRowCount(len(self.dataL)) for i in range(len(self.dataL)): tableWidget.setItem(i, 0, QTableWidgetItem(self.dataL[i][0])) tableWidget.setItem(i, 1, QTableWidgetItem(self.dataL[i][1])) def openTagFile(self): filename, _ = QFileDialog.getOpenFileName( self, "Open Tag File", filter="*.csv", ) if filename != "": self.fileName = filename with open(filename, mode="r+") as f: data = csv.reader(f) self.dataL = list(data) def opensecond(self): login_page = LoginPage() login_page.setWindowFlags(QtCore.Qt.WindowCloseButtonHint) if int(self.config) % 10 == 1: login_page.Save.setText("برو به") login_page.apply.setText("اعمال تغییرات") login_page.buttonBox.button(QDialogButtonBox.Ok).setText("تایید") login_page.buttonBox.button( QDialogButtonBox.Cancel).setText("انصراف") login_page.AddRow.setText("افزودن تگ") login_page.DeleteRow.setText("حذف تگ") login_page.OpenTagButton.setText("باز کردن فایل تگ") login_page.tableWidget.setHorizontalHeaderLabels(["تگ", "زمان"]) else: login_page.tableWidget.setHorizontalHeaderLabels(["Tag", "Time"]) self.fillTable(login_page.tableWidget) login_page.buttonBox.accepted.connect(lambda: [ self.updateList(login_page.tableWidget), self.listbtn.setFocus(), self.listView.clear(), self.fillListView(), self.updateTagFile(), ]) login_page.buttonBox.rejected.connect(lambda: [ self.listbtn.setFocus(), self.undoChanges(), ]) login_page.apply.clicked.connect(lambda: [ self.updateList(login_page.tableWidget), self.listView.clear(), self.fillListView(), ]) login_page.AddRow.clicked.connect(lambda: [ self.insertTag(login_page.tableWidget), ]) login_page.Save.clicked.connect(lambda: [ login_page.shows(self), self.updateList(login_page.tableWidget), self.listbtn.setFocus(), self.listView.clear(), self.fillListView(), ]) login_page.DeleteRow.clicked.connect(lambda: [ self.removeRow(login_page.tableWidget), ]) login_page.OpenTagButton.clicked.connect(lambda: [ self.openTagFile(), self.fillTable(login_page.tableWidget), self.listView.clear(), self.fillListView(), ]) login_page.tableWidget.sortByColumn(1, Qt.AscendingOrder) # if int(self.config) % 10 == 2: # login_page.tableWidget.setHorizontalHeaderLabels(["Tag", "Time"]) # else: # login_page.tableWidget.setHorizontalHeaderLabels(["تگ", "زمان"]) login_page.exec_() # End of Handling Tags def fulls(self): self.decreaseRate.hide() self.increaseRate.hide() self.centralwidget.setContentsMargins(0, 0, 0, 0) self.play.hide() self.open.hide() self.skipforward.hide() self.skipback.hide() self.label.hide() self.label_2.hide() self.volume.hide() self.menubar.hide() self.sliderfilm.hide() self.statusBar.hide() self.showFullScreen() self.listbtn.hide() self.widget.hide() self.listView.hide() self.frame_2.hide() self.stop.hide() self.listviewstatus = 1 def unfull(self): self.frame_2.show() self.stop.show() self.list() self.centralwidget.setContentsMargins(10, 10, 10, 10) self.decreaseRate.show() self.increaseRate.show() self.play.show() self.open.show() self.skipforward.show() self.skipback.show() self.label.show() self.label_2.show() self.volume.show() self.menubar.show() self.sliderfilm.show() self.statusBar.show() self.showNormal() self.listbtn.show() ##setting position of film def setpos(self, position): self.videoplayer.setPosition(position) def position(self, position): position2 = self.tolfilm * 1000 - position + 1000 hour = int((position / 3600000) % 24) hour2 = int((position2 / 3600000) % 24) if hour < 10: hour = "0" + str(hour) if hour2 < 10: hour2 = "0" + str(hour2) minute = int((position / 60000) % 60) minute2 = int((position2 / 60000) % 60) if minute < 10: minute = "0" + str(minute) if minute2 < 10: minute2 = "0" + str(minute2) second = int((position / 1000) % 60) second2 = int((position2 / 1000) % 60) if second < 10: second = "0" + str(second) if second2 < 10: second2 = "0" + str(second2) self.label.setText(f"{hour}:{minute}:{second}") self.label_2.setText(f"{hour2}:{minute2}:{second2}") self.sliderfilm.setValue(position) if position2 < 1000: self.videoplayer.stop() self.sliderfilm.setValue(0) self.stop.setEnabled(False) self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) def changed(self, duration): self.sliderfilm.setRange(0, duration) ##setting position of volume def setvolpos(self, position): self.videoplayer.setVolume(position) ##open button or open from menu bar def Loadvideo(self, videoplayer): self.a = 0 filename, _ = QFileDialog.getOpenFileName( self, "Open Video", filter="*.mp4;*.mov;*.wmv;*.webm;*.wmv;*.m4v;*.m4a;*.flv", ) if filename != "": self.videoplayer.setPosition(0) self.filename = filename if filename != "": self.fileName = filename.split(".")[0] fname = filename.split(".") fnmae = fname[0] if os.path.isfile(fnmae + ".csv"): with open(fnmae + ".csv", mode="r+") as f: data = csv.reader(f) self.dataL = list(data) self.listView.clear(), self.fillListView() clip = VideoFileClip(filename) self.dur = clip.duration self.videoplayer.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.videoplayer3.setMedia( QMediaContent(QUrl.fromLocalFile(filename))) self.moviess() clip = VideoFileClip(filename) self.tolfilm = int(clip.duration) title = filename.split("/") title = title[len(title) - 1] self.setWindowTitle(f"Taz Player openning : {title}") self.videoplayer3.play() self.videoplayer3.pause() self.widget.hide() self.stop.setEnabled(True) self.videoplayer.play() self.play.setEnabled(True) self.play.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) self.increaseRate.setEnabled(True) self.decreaseRate.setEnabled(True) ##play button def play_video(self): if self.videoplayer.state() == QMediaPlayer.PlayingState: self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.videoplayer.pause() else: self.videoplayer.play() self.stop.setEnabled(True) self.play.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) def theme01(self): self.videowidget.setStyleSheet("background-color: #404040") self.setStyleSheet("background-color: #A0A0A0") if self.theme1.text() == "Theme1": with open("config.txt", "w") as f: f.write("12") else: with open("config.txt", "w") as f: f.write("11") def theme02(self): self.videowidget.setStyleSheet("background-color: #330019") self.setStyleSheet("background-color: #990000") if self.theme1.text() == "Theme1": with open("config.txt", "w") as f: f.write("22") else: with open("config.txt", "w") as f: f.write("21") def theme03(self): self.videowidget.setStyleSheet("background-color: #35557F") self.setStyleSheet("background-color: #003366") if self.theme1.text() == "Theme1": with open("config.txt", "w") as f: f.write("32") else: with open("config.txt", "w") as f: f.write("31") def theme04(self): self.videowidget.setStyleSheet("background-color: #00FF00") self.setStyleSheet("background-color: #4C9900") if self.theme1.text() == "Theme1": with open("config.txt", "w") as f: f.write("42") else: with open("config.txt", "w") as f: f.write("41")
QMediaContent( QUrl.fromLocalFile( "/Users/uma/Documents/my_website/CarEntryH2.MOV"))) playlist_2.setPlaybackMode(QMediaPlaylist.Loop) playlist_3 = QMediaPlaylist() playlist_3.addMedia( QMediaContent( QUrl.fromLocalFile( "/Users/uma/Documents/my_website/CarExitH2.MOV"))) playlist_3.setPlaybackMode(QMediaPlaylist.Loop) player_1 = QMediaPlayer(None, QMediaPlayer.VideoSurface) player_1.setVideoOutput(ui.vid_1) player_1.setPlaylist(playlist_1) player_1.setMuted(True) player_1.play() player_2 = QMediaPlayer(None, QMediaPlayer.VideoSurface) player_2.setVideoOutput(ui.vid_2) player_2.setPlaylist(playlist_2) player_2.setMuted(True) player_2.play() player_3 = QMediaPlayer(None, QMediaPlayer.VideoSurface) player_3.setVideoOutput(ui.vid_3) player_3.setPlaylist(playlist_3) player_3.setMuted(True) player_3.play() timer = QTimer()
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.player = QMediaPlayer(self) #创建视频播放器 self.player.setNotifyInterval(1000) #信息更新周期, ms scene = QGraphicsScene(self) self.ui.graphicsView.setScene(scene) self.videoItem = QGraphicsVideoItem() #视频显示画面 self.videoItem.setSize(QSizeF(320, 220)) self.videoItem.setFlag(QGraphicsItem.ItemIsMovable) self.videoItem.setFlag(QGraphicsItem.ItemIsSelectable) self.videoItem.setFlag(QGraphicsItem.ItemIsFocusable) scene.addItem(self.videoItem) self.player.setVideoOutput(self.videoItem) #设置视频显示图形项 self.textItem = QGraphicsTextItem("面朝大海,春暖花开") #弹幕文字 font = self.textItem.font() font.setPointSize(20) self.textItem.setFont(font) self.textItem.setDefaultTextColor(Qt.red) self.textItem.setPos(100, 220) self.textItem.setFlag(QGraphicsItem.ItemIsMovable) self.textItem.setFlag(QGraphicsItem.ItemIsSelectable) self.textItem.setFlag(QGraphicsItem.ItemIsFocusable) scene.addItem(self.textItem) self.ui.btnText.setCheckable(True) #弹幕文字按钮 self.ui.btnText.setChecked(True) self.__duration = "" self.__curPos = "" self.player.stateChanged.connect(self.do_stateChanged) self.player.positionChanged.connect(self.do_positionChanged) self.player.durationChanged.connect(self.do_durationChanged) ## ==============自定义功能函数======================== ## ==============event处理函数========================== def closeEvent(self, event): #窗体关闭时 # 窗口关闭时不能自动停止播放,需手动停止 if (self.player.state() == QMediaPlayer.PlayingState): self.player.stop() ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() ##打开文件 def on_btnOpen_clicked(self): curPath = QDir.currentPath() #获取系统当前目录 ## curPath=os.getcwd() title = "选择视频文件" filt = "视频文件(*.wmv *.avi);;所有文件(*.*)" fileName, flt = QFileDialog.getOpenFileName(self, title, curPath, filt) if (fileName == ""): return fileInfo = QFileInfo(fileName) baseName = fileInfo.fileName() ## baseName=os.path.basename(fileName) self.ui.LabCurMedia.setText(baseName) curPath = fileInfo.absolutePath() QDir.setCurrent(curPath) #重设当前目录 media = QMediaContent(QUrl.fromLocalFile(fileName)) self.player.setMedia(media) #设置播放文件 self.player.play() @pyqtSlot() ##播放 def on_btnPlay_clicked(self): self.player.play() @pyqtSlot() ##暂停 def on_btnPause_clicked(self): self.player.pause() @pyqtSlot() ##停止 def on_btnStop_clicked(self): self.player.stop() @pyqtSlot() ##全屏 def on_btnFullScreen_clicked(self): self.videoWidget.setFullScreen(True) @pyqtSlot() ##静音按钮 def on_btnSound_clicked(self): mute = self.player.isMuted() self.player.setMuted(not mute) if mute: self.ui.btnSound.setIcon(QIcon(":/icons/images/volumn.bmp")) else: self.ui.btnSound.setIcon(QIcon(":/icons/images/mute.bmp")) @pyqtSlot(int) ##音量调节 def on_sliderVolumn_valueChanged(self, value): self.player.setVolume(value) @pyqtSlot(int) ##播放进度调节 def on_sliderPosition_valueChanged(self, value): self.player.setPosition(value) @pyqtSlot() ##放大 def on_btnZoomIn_clicked(self): sc = self.videoItem.scale() self.videoItem.setScale(sc + 0.1) @pyqtSlot() ##缩小 def on_btnZoomOut_clicked(self): sc = self.videoItem.scale() self.videoItem.setScale(sc - 0.1) @pyqtSlot(bool) ##弹幕 def on_btnText_clicked(self, checked): self.textItem.setVisible(checked) ## =============自定义槽函数=============================== def do_stateChanged(self, state): isPlaying = (state == QMediaPlayer.PlayingState) self.ui.btnPlay.setEnabled(not isPlaying) self.ui.btnPause.setEnabled(isPlaying) self.ui.btnStop.setEnabled(isPlaying) def do_durationChanged(self, duration): self.ui.sliderPosition.setMaximum(duration) secs = duration / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__duration = "%d:%d" % (mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration) def do_positionChanged(self, position): if (self.ui.sliderPosition.isSliderDown()): return #如果正在拖动滑条,退出 self.ui.sliderPosition.setSliderPosition(position) secs = position / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__curPos = "%d:%d" % (mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration)
class VideoPlayer(QWidget): def __init__(self, parent=None, mute=True): QWidget.__init__(self, parent) self.ui = Ui_VideoPlayer() self.error_handler = lambda txt: None savecwd = os.getcwd() os.chdir('view/ui') self.ui.setupUi(self) os.chdir(savecwd) self.ui.bn_size.hide() self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) # self.item=QGraphicsVideoItem() # self.ui.mid_frame_grid_layout.addItem(self.item,0,0) # self.media_player.setVideoOutput(self.item) self.media_player_widget = QVideoWidget(self.ui.mid_frame) self.ui.mid_frame_grid_layout.addWidget(self.media_player_widget, 0, 0) self.media_player.setVideoOutput(self.media_player_widget) # self.media_player.stateChanged.connect(self.state_changed) self.media_player.bufferStatusChanged.connect( self.buffer_status_changed) self.media_player.mediaStatusChanged.connect(self.media_status_changed) self.media_player.positionChanged.connect(self.positionChanged) self.media_player.durationChanged.connect(self.durationChanged) self.media_player.error.connect(self.handleError) # self.media_player.metaDataChanged.connect(self.meta_data_changed) self.ui.bn_mute.setChecked(mute) self.mute() self.connect_to_playlist(connected=False, toggle_playlist=lambda: None) self.ui.dial_volume.setFixedWidth(50) # binding self.ui.bn_play.clicked.connect(self.media_player.play) self.ui.bn_pause.clicked.connect(self.media_player.pause) self.ui.bn_mute.clicked.connect(self.mute) self.ui.bn_stop.clicked.connect(self.media_player.stop) self.ui.bn_next.clicked.connect(self.next) self.ui.bn_prev.clicked.connect(self.prev) self.ui.bn_playlist.clicked.connect(self.show_playlist) self.ui.bn_uget.clicked.connect(self.on_uget_pressed) self.ui.progress_slider.sliderMoved.connect( self.media_player.setPosition) # self.ui.spin_volume.valueChanged.connect(self.media_player.setVolume) self.ui.dial_volume.valueChanged.connect(self.media_player.setVolume) self.url = '' self.altermate = list() self.duration = '0:00' self.change_position = None self.uget_handler = lambda fname='', url='': None # self.on_end_of_playing=lambda :None def set_error_handler(self, handler): self.error_handler = handler def icons_set(self, bn, fname_off, fname_on=None): icon = QIcon() icon.addPixmap(QPixmap(fname_off), QIcon.Normal, QIcon.Off) if fname_on is not None: icon.addPixmap(QPixmap(fname_on), QIcon.Normal, QIcon.On) bn.setIcon(icon) def connect_to_playlist(self, connected=False, goto_prev=lambda: None, goto_next=lambda: None, toggle_playlist=None): self.goto_next = goto_next self.goto_prev = goto_prev if toggle_playlist is not None: self.toggle_playlist = toggle_playlist self.connected = connected if self.connected: self.ui.playlist_frame.show() self.ui.bn_add.hide() self.ui.bn_minus.show() else: self.ui.playlist_frame.hide() self.ui.bn_add.show() self.ui.bn_minus.hide() def set_plus_handler(self, handler=lambda: None): self.ui.bn_add.clicked.connect(handler) def set_minus_handler(self, handler=lambda: None): self.ui.bn_minus.clicked.connect(handler) def set_uget_handler(self, handler=lambda fname='', url='': None): self.uget_handler = handler def on_uget_pressed(self, url=None): self.uget_handler(fname=urlparse( url.rstrip('/'))[2].rpartition('/')[2], url=url) def set_url(self, url=''): self.url = url self.altermate = list() self.ui.bn_size.hide() self.media_player.setMedia(QMediaContent(QUrl(url))) uget_menu = QMenu(self) uget_menu_action = QAction('Standart quality', self, triggered=self.get_handler( self.on_uget_pressed, url)) uget_menu.addAction(uget_menu_action) self.ui.bn_uget.setMenu(uget_menu) def change_url(self, url): position = self.media_player.position() self.media_player.stop() self.media_player.setMedia(QMediaContent(QUrl(url))) self.media_player.play() self.change_position = position def add_alternate_url(self, caption='', url=''): self.ui.bn_size.show() self.altermate.append(dict(caption=caption, url=url)) menu = QMenu(self) uget_menu = QMenu(self) for item in self.altermate: menu_action = QAction(item['caption'], self, triggered=self.get_handler( self.change_url, item['url'])) menu.addAction(menu_action) uget_menu_action = QAction(item['caption'], self, triggered=self.get_handler( self.on_uget_pressed, item['url'])) uget_menu.addAction(uget_menu_action) self.ui.bn_size.setMenu(menu) self.ui.bn_uget.setMenu(uget_menu) def get_handler(self, function, arg): return lambda: function(arg) def play(self): self.media_player.play() def pause(self): self.media_player.pause() def stop(self): self.media_player.stop() def next(self): self.goto_next() def prev(self): self.goto_prev() def show_playlist(self): self.toggle_playlist() def mute(self): if self.ui.bn_mute.isChecked(): self.media_player.setMuted(True) else: self.media_player.setMuted(False) self.media_player.setVolume(self.ui.dial_volume.value()) def little_forvard(self, s=30): self.media_player.setPosition(self.media_player.position() + s * 1000) def media_status_changed(self, status): # print('Media status=', status) if status == QMediaPlayer.StalledMedia: self.ui.progress_buffer.show() else: self.ui.progress_buffer.hide() if status == QMediaPlayer.BufferedMedia: if self.change_position is not None: # print('Changing position') self.media_player.setPosition(self.change_position) self.change_position = None if status == QMediaPlayer.EndOfMedia: self.goto_next() def buffer_status_changed(self, status): # print('Buffer status=', status) self.ui.progress_buffer.setValue(status) # def state_changed(self,status): # print('State=', status) def state(self): return self.media_player.state() def positionChanged(self, position): self.ui.progress_slider.setValue(position) self.ui.lbl_time.setText( self.time_format(position) + ' / ' + self.duration) def durationChanged(self, duration): self.ui.progress_slider.setRange(0, duration) self.duration = self.time_format(duration) def time_format(self, ms): dur = ms // 1000 minutes = dur // 60 secundes = dur - minutes * 60 return '%d:%02d' % (minutes, secundes) def handleError(self): print("Error in " + self.url + ': ' + self.media_player.errorString()) self.error_handler('Player error: ' + self.media_player.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 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] =="vut": self.projectfile = projectfile else: self.projectfile = projectfile +'.vut' self.videofile = None self.GPXfile = None self.GPXList = None self.fps = None self.RealFps = None self.DB = None self.DEM = None self.Image = None self.HFilmSize = None self.VFilmSize = None self.FocalLenght = None self.GPXMode = 2 self.Course = 0 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) self.toolButton_4.clicked.connect(self.Setup3DParameterer) if os.name == 'nt': self.toolButton_4.setEnabled(False) def Setup3DParameterer(self): treDOptions = Setup3D(QgsProject) a = treDOptions.exec_() if a == 1: self.DEM = treDOptions.DEM self.Image = treDOptions.Image self.HFilmSize = treDOptions.HFilmSize self.VFilmSize = treDOptions.VFilmSize self.FocalLenght = treDOptions.FocalLenght self.GPXMode = treDOptions.GPXMODE if self.GPXMode == 1: self.HeadingOffset = treDOptions.HeadingOffset self.PitchOffset = treDOptions.PitchOffset self.RollOffset = treDOptions.RollOffset 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.checkBox.isChecked(): PixelConversion = str(1) else: PixelConversion = str(0) if self.DB == None: outputFile.write('Video UAV Tracker Project v0.2 DO NOT MODIFY'+ '\nVideo file location = ' +self.videofile+ '\nVideo start at msecond: '+ str(self.player.position())+ ' #fps = '+str(self.RealFps)+' '+str(self.VideoWidth)+' '+str(self.VideoHeight)+' '+PixelConversion+ '\nDB = None'+ '\n3D = ' + str(self.DEM) + ',' + str(self.Image) + ',' + str(self.HFilmSize) + ',' + str(self.VFilmSize) + ',' + str(self.FocalLenght) +','+str(self.Course)+ '\n'+'Latitude # Longitude # Ele # Speed (m/s) # Course # Time \n') else: outputFile.write('Video UAV Tracker Project v0.2 DO NOT MODIFY'+ '\nVideo file location = ' +self.videofile+ '\nVideo start at msecond: '+ str(self.player.position())+ ' #fps = '+str(self.RealFps)+' '+str(self.VideoWidth)+' '+str(self.VideoHeight)+' '+PixelConversion+ '\nDB = '+str(self.DB.dataProvider().dataSourceUri().split('|')[0])+ '\n3D = '+str(self.DEM)+','+str(self.Image)+','+str(self.HFilmSize)+','+str(self.VFilmSize)+','+str(self.FocalLenght)+','+str(self.Course)+ '\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 if self.Course == 1: Course = float(x[1][4]) Pitch = float(x[1][5]) Roll = float(x[1][6]) else: Course = GeodesicCalcolus['azi2'] if Course < 0: Course += 360 Pitch = 0 Roll = 0 if self.GPXMode == 1: # correct value with fixed offset Course = Course + self.HeadingOffset if Course > 360: Course = Course -360 elif Course < 0: Course += 360 Pitch = Pitch + self.PitchOffset if Pitch < -180: Pitch = 360 - abs(Pitch) elif Pitch > 180: Pitch = -(360-Pitch) Roll = Roll + self.RollOffset if Roll < -180: Roll = 360 - abs(Roll) elif Roll > 180: Roll = -(360-Roll) 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 if self.Course == 1: Course = float(x[1][4]) Pitch = float(x[1][5]) Roll = float(x[1][6]) else: Course = GeodesicCalcolus['azi2'] if Course < 0: Course += 360 Pitch = 0 Roll = 0 if self.GPXMode == 1: # correct value with fixed offset Course = Course + self.HeadingOffset if Course > 360: Course = Course -360 elif Course < 0: Course += 360 Pitch = Pitch + self.PitchOffset if Pitch < -180: Pitch = 360 - abs(Pitch) elif Pitch > 180: Pitch = -(360-Pitch) Roll = Roll + self.RollOffset if Roll < -180: Roll = 360 - abs(Roll) elif Roll > 180: Roll = -(360-Roll) Ele = x[1][2] Time = x[1][3] Counter = Counter + 1 outputFile.write(str(ActualLatitude)+' '+str(ActualLongitude)+ ' '+str(Ele)+' '+str(Speed)+' '+str(Course)+ ' '+str(Pitch)+' '+str(Roll)+' '+str(Time)+'\n') outputFile.close() self.Main.LoadProjFromNew(self.projectfile) self.close() def SelectVideoGPX(self): if os.name == 'nt': ffmpeg = os.path.dirname(__file__)+'/FFMPEG/ffprobe.exe' versione = 'ffprobe.exe' else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffprobe' versione = 'ffprobe' if os.path.exists(ffmpeg): 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.Course = 0 self.ParseGpx(self.GPXfile) self.LoadVideo(self.videofile) self.replayPosition_label.setText( "-:- / -:-") else: ret = QMessageBox.warning(self, "Warning", 'missing ffprobe binaries, please download it from https://github.com/sagost/Video_UAV_Tracker-3D/tree/master/Video_UAV_Tracker/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,'Course':0,'Pitch':0,'Roll':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:-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: 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: Error = 1 FormatoErrore = str(x) elif x.find('<course>')==0: dict['Course'] = float(x[8:-9]) self.Course = 1 elif x.find('<yaw>') == 0: dict['Course'] = float(x[5:-6]) self.Course = 1 elif x.find('<pitch>') == 0: dict['Pitch'] = float(x[7:-8]) elif x.find('<roll>') == 0: dict['Roll'] = float(x[6:-7]) if dict['Time'] != Timestamp: if self.Course == 1: Point = [dict['Lat'], dict['Lon'], dict['Ele'], dict['Time'],dict['Course'],dict['Pitch'],dict['Roll']] else: 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): filepath2 = '"'+filepath+'"' if os.name == 'nt': ffmpeg = '"'+os.path.dirname(__file__)[0:-18]+'/Video_UAV_Tracker/FFMPEG/ffprobe.exe'+'"' else: ffmpeg = os.path.dirname(__file__)+'/FFMPEG/./ffprobe' p = os.popen(ffmpeg + ' -v error -show_format -show_streams '+filepath2) lines = p.readlines() for l in lines: l = l.strip() if str(l).startswith("width"): self.VideoWidth = str(l).split('=')[1] elif str(l).startswith("height"): self.VideoHeight = str(l).split('=')[1] elif str(l).startswith("r_frame_rate"): if str(l).split('=')[1] != '0/0' fps = float(str(l).split('=')[1].split('/')[0] ) / float(str(l).split('=')[1].split('/')[1] ) 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+round(self.fps)) def BackwardFrame(self): position = self.player.position() self.player.setPosition(position-round(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 Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.time_label = QLabel(self) self.volume_slider = QSlider(self) self.progress_slider = QSlider(self) self.sound_btn = QPushButton(self) self.previous_btn = QPushButton(self) self.play_pause_btn = QPushButton(self) self.next_btn = QPushButton(self) self.mode_btn = QPushButton(self) self.list_btn = QPushButton(self) self.list_widget = QListWidget(self) self.h1_layout = QHBoxLayout() self.h2_layout = QHBoxLayout() self.all_v_layout = QVBoxLayout() self.playlist = QMediaPlaylist(self) self.player = QMediaPlayer(self) self.widget_init() self.layout_init() self.signal_init() def widget_init(self): self.time_label.setText('--/--') self.volume_slider.setRange(0, 100) self.volume_slider.setValue(100) self.volume_slider.setOrientation(Qt.Horizontal) self.progress_slider.setEnabled(False) self.progress_slider.setOrientation(Qt.Horizontal) self.sound_btn.setIcon(QIcon('images/sound_on.png')) self.previous_btn.setIcon(QIcon('images/previous.png')) self.play_pause_btn.setIcon(QIcon('images/play.png')) self.next_btn.setIcon(QIcon('images/next.png')) self.mode_btn.setIcon(QIcon('images/list_loop.png')) self.list_btn.setIcon(QIcon('images/show.png')) self.player.setPlaylist(self.playlist) self.media_list = ['/Users/louis/Downloads/music1.mp3', '/Users/louis/Downloads/music2.mp4', '/Users/louis/Downloads/music3.mp3'] for m in self.media_list: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(m))) self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.list_widget.addItems([m.split('/')[-1] for m in self.media_list]) def layout_init(self): self.h1_layout.addWidget(self.progress_slider) self.h1_layout.addWidget(self.time_label) self.h2_layout.addWidget(self.volume_slider) self.h2_layout.addWidget(self.sound_btn) self.h2_layout.addWidget(self.previous_btn) self.h2_layout.addWidget(self.play_pause_btn) self.h2_layout.addWidget(self.next_btn) self.h2_layout.addWidget(self.mode_btn) self.h2_layout.addWidget(self.list_btn) self.all_v_layout.addLayout(self.h1_layout) self.all_v_layout.addLayout(self.h2_layout) self.all_v_layout.addWidget(self.list_widget) self.all_v_layout.setSizeConstraint(QVBoxLayout.SetFixedSize) self.setLayout(self.all_v_layout) def signal_init(self): self.sound_btn.clicked.connect(lambda: self.btn_func(self.sound_btn)) self.previous_btn.clicked.connect(lambda: self.btn_func(self.previous_btn)) self.play_pause_btn.clicked.connect(lambda: self.btn_func(self.play_pause_btn)) self.next_btn.clicked.connect(lambda: self.btn_func(self.next_btn)) self.mode_btn.clicked.connect(lambda: self.btn_func(self.mode_btn)) self.list_btn.clicked.connect(lambda: self.btn_func(self.list_btn)) self.volume_slider.valueChanged.connect(self.volume_slider_func) self.list_widget.doubleClicked.connect(self.list_play_func) self.player.durationChanged.connect(self.get_duration_func) self.player.positionChanged.connect(self.get_position_func) self.progress_slider.sliderMoved.connect(self.update_position_func) def btn_func(self, btn): if btn == self.sound_btn: if self.player.isMuted(): self.player.setMuted(False) self.sound_btn.setIcon(QIcon('images/sound_on')) else: self.player.setMuted(True) self.sound_btn.setIcon(QIcon('images/sound_off')) elif btn == self.previous_btn: if self.playlist.currentIndex() == 0: self.playlist.setCurrentIndex(self.playlist.mediaCount() - 1) else: self.playlist.previous() elif btn == self.play_pause_btn: if self.player.state() == 1: self.player.pause() self.play_pause_btn.setIcon(QIcon('images/play.png')) else: self.player.play() self.play_pause_btn.setIcon(QIcon('images/pause.png')) elif btn == self.next_btn: if self.playlist.currentIndex() == self.playlist.mediaCount() - 1: self.playlist.setCurrentIndex(0) else: self.playlist.next() elif btn == self.mode_btn: if self.playlist.playbackMode() == 2: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) self.mode_btn.setIcon(QIcon('images/item_loop.png')) elif self.playlist.playbackMode() == 3: self.playlist.setPlaybackMode(QMediaPlaylist.Random) self.mode_btn.setIcon(QIcon('images/random.png')) elif self.playlist.playbackMode() == 4: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.mode_btn.setIcon(QIcon('images/list_loop.png')) elif btn == self.list_btn: if self.list_widget.isHidden(): self.list_widget.show() self.list_btn.setIcon(QIcon('images/show.png')) else: self.list_widget.hide() self.list_btn.setIcon(QIcon('images/hide.png')) def volume_slider_func(self, value): self.player.setVolume(value) if value == 0: self.sound_btn.setIcon(QIcon('images/sound_off.png')) else: self.sound_btn.setIcon(QIcon('images/sound_on.png')) def list_play_func(self): self.playlist.setCurrentIndex(self.list_widget.currentRow()) self.player.play() self.play_pause_btn.setIcon(QIcon('images/pause.png')) def get_duration_func(self, d): self.progress_slider.setRange(0, d) self.progress_slider.setEnabled(True) self.get_time_func(d) def get_time_func(self, d): seconds = int(d / 1000) minutes = int(seconds / 60) seconds -= minutes * 60 if minutes == 0 and seconds == 0: self.time_label.setText('--/--') self.play_pause_btn.setIcon(QIcon('images/play.png')) else: self.time_label.setText('{}:{}'.format(minutes, seconds)) def get_position_func(self, p): self.progress_slider.setValue(p) def update_position_func(self, v): self.player.setPosition(v) d = self.progress_slider.maximum() - v self.get_time_func(d)
class QmyMainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 ## self.setWindowTitle("Demo10_1,音乐播放器") self.player = QMediaPlayer(self) self.playlist = QMediaPlaylist(self) self.player.setPlaylist(self.playlist) self.playlist.setPlaybackMode(QMediaPlaylist.Loop) #循环模式 self.__duration = "" #文件总时间长度 self.__curPos = "" #当前播放到位置 self.player.stateChanged.connect(self.do_stateChanged) self.player.positionChanged.connect(self.do_positionChanged) self.player.durationChanged.connect(self.do_durationChanged) self.playlist.currentIndexChanged.connect(self.do_currentChanged) ## ==============自定义功能函数============ ## ===============event 处理函数========== def closeEvent(self, event): ##窗体关闭时 ## 窗口关闭时不能自动停止播放,需手动停止 if (self.player.state() == QMediaPlayer.PlayingState): self.player.stop() ## ==========由connectSlotsByName() 自动连接的槽函数================== # 播放列表管理 @pyqtSlot() ##添加文件 def on_btnAdd_clicked(self): ## curPath=os.getcwd() #获取系统当前目录 ## curPath=QDir.homePath() curPath = QDir.currentPath() dlgTitle = "选择音频文件" filt = "音频文件(*.mp3 *.wav *.wma);;所有文件(*.*)" fileList, flt = QFileDialog.getOpenFileNames(self, dlgTitle, curPath, filt) count = len(fileList) if count < 1: return filename = fileList[0] fileInfo = QFileInfo(filename) #文件信息 QDir.setCurrent(fileInfo.absolutePath()) #重设当前路径 for i in range(count): filename = fileList[i] fileInfo.setFile(filename) song = QMediaContent(QUrl.fromLocalFile(filename)) self.playlist.addMedia(song) #添加播放媒体 ## basename=os.path.basename(filename) #文件名和后缀 basename = fileInfo.baseName() self.ui.listWidget.addItem(basename) #添加到界面文件列表 if (self.player.state() != QMediaPlayer.PlayingState): self.playlist.setCurrentIndex(0) self.player.play() @pyqtSlot() ##移除一个文件 def on_btnRemove_clicked(self): pos = self.ui.listWidget.currentRow() item = self.ui.listWidget.takeItem(pos) #python会自动删除 if (self.playlist.currentIndex() == pos): #是当前播放的曲目 nextPos = 0 if pos >= 1: nextPos = pos - 1 self.playlist.removeMedia(pos) #从播放列表里移除 if self.ui.listWidget.count() > 0: #剩余个数 self.playlist.setCurrentIndex(nextPos) self.do_currentChanged(nextPos) #当前曲目变化 else: self.player.stop() self.ui.LabCurMedia.setText("无曲目") else: self.playlist.removeMedia(pos) @pyqtSlot() ##清空播放列表 def on_btnClear_clicked(self): self.playlist.clear() #清空播放列表 self.ui.listWidget.clear() self.player.stop() #停止播放 ## @pyqtSlot() ##双击时切换播放文件 def on_listWidget_doubleClicked(self, index): rowNo = index.row() #行号 self.playlist.setCurrentIndex(rowNo) self.player.play() # 播放控制 @pyqtSlot() ##播放 def on_btnPlay_clicked(self): if (self.playlist.currentIndex() < 0): self.playlist.setCurrentIndex(0) self.player.play() @pyqtSlot() ##暂停 def on_btnPause_clicked(self): self.player.pause() @pyqtSlot() ##停止 def on_btnStop_clicked(self): self.player.stop() @pyqtSlot() ##上一曲目 def on_btnPrevious_clicked(self): self.playlist.previous() @pyqtSlot() ##下一曲目 def on_btnNext_clicked(self): self.playlist.next() @pyqtSlot() ##静音控制 def on_btnSound_clicked(self): mute = self.player.isMuted() self.player.setMuted(not mute) if mute: self.ui.btnSound.setIcon(QIcon(":/icons/images/volumn.bmp")) else: self.ui.btnSound.setIcon(QIcon(":/icons/images/mute.bmp")) @pyqtSlot(int) ##调节音量 def on_sliderVolumn_valueChanged(self, value): self.player.setVolume(value) @pyqtSlot(int) ##文件进度调控 def on_sliderPosition_valueChanged(self, value): self.player.setPosition(value) ## =============自定义槽函数=============================== def do_stateChanged(self, state): ##播放器状态变化 self.ui.btnPlay.setEnabled(state != QMediaPlayer.PlayingState) self.ui.btnPause.setEnabled(state == QMediaPlayer.PlayingState) self.ui.btnStop.setEnabled(state == QMediaPlayer.PlayingState) def do_positionChanged(self, position): ##当前文件播放位置变化,更新进度显示 if (self.ui.sliderPosition.isSliderDown()): #在拖动滑块调整进度 return self.ui.sliderPosition.setSliderPosition(position) secs = position / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__curPos = "%d:%d" % (mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration) def do_durationChanged(self, duration): ##文件时长变化 self.ui.sliderPosition.setMaximum(duration) secs = duration / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__duration = "%d:%d" % (mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration) def do_currentChanged(self, position): ##playlist当前曲目变化 self.ui.listWidget.setCurrentRow(position) item = self.ui.listWidget.currentItem() #QListWidgetItem if (item != None): self.ui.LabCurMedia.setText(item.text())
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 Control: """A class that handles the logic behind the program by manipulating the GUI classes and calling their methods in response to received signals.""" MAGIC = b"\x01\xff" def __init__(self, screens: list) -> None: self.player = QMediaPlayer() self.player.setAudioRole(QAudio.MusicRole) self.playlist = QMediaPlaylist() self.player.setPlaylist(self.playlist) self.mainWindow = MainWindow(self, screens) self.mainArea = self.mainWindow.centralWidget().upperBox.mainArea self.songList = self.mainWindow.centralWidget().upperBox.songList self.mediaControlArea = self.mainWindow.centralWidget( ).mediaControlArea self.mainWindow.show() self.library = None self.currentSong = None self.playing = False self.random = False self.repeat = 0 self.volume = 50 self.volumeChange(self.volume) self.mediaControlArea.volumeControl.setValue(self.volume) self.mainTimer = QTimer() self.mainTimer.setInterval(100) self.mainTimer.timeout.connect(self.updateSongProgress) self.mainTimer.start() self.libraryUpdateTimer = QTimer() self.libraryUpdateTimer.setInterval(15_000) self.libraryUpdateTimer.timeout.connect(self.updateLibrary) self.libraryUpdateTimer.start() self._connection = None self.connections() self.displayedType = None self.displayedName = None self.types = None self.songListWidth = None values = self.load() if values: self.mainWindow.setGeometry(*values) self.volumeChange(self.volume) self.mediaControlArea.volumeControl.setValue(self.volume) self.setUpTimer = QTimer() self.setUpTimer.setInterval(20) self.setUpTimer.setSingleShot(True) self.setUpTimer.timeout.connect(self.setAreas) self.setUpTimer.start() def connections(self): self.player.currentMediaChanged.connect(self.updateCurrentSong) self.player.durationChanged.connect(self.updateSongProgressRange) self.player.stateChanged.connect(self.playerStatusChanged) self.mediaControlArea.previousButton.click.connect( self.playlist.previous) self.mediaControlArea.repeatButton.click.connect( self.repeatButtonClick) self.mediaControlArea.stopButton.click.connect(self.stopButtonClick) self.mediaControlArea.playButton.click.connect(self.playButtonClick) self.mediaControlArea.randomButton.click.connect( self.randomButtonClick) self.mediaControlArea.nextButton.click.connect(self.playlist.next) self.mediaControlArea.muteButton.click.connect(self.mute) self.mediaControlArea.songProgress.sliderMoved.connect( self.songProgressMove) self.mediaControlArea.volumeControl.sliderMoved.connect( self.volumeChange) def setAreas(self) -> None: """Called after the GUI is created to provide user with a feedback that the program is running in case a larger amount of songs will be added when the Library class is initialized.""" # TODO add a tooltip that will notify the user larger amount of songs is being loaded # (freezes the program as the execution moves to the Library class.) self.library = library.Library() self.types = { "artist": self.library.getSongsForArtist, "album": self.library.getSongsForAlbum, "playlist": self.library.getSongsForPlaylist } self.mainArea.setAreas(self.library) self.setUpTimer.deleteLater() self.setUpTimer = None self.getSongs(self.displayedType, self.displayedName) if self.songListWidth is not None: songListGeometry = self.songList.geometry() self.songList.preferredWidth = songListGeometry.width( ) - self.songListWidth self.mainWindow.centralWidget().upperBox.line.resizeWidgets( songListGeometry.width() - self.songListWidth) def updateLibrary(self) -> None: self.library.update() self.mainArea.updateView(self.library) def updateCurrentSong(self) -> None: """Update all areas that may display information about the currently playing song - SongList, Now Playing tab, BottomBox""" media = self.player.currentMedia() self.currentSong = media.request().url().toLocalFile().replace( "/", "\\") if self.currentSong in self.library.library: self.songList.updateActiveSong(self.currentSong) self.mainArea.updateActiveSong(self.playlist.currentIndex()) songEntry = self.library.library[self.currentSong] self.mediaControlArea.updateSongInfo( f"{songEntry[ARTIST]} - {songEntry[NAME]}") def updateSongProgressRange(self) -> None: """Updates the range of the slider that represents the song position.""" self.mediaControlArea.updateSongProgressRange(self.player.duration()) def playerStatusChanged(self) -> None: """Used to properly update the player look after the current playlist has finished.""" index = self.playlist.currentIndex() if index == -1: self.stopButtonClick() def getSongs(self, isType: str, name: str) -> None: """Retrieves the songs for a given artist, album or playlist based on type and passes the resulting list to the SongList class.""" if isType is None: isType = self.displayedType if name is None: name = self.displayedName orderBy = self.songList.buttonOrderBy.text() reverse = True if self.songList.buttonOrderReverse.text() == chr( 0x25bc) else False listForType = self.types[isType](name, orderBy, reverse) playlist = None if isType == "playlist": playlist = name if len(listForType) == 0: artists = self.library.artists if len(artists): listForType = self.library.getSongsForArtist(artists[0]) self.songList.updateSongList(listForType, self.library.library, self.currentSong, playlist, isType) self.displayedType = isType self.displayedName = name def playSongList(self, song: str = None) -> None: """Called when user double-clicks on an artist/album/playlist widget or a song in right-hand side panel.""" self.playlist.clear() index = 0 loopIndex = 0 for songPath in self.songList.garbageProtector: if song == songPath: index = loopIndex self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(songPath))) loopIndex += 1 if self.playlist.isEmpty(): return self.player.play() if index > 0: self.playlist.setCurrentIndex(index) self.playing = True self.mediaControlArea.playButton.updatePictures( bottom.pausePixmap, bottom.pauseHoverPixmap, False) self.mainArea.setNowPlayingArea(self.library) self.mainArea.updateActiveSong(self.playlist.currentIndex()) def playSongWidget(self, songPath: str, afterCurrent: bool = False) -> None: if afterCurrent: index = self.playlist.currentIndex() + 1 self.playlist.insertMedia( index, QMediaContent(QUrl.fromLocalFile(songPath))) else: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(songPath))) self.mainArea.setNowPlayingArea(self.library) self.mainArea.updateActiveSong(self.playlist.currentIndex()) self.playing = True def removeFromNowPlaying(self, widget) -> None: if self.playlist.mediaCount() > 1: for row in range(self.mainArea.nowPlayingLayout.rowCount()): for column in range( self.mainArea.nowPlayingLayout.columnCount()): if self.mainArea.nowPlayingLayout.itemAtPosition( row, column).widget() is widget: self.playlist.removeMedia(row - 1) break else: continue break else: self.stopButtonClick() self.playlist.clear() self.mainArea.setNowPlayingArea(self.library) if self.playing: self.mainArea.updateActiveSong(self.playlist.currentIndex()) def playMediaWidget(self, isType: str, target: str, startOver: bool, afterCurrent: bool) -> None: """Called from MediaWidget - plays all songs for MediaWidget's type and name.""" if startOver: self.playlist.clear() if afterCurrent: index = self.playlist.currentIndex() + 1 for songPath in self.types[isType](target): self.playlist.insertMedia( index, QMediaContent(QUrl.fromLocalFile(songPath))) index += 1 else: for songPath in self.types[isType](target): self.playlist.addMedia( QMediaContent(QUrl.fromLocalFile(songPath))) if startOver: self.player.play() self.playing = True self.mediaControlArea.playButton.updatePictures( bottom.pausePixmap, bottom.pauseHoverPixmap, False) self.mainArea.setNowPlayingArea(self.library) self.mainArea.updateActiveSong(self.playlist.currentIndex()) def playFromNowPlaying(self, song: str) -> None: """Called when user double-clicks on a song in the Now Playing tab.""" for n in range(self.playlist.mediaCount()): media = self.playlist.media(n) if song == media.request().url().toLocalFile().replace("/", "\\"): self.playlist.setCurrentIndex(n) if not self.playing: self.player.play() self.playing = True return def createPlaylist(self, playlistName: str) -> None: self.library.createPlaylist(playlistName) self.mainArea.setMainAreaPlaylists(self.library) def addToExistingPlaylist(self, playlist: str, songOrWidget: str, isType: str) -> None: if isType in self.types: for song in self.types[isType](songOrWidget): self.library.addToPlaylist(playlist, song) else: self.library.addToPlaylist(playlist, songOrWidget) self.library.update() def removeFromPlaylist(self, playlist: str, song: str) -> None: self.library.deleteFromPlaylist(playlist, song) self.mainArea.setMainAreaPlaylists(self.library) self.library.update() self.getSongs("playlist", playlist) def renamePlaylist(self, playlistName: str, newPlaylistName: str) -> None: self.library.renamePlaylist(playlistName, newPlaylistName) self.mainArea.setMainAreaPlaylists(self.library) self.library.update() def deletePlaylist(self, playlistName: str) -> None: self.library.deletePlaylist(playlistName) self.mainArea.setMainAreaPlaylists(self.library) self.library.update() def addWatchedFolder(self, folder: str) -> None: """Adds a folder to the Library class. all mp3 files within the folder and its sub-folders will be added to the library and accessible to the player.""" self.library.addFolder(folder.replace("/", "\\")) self.mainArea.updateView(self.library) def removeWatchedFolder(self, folder: str) -> None: """Removes folder from the library, updates view and stops playback if the current song was in the now-removed folder.""" self.library.deleteFolder(folder) self.mainArea.updateView(self.library) if self.currentSong not in self.library.library: self.songList.updateSongList([], [], "", "") self.player.stop() self.playlist.clear() self.mediaControlArea.updateSongInfo("") self.songList.nowPlayingSong = None self.mainArea.nowPlayingSong = None self.playing = False self.mediaControlArea.updatePlayButton(self.playing, False) def playButtonClick(self, passMove: bool = True) -> None: if not self.playing: if self.playlist.isEmpty(): self.playSongList() return self.playing = True self.player.play() self.mainArea.updateActiveSong(self.playlist.currentIndex()) self.songList.updateActiveSong(self.currentSong) else: self.playing = False self.player.pause() self.mediaControlArea.updatePlayButton(self.playing, passMove) def repeatButtonClick(self) -> None: if self.repeat == 0: self.repeat = 1 self.playlist.setPlaybackMode(QMediaPlaylist.Loop) elif self.repeat == 1: self.repeat = 2 self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) elif self.repeat == 2: self.repeat = 0 self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.mediaControlArea.updateRepeatButton(self.repeat) def randomButtonClick(self) -> None: if not self.random: self.random = True self.playlist.setPlaybackMode(QMediaPlaylist.Random) else: self.random = False self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.mediaControlArea.updateRandomButton(self.random) def stopButtonClick(self) -> None: self.playing = False self.player.stop() if self.songList.nowPlayingSong is not None: self.songList.nowPlayingSong.clear() if self.mainArea.nowPlayingSong is not None: self.mainArea.nowPlayingSong.clear() self.mediaControlArea.updatePlayButton(self.playing, False) def mute(self) -> None: if not self.player.isMuted(): self.player.setMuted(True) self.mediaControlArea.showMute() else: self.player.setMuted(False) self.volumeChange(self.volume) def volumeChange(self, volume: int) -> None: logVolume = QAudio.convertVolume(volume / 100, QAudio.LogarithmicVolumeScale, QAudio.LinearVolumeScale) * 100 self.player.setVolume(logVolume) self.volume = volume self.mediaControlArea.updateVolumeBar(volume) def songProgressMove(self, position: int) -> None: self.player.setPosition(position) def updateSongProgress(self) -> None: position = self.player.position() if 0 <= position < 2_000_000_000: if self.player.state() > 0: self.mediaControlArea.updateSongProgress(position) if self.playing: self.songList.activeSongPixmap() self.mainArea.activeSongPixmap() else: self.mediaControlArea.updateSongProgress(0) def disconnect(self): self.player.currentMediaChanged.disconnect() self.player.durationChanged.disconnect() self.player.stateChanged.disconnect() self.mediaControlArea.previousButton.click.disconnect() self.mediaControlArea.repeatButton.click.disconnect() self.mediaControlArea.stopButton.click.disconnect() self.mediaControlArea.playButton.click.disconnect() self.mediaControlArea.randomButton.click.disconnect() self.mediaControlArea.nextButton.click.disconnect() self.mediaControlArea.muteButton.click.disconnect() self.mediaControlArea.songProgress.sliderMoved.disconnect() self.mediaControlArea.volumeControl.sliderMoved.disconnect() def close(self) -> None: self.disconnect() self.player.stop() self.mainTimer.stop() self.save() def save(self) -> None: """Called on exit, saves current view, geometry and volume.""" with gzip.open(r"musicplayer\mpdata", "wb") as fh: fh.write(self.MAGIC) toBeWritten = struct.pack(f"<h{len(self.displayedType.encode())}s", len(self.displayedType.encode()), self.displayedType.encode()) fh.write(toBeWritten) fh.write(self.MAGIC) toBeWritten = struct.pack(f"<h{len(self.displayedName.encode())}s", len(self.displayedName.encode()), self.displayedName.encode()) fh.write(toBeWritten) fh.write(self.MAGIC) geo = self.mainWindow.geometry() toBeWritten = struct.pack("<4h", geo.x(), geo.y(), geo.width(), geo.height()) fh.write(toBeWritten) toBeWritten = struct.pack("<h", self.volume) fh.write(toBeWritten) toBeWritten = struct.pack("<h", self.songList.width()) fh.write(toBeWritten) def load(self) -> [bool, tuple]: """Called on startup, loads view, geometry and volume saved on previous run.""" try: with gzip.open(r"musicplayer\mpdata", "rb") as fh: if not fh.read(2) == self.MAGIC: return False length = fh.read(2) length = struct.unpack("<h", length)[0] displayedType = fh.read(length) displayedType = struct.unpack(f"<{length}s", displayedType)[0].decode("utf8") if displayedType in ["artist", "album", "playlist"]: self.displayedType = displayedType if not fh.read(2) == self.MAGIC: return False length = fh.read(2) length = struct.unpack("<h", length)[0] displayedName = fh.read(length) displayedName = struct.unpack(f"<{length}s", displayedName)[0].decode("utf8") if not fh.read(2) == self.MAGIC: return False self.displayedName = displayedName variables = [] for n in range(6): var = fh.read(2) var = struct.unpack("<h", var)[0] variables.append(var) x, y, width, height, volume, songListWidth = variables self.volume = volume self.songListWidth = songListWidth return x, y, width, height except Exception: return False
class Reproductor(Genesis, QMainWindow): """ Instalar MatroskaSplitter y LAVFilters(Codecs), para que pueda reproducir videos y audio LAVFilters https://github.com/Nevcairiel/LAVFilters/releases MatroskaSplitter https://haali.su/mkv/ """ def __init__(self, *args, **kwargs): super(Reproductor, self).__init__() self.transcurso = 0 # Centramos la ventana principal self.centrar() # Inicializamos el modulo QMediaPlayer self.media = QMediaPlayer() self.media.setVolume(5) self.reproducir.setEnabled(False) # Setup the playlist. self.lista_repro = QMediaPlaylist() self.media.setPlaylist(self.lista_repro) self.modelo = ListaModelo(self.lista_repro) self.lista.setModel(self.modelo) self.lista_repro.currentIndexChanged.connect(self.cambio_lista_repro) modelo_seleccion = self.lista.selectionModel() modelo_seleccion.selectionChanged.connect(self.seleccion_lista_repro) # ********** Inicializamos el modulo QVideoWidget ******* self.video = QVideoWidget() # Agregamos el modulo QVideoWidget al grid donde se mostrara el video self.reproductor.addWidget(self.video) # Tambien lo agregamos al modulo QMediaPlayer self.media.setVideoOutput(self.video) # Conectamos el boton de reproducir con su metodo correspondiente self.reproducir.clicked.connect(self.play_video) # Conectamos el Skider del tiempo con su metodo correspondiente self.tiempo.sliderMoved.connect(self.posicion_establecida) # ****** Conectamos los estados del modulo QMediaPlayer con sus correspondientes metodos ***** self.media.stateChanged.connect(self.cambios_video) self.media.positionChanged.connect(self.posicion_video) self.media.durationChanged.connect(self.duracion_video) self.total_duracion = 0 self.cargar.clicked.connect(self.abrir_archivo) #self.marco.origen.connect(self.arrastrar_soltar) self.parar.pressed.connect(self.media.stop) self.atras.pressed.connect(self.lista_repro.previous) self.adelante.pressed.connect(self.lista_repro.next) self.volumen.valueChanged.connect(self.media.setVolume) self.logo_volumen.clicked.connect(self.silenciar) self.lista.doubleClicked.connect(self.play_video) self.video.keyPressEvent = self.keyPressEvent # ****** Boton de menu ****** self.lista.setMinimumSize(QSize(0, 0)) self.lista_visible = True self.menu.clicked.connect(self.boton_menu) self.setAcceptDrops(True) self.primera_reproduccion = True self.show() # ---------------- Inicio de Metodos --------------------------- # # Detectamos una tecla presionada def keyPressEvent(self, event): if event.key() == Qt.Key_F11 or event.key() == Qt.Key_Escape and self.video.isFullScreen(): self.fullscreen_change() elif event.key() == Qt.Key_Space: self.play_video() #Pantalla completa def fullscreen_change(self): if self.video.isFullScreen(): self.video.setFullScreen(False) self.lista.setMinimumSize(QSize(300, 16777215)) else: self.video.setFullScreen(True) # Ocultar y mostrar la lista de reproduccion def boton_menu(self): if self.lista_visible: self.lista.setVisible(False) size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.marco.setSizePolicy(size_policy) self.lista_visible = False else: self.lista.setVisible(True) self.lista_visible = True # Metodos para arrastrar y soltar en la lista de reproduccion def dragEnterEvent(self, e): if e.mimeData().hasUrls(): e.acceptProposedAction() # Metodos para arrastrar y soltar en la lista de reproduccion def dropEvent(self, e): for url in e.mimeData().urls(): self.lista_repro.addMedia(QMediaContent(url)) self.lista_repro.setPlaybackMode(QMediaPlaylist.Loop) self.media.setPlaylist(self.lista_repro) self.reproducir.setEnabled(True) self.reproductor.removeWidget(self.logo) self.media.play() self.modelo.layoutChanged.emit() """ # If not playing, seeking to first of newly added + play. if self.media.state() != QMediaPlayer.PlayingState: #i = self.lista_repro.mediaCount() - len(e.mimeData().urls()) #print(i) #self.lista_repro.setCurrentIndex(i) self.reproducir.setEnabled(True) self.reproductor.removeWidget(self.logo) #self.media.setPlaylist(playlist) self.media.play() """ # Metodo para cargar el video en cuestion def abrir_archivo(self): archivo, _ = QFileDialog.getOpenFileName(self, ' Abrir Archivo !!!', 'C:/Users/Duque/Videos', 'Solo Video (*.mp4 *.mov *.flv *.mkv *.ts *.mts *.avi);; Solo Audio (*.mp3 *.flac *.m4a *.wav)') if archivo != '': self.reproductor.removeWidget(self.logo) self.primera_reproduccion = False self.lista_repro.addMedia(QMediaContent(QUrl.fromLocalFile(archivo))) self.reproducir.setEnabled(True) self.modelo.layoutChanged.emit() # Metodo para el cambio en la lista de reproduccion def cambio_lista_repro(self, i): if i > -1: ix = self.modelo.index(i) self.lista.setCurrentIndex(ix) # Metodo para la seleccion en la lista de reproduccion def seleccion_lista_repro(self, ix): i = ix.indexes()[0].row() self.lista_repro.setCurrentIndex(i) # Metodo para silenciar el audio o video def silenciar(self): if self.media.isMuted(): self.media.setMuted(False) icon = QIcon() icon.addPixmap(QPixmap(":/img/altavoz3.png"), QIcon.Normal, QIcon.Off) self.logo_volumen.setIcon(icon) self.logo_volumen.setToolTip(' Silenciar ') else: self.media.setMuted(True) icon = QIcon() icon.addPixmap(QPixmap(":/img/altavoz4.png"), QIcon.Normal, QIcon.Off) self.logo_volumen.setIcon(icon) self.logo_volumen.setToolTip(' Restablecer Sonido ') @pyqtSlot(str) def arrastrar_soltar(self, archivo): if archivo != '': self.media.setMedia(QMediaContent(QUrl.fromLocalFile(archivo))) self.reproducir.setEnabled(True) self.lista_repro.addMedia(QMediaContent(QUrl.fromLocalFile(archivo))) self.modelo.layoutChanged.emit() # Metodo para reproducir el video en cuestion def play_video(self): if self.primera_reproduccion: self.reproductor.removeWidget(self.logo) self.primera_reproduccion = False if self.media.state() == QMediaPlayer.PlayingState: self.media.pause() else: self.media.play() # Metodo que detecta el estado de cambio del boton reproducir de play a pausa y viceversa def cambios_video(self, state): if self.media.state() == QMediaPlayer.PlayingState: icon = QIcon() icon.addPixmap(QPixmap(":/img/pausa.png"), QIcon.Normal, QIcon.Off) self.reproducir.setIcon(icon) self.reproducir.setToolTip(' Pausar Video o Audio ') QToolTip.setFont(QFont('Cascadia Code PL', 18)) else: icon = QIcon() icon.addPixmap(QPixmap(":/img/play.svg"), QIcon.Normal, QIcon.Off) self.reproducir.setIcon(icon) self.reproducir.setToolTip(' Reproducir Video o Audio ') QToolTip.setFont(QFont('Cascadia Code PL', 18)) def duracion_video(self, duracion): """ # Detecta la duración del vídeo en el slider. """ self.tiempo.setMaximum(duracion) self.total_duracion = duracion # Metodo que detecta la posiscion del video en el slider def posicion_video(self, posicion): if posicion >= 0: reproduccion = f'{detalle_tiempo(posicion)} || {detalle_tiempo(self.total_duracion)}' self.datos.setText(reproduccion) self.tiempo.blockSignals(True) self.tiempo.setValue(posicion) self.tiempo.blockSignals(False) # Metodo que detecta la posiscion establecida del modulo QMediaPlayer def posicion_establecida(self, position): self.media.setPosition(position) def errores(self): self.reproducir.setEnabled(False) # self.lbl.setText("Error: " + self.media.errorString()) # Metodo para centrar la ventana principal def centrar(self): ventana = self.frameGeometry() centro = QDesktopWidget().availableGeometry().center() # print(centro) ventana.moveCenter(centro) self.move(ventana.topLeft())
class MainWindow(ui_mainwindow, qtbaseclass): # 详情页面 detail = None # 播放列表dock栏,初始隐藏 playListDockView = None # 当前播放列表 playList = [] # 当前播放的歌曲在列表中的索引号 songIndex = 0 # 当前播放的歌曲 song = None # 播放器 player = None # api func = netease # 是否循环播放 loop = True # 记录上次音量值 lastVolume = 0 def __init__(self, parent=None): if parent == None: parent = self ui_mainwindow.__init__(parent) qtbaseclass.__init__(parent) self.setupUi(self) self.setWindowTitle("Music") self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.setWindowIcon(QIcon('resource/format.ico')) with open('QSS/mainWindow.qss', 'r') as f: style = f.read() self.setStyleSheet(style) # 初始化 self.initList() self.initPlayWidgets() self.initTabWidgets() self.initDetailView() self.initPlayListDockView() def initList(self): # 初始化列表信息 # 设置推荐列表 self.recommandList.addItem( QListWidgetItem(QIcon('resource/music.png'), " 发现音乐")) self.recommandList.addItem( QListWidgetItem(QIcon('resource/signal.png'), " 私人FM")) self.recommandList.addItem( QListWidgetItem(QIcon('resource/movie.png'), " MV")) self.recommandList.setCurrentRow(0) # 设置我的音乐 self.myList.addItem( QListWidgetItem(QIcon('resource/notes.png'), " 本地音乐")) # 设置收藏与创建的歌单 # 未实现(动态添加) def initPlayWidgets(self): ''' 初始化播放控件状态''' self.player = QMediaPlayer(self) # self.player.setVolume(100) # 设置音量同时设置进度条 self.volumeSlider.setValue(100) self.player.stateChanged.connect(self.slot_player_stateChanged) self.player.positionChanged.connect(self.slot_player_positionChanged) self.player.durationChanged.connect(self.slot_player_durationChanged) # 隐藏暂停按键 self.pauseButton.hide() self.noVolume.hide() def initTabWidgets(self): # 初始化主窗口中TabWdidget self.detailView.hide() self.tabWidget.clear() netEase = SongsFrame(self) self.tabWidget.addTab(netEase, '网易云音乐') def initDetailView(self): # 初始化详情页 self.detail = AlbumDetailView(self) self.detailView.setWidget(self.detail) self.detail.addSongs.connect(self.slot_addSongs) def initPlayListDockView(self): # 主显示区域添加播放列表DOCK self.playListDockView = PlayListDockWidget(self) self.playListDockView.hide() # 初始状态为隐藏 self.playListDockView.doubleClicked.connect( self.slot_playList_doubleClicked) self.mainHorizontalLayout.addWidget(self.playListDockView) def mouseMoveEvent(self, event): if event.buttons() == QtCore.Qt.MiddleButton: # if event.globalPos().x() > self.pos().x(): # print("Y") # else: # print('N') self.move(event.globalPos()) event.accept() else: super().mouseMoveEvent(event) def slot_prev_page_clicked(self): '''上一页''' if self.tabWidget.isHidden(): self.tabWidget.show() self.detailView.hide() def slot_next_page_clicked(self): '''下一页''' # if self.detailView.isHidden(): # self.tabWidget.hide() # self.detailView.show() pass def slot_prev_song_clicked(self): '''上一首歌''' self.player.stateChanged.disconnect() self.songIndex = self.songIndex - 1 if self.songIndex < 0: self.songIndex = 0 else: self.song = self.playList[self.songIndex] if self.set_player_media(): self.player.play() self.playListDockView.setSelectRow(self.songIndex) self.player.stateChanged.connect(self.slot_player_stateChanged) def slot_next_song_clicked(self): '''下一首歌''' self.player.stateChanged.disconnect() self.songIndex = (self.songIndex + 1) % len(self.playList) self.song = self.playList[self.songIndex] if self.set_player_media(): self.player.play() self.playListDockView.setSelectRow(self.songIndex) self.player.stateChanged.connect(self.slot_player_stateChanged) def slot_play_clicked(self): '''播放 点击事件''' if self.player.mediaStatus() > 1 and self.player.mediaStatus() < 7: self.player.play() else: # 未添加 音乐 QMessageBox.warning(self, '警告', '播放列表为空!请先添加音乐到播放列表。') def slot_pause_clicked(self): '''暂停 点击事件''' self.player.pause() # self.playButton.show() # self.pauseButton.hide() def slot_addSongs(self, songsList): '''添加歌曲''' # 去重合并列表 ids = [x.id for x in self.playList] for song in songsList: if song.id not in ids: self.playList.append(song) # 播放列表变化,更新列表显示 self.playListDockView.setList(self.playList) # 初始化song if self.song == None: self.song = self.playList[self.songIndex] self.set_player_media() def slot_player_stateChanged(self): '''播放器状态变化''' if not self.playList: return if self.player.state() == QMediaPlayer.StoppedState: if self.loop: self.songIndex = (self.songIndex + 1) % len(self.playList) self.song = self.playList[self.songIndex] if self.set_player_media(): self.player.play() else: self.playButton.show() self.pauseButton.hide() elif self.player.state() == QMediaPlayer.PausedState: self.playButton.show() self.pauseButton.hide() elif self.player.state() == QMediaPlayer.PlayingState: self.playButton.hide() self.pauseButton.show() self.countTime.setText(self.song.time) def slot_player_positionChanged(self, pos): '''播放时间改变控件位置''' t = pos / 1000 mins = t // 60 secs = t % 60 curTime = QtCore.QTime(0, mins, secs).toString('mm:ss') self.currentTime.setText(curTime) self.timeSlider.setValue(pos) def slot_player_durationChanged(self, duration): '''设置进度条最大值''' self.timeSlider.setRange(0, duration) def set_player_media(self): '''设置播放器音乐媒体,成功返回True,否则False''' try: mp3 = self.func.singsUrl([self.song.id]) if mp3: mp3 = mp3[0]['url'] self.player.setMedia(QMediaContent(QtCore.QUrl(mp3))) return True except: # 网络异常 QMessageBox.warning(self, '获取音乐地址失败!请检查网络后重试!', '警告') return False def slot_playList_clicked(self): '''播放列表按钮 点击事件''' if self.playListDockView.isHidden(): self.playListDockView.show() else: self.playListDockView.hide() def slot_playList_doubleClicked(self, songIndex): '''播放列表双击事件 songIndex -- 为当前双击歌曲在列表中的索引号。 执行动作:立即播放该歌曲 ''' self.songIndex = songIndex if self.set_player_media(): self.player.play() def slot_volumeSlider_valueChanged(self, value): '''音量调节''' self.player.setVolume(value) if value == 0: self.noVolume.show() self.volume.hide() else: self.noVolume.hide() self.volume.show() def slot_noVolume_clicked(self): '''静音按钮点击事件,动作:切成原始音量''' # self.volumeSlider.setValue(0) self.player.setMuted(False) self.noVolume.hide() self.volume.show() def slot_volume_clicked(self): '''音量按钮点击事件,动作:切成静音''' # self.volumeSlider.setValue(0) self.player.setMuted(True) self.noVolume.show() self.volume.hide()
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.ui = loadUi('forms/mainwindow.ui', self) # self.ui = Ui_MainWindow() # self.ui.setupUi(self) self.input_name = None self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoWidget = VideoWidget(self) self.detector = CellDetector() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.videoWidget) self.ui.videoFrame.setLayout(layout) self.ui.playButton.setEnabled(False) self.ui.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) self.ui.playButton.clicked.connect(self.play) self.ui.openButton.clicked.connect(self.openFile) self.ui.saveButton.clicked.connect(self.saveFile) self.ui.saveButton.setEnabled(False) self.ui.timeSlider.sliderMoved.connect(self.setPosition) self.ui.modeCheckBox.stateChanged.connect(self.switchMode) self.ui.statusbar: QStatusBar self.ui.statusbar.showMessage("Init Model ...") # self.ui.statusbar.setLayout() self.mediaPlayer.setVideoOutput(self.videoWidget.videoSurface()) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.setMuted(True) # shortcut QShortcut(QKeySequence('Space'), self).activated.connect(self.play) # s_max = self.maximumSize() # # self.ui.statusBar.setSizeGripEnabled(False) # self.show() # self.setFixedSize(s_max) def showEvent(self, *args, **kwargs): self.detector.onInitModelSuccess.connect( lambda: self.ui.statusbar.showMessage("Ready")) self.detector.initModel() def closeEvent(self, *args, **kwargs): QApplication.closeAllWindows() def switchMode(self, state): self.detector.setMode(state) self.startProcess() def startProcess(self): if self.input_name: self.ui.listWidget.clear() self.sum_cells = 0 self.log = [] self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(self.input_name))) self.cap = cv2.VideoCapture(self.input_name) VideoInfo.init(self.cap) self.frameCount = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT)) fps = np.ceil(self.cap.get(cv2.CAP_PROP_FPS)) window_time = 2 # sec dialog = ProcessDialog(self) dialog.setMaximum(self.frameCount) map_worker = ObjectMapper(self.frameCount, fps) map_worker.onUpdateObject.connect(self.updateObject) map_worker.onUpdateProgress.connect(dialog.updateProgress) ppc_worker = PreprocessThread(self.input_name) ppc_worker.onFrameChanged.connect(map_worker.updateOpticalFlow) ppc_worker.onFrameChanged.connect(self.detector.updateOpticalFlow) ppc_worker.onBufferReady.connect(self.detector.detect) ppc_worker.onUpdateProgress.connect(dialog.updateProgress) map_worker.onNewDetectedCells.connect(self.updateDetectLog) map_worker.finished.connect(dialog.close) dialog.closed.connect(ppc_worker.quit) dialog.closed.connect(map_worker.quit) self.detector.onDetectSuccess.connect(map_worker.queueOutput) # ppc_worker.finished.connect(dialog.close) # dialog.onReady2Read.connect(self.setOutput) dialog.show() map_worker.start() ppc_worker.start() dialog.exec_() self.ui.playButton.setEnabled(True) self.ui.saveButton.setEnabled(True) def openFile(self): file_name = QFileDialog.getOpenFileName(self, "Open Video")[0] if os.path.exists(file_name): self.input_name = file_name self.startProcess() def saveFile(self): dialog = SaveDialog() dialog.exec_() head, tail = os.path.split(self.input_name) file_prefix = tail.split('.')[0] worker = VideoWriterThread(self.cap, self.frame_objects, self.log, file_prefix, dialog.getSaveDirectory(), dialog.isSaveImage, dialog.isSaveVideo) worker.start() def updateObject(self, frame_objects): self.frame_objects = frame_objects duration = self.mediaPlayer.duration() self.videoWidget.setOutput(frame_objects, duration / self.frameCount) self.ui.playButton.setEnabled(True) self.ui.saveButton.setEnabled(True) def updateDetectLog(self, detected_frame_id, cell_map, cell_count): # append log widget = QCustomQWidget() self.sum_cells += cell_count self.cap.set(cv2.CAP_PROP_POS_FRAMES, detected_frame_id) _, image = self.cap.read() _, min, sec = getHHMMSSFormat(self.mediaPlayer.duration() / self.frameCount * detected_frame_id) time_text = '{:02}-{:02}'.format(min, sec) self.log.append({ "image": image.copy(), "detect_time": time_text, "cells": cell_map }) drawBoxes(image, cell_map, (0, 255, 0)) icon = imutils.resize(image, height=64) icon = toQImage(icon) widget.setPreviewImg(icon) widget.setCount(cell_count) widget.setDetectionFramePosition(self.mediaPlayer.duration() / self.frameCount * detected_frame_id) widget.setTimeText('{:02}:{:02}'.format(min, sec)) # widget.onDoubleClick.connect(self.positionChanged) widget.onDoubleClick.connect(self.setPosition) list_widget_item = QListWidgetItem(self.ui.listWidget) list_widget_item.setSizeHint(widget.size()) self.ui.listWidget.addItem(list_widget_item) self.ui.listWidget.setItemWidget(list_widget_item, widget) self.ui.totalNumber.display(self.sum_cells) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if state == QMediaPlayer.PlayingState: self.ui.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.ui.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.ui.timeSlider.setValue(position) duration = self.mediaPlayer.duration() _, dmin, dsec = getHHMMSSFormat(duration) _, pmin, psec = getHHMMSSFormat(position) self.ui.timeLabel.setText('{:02}:{:02}/{:02}:{:02}'.format( int(pmin), int(psec), int(dmin), int(dsec))) def durationChanged(self, duration): self.ui.timeSlider.setRange(0, duration) _, dmin, dsec = getHHMMSSFormat(duration) self.ui.timeLabel.setText('00:00/{:02}:{:02}'.format( int(dmin), int(dsec))) def setPosition(self, position): self.mediaPlayer.setPosition(position)
class VideoWindow(QMainWindow): def __init__(self, parent=None): super(VideoWindow, self).__init__(parent) self.settings = QSettings("CropMe", "CropMe App") self.setWindowTitle("CropMe") self.directory = self.settings.value("directory", QDir.homePath(), str) self.position = 0 self.frameMovementThreshold = 500 self.initFrame = -1 self.finalFrame = -1 self.latestvideo = '' self.autoplay = self.settings.value("autoplay", False, bool) 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.initFrameButton = QPushButton() self.initFrameButton.setEnabled(False) self.initFrameButton.setText('Set Initial Frame') self.initFrameButton.clicked.connect(self.setInitFrame) self.finalFrameButton = QPushButton() self.finalFrameButton.setEnabled(False) self.finalFrameButton.setText('Set Final Frame') self.finalFrameButton.clicked.connect(self.setFinalFrame) self.cropButton = QPushButton() self.cropButton.setEnabled(False) self.cropButton.setText('Crop Video') self.cropButton.clicked.connect(self.crop) self.watchnewvid = QPushButton() self.watchnewvid.setEnabled(False) self.watchnewvid.setText('Watch Cropped Video') self.watchnewvid.clicked.connect(self.opencv_playvideo) self.deleteButton = QPushButton() self.deleteButton.setEnabled(False) self.deleteButton.setText('Delete Original Video') self.deleteButton.clicked.connect(self.deleteOriginalVideo) self.autoplayCheck = QCheckBox("Autoplay after cropping?", self) self.autoplayCheck.setChecked( self.settings.value("autoplay", False, bool)) self.autoplayCheck.stateChanged.connect(self.autoplaySwitch) self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) self.currentTimeLabel = QLabel() self.currentTimeLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.totalTimeLabel = QLabel() self.totalTimeLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) self.fileName = QLabel() self.fileName.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # Create new action openAction = QAction(QIcon('open.png'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open movie') openAction.triggered.connect(self.openFile) # Create exit action exitAction = QAction(QIcon('exit.png'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.exitCall) # Create Next Frame action fowardAction = QAction(QIcon('SP_ArrowForward'), '&Foward', self) fowardAction.setShortcut('.') fowardAction.setStatusTip('Next Frame') fowardAction.triggered.connect(self.nextFrame) # Create Previous Frame action backAction = QAction(QIcon('SP_ArrowBack'), '&Back', self) backAction.setShortcut(',') backAction.setStatusTip('Back Frame') backAction.triggered.connect(self.prevFrame) # Create Play action playAction = QAction(QIcon('space'), '&space', self) playAction.setShortcut(' ') playAction.setStatusTip('Play/Pause') playAction.triggered.connect(self.play) # Create menu bar and add action menuBar = self.menuBar() fileMenu = menuBar.addMenu('&File') editMenu = menuBar.addMenu('&Edit') editMenu.addAction(backAction) editMenu.addAction(fowardAction) editMenu.addAction(playAction) # fileMenu.addAction(newAction) fileMenu.addAction(openAction) fileMenu.addAction(exitAction) # Create a widget for window contents wid = QWidget(self) self.setCentralWidget(wid) # Create layouts to place inside widget controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) controlLayout.addWidget(self.currentTimeLabel) controlLayout.addWidget(self.totalTimeLabel) lay = QHBoxLayout() lay.addWidget(self.initFrameButton) lay.addWidget(self.finalFrameButton) watch = QHBoxLayout() watch.addWidget(self.watchnewvid) watch.addWidget(self.autoplayCheck) layout = QVBoxLayout() layout.addWidget(self.fileName) layout.addWidget(videoWidget) layout.addLayout(controlLayout) layout.addLayout(lay) layout.addWidget(self.cropButton) layout.addWidget(self.deleteButton) layout.addLayout(watch) layout.addWidget(self.errorLabel) # Set widget to contain window contents wid.setLayout(layout) self.mediaPlayer.setVideoOutput(videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError) def opencv_playvideo(self): video = cv2.VideoCapture(self.latestvideo) frames_counter = 1 #fps = video.get(cv2.CAP_PROP_FPS) while True: frames_counter = frames_counter + 1 check, frame = video.read() if check: cv2.imshow("Capturing", frame) key = cv2.waitKey(15) else: break video.release() cv2.destroyAllWindows() def autoplaySwitch(self): self.autoplay = not self.autoplay self.settings.setValue("autoplay", self.autoplay) def openFile(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName(parent=self, caption="Open Movie", directory=self.directory, options=options) if fileName != '': self.settings.setValue("directory", fileName) self.mediaPlayer.setMedia( QMediaContent(QUrl.fromLocalFile(fileName))) self.playButton.setEnabled(True) self.mediaPlayer.setMuted(True) self.initFrameButton.setEnabled(True) self.finalFrameButton.setEnabled(True) self.initFrame = -1 self.finalFrame = -1 self.cropButton.setEnabled(False) self.deleteButton.setEnabled(True) self.watchnewvid.setEnabled(False) self.initFrameButton.setText('Set Initial Frame') self.finalFrameButton.setText('Set Final Frame') self.play() self.directory = fileName self.fileName.setText(os.path.basename(self.directory)) def ffmpeg_cut(self, filename, start_time, end_time, outfilename): os.chdir(os.path.dirname(filename)) subprocess.call([ 'ffmpeg', "-ss", "%.2f" % start_time, "-i", filename, "-t", "%.2f" % end_time, outfilename ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def setInitFrame(self): self.initFrameButton.setText("Set Initial Frame: " + self.hhmmss(self.position)) self.initFrame = self.position if self.initFrame >= 0 and self.finalFrame >= 0: self.cropButton.setEnabled(True) def setFinalFrame(self): self.finalFrameButton.setText('Set Final Frame: ' + self.hhmmss(self.position)) self.finalFrame = self.position if self.initFrame >= 0 and self.finalFrame >= 0: self.cropButton.setEnabled(True) def exitCall(self): sys.exit(app.exec_()) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() self.resize(self.width(), self.height() + 1) else: self.mediaPlayer.play() self.resize(self.width(), self.height() - 1) def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) self.position = position if position >= 0: self.currentTimeLabel.setText(self.hhmmss(position)) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) if duration >= 0: self.totalTimeLabel.setText(self.hhmmss(duration)) self.finalFrame = duration self.finalFrameButton.setText('Set Final Frame: ' + self.hhmmss(duration)) def setPosition(self, position): self.mediaPlayer.setPosition(position) def hhmmss(self, ms): mss = (ms % 1000) s = (ms / 1000) % 60 m = (ms / (1000 * 60)) % 60 h = (ms / (1000 * 60 * 60)) % 24 return ("%d:%02d:%02d:%d" % (h, m, s, mss)) if h > 0 else ("%d:%02d:%d" % (m, s, mss)) def handleError(self): self.playButton.setEnabled(False) self.errorLabel.setText("Error: " + self.mediaPlayer.errorString()) def nextFrame(self): self.setPosition(self.position + self.frameMovementThreshold) def prevFrame(self): self.setPosition(self.position - 2 * self.frameMovementThreshold) def crop(self): i = 0 while True: newFileName = os.path.dirname( self.directory) + f"/{i}_" + os.path.basename(self.directory) if not os.path.isfile(newFileName): self.ffmpeg_cut(self.directory, (self.initFrame / 1000), (self.finalFrame / 1000), newFileName) self.watchnewvid.setEnabled(True) self.latestvideo = newFileName if self.autoplay: self.opencv_playvideo() break i += 1 def deleteOriginalVideo(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.play() buttonReply = QMessageBox.question( self, 'Warning message', f"Would you like to delete {os.path.basename(self.directory)}?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: os.remove(self.directory)
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 QgsFmvPlayer(QMainWindow, Ui_PlayerWindow): """ Video Player Class """ def __init__(self, iface, path, parent=None, meta_reader=None, pass_time=None, initialPt=None, isStreaming=False): """ Constructor """ super(QgsFmvPlayer, self).__init__(parent) self.setupUi(self) self.parent = parent self.iface = iface self.fileName = path self.initialPt = initialPt self.meta_reader = meta_reader self.isStreaming = isStreaming self.createingMosaic = False self.currentInfo = 0.0 self.data = None # Create Draw Toolbar self.DrawToolBar.addAction(self.actionMagnifying_glass) self.DrawToolBar.addSeparator() # Draw Polygon QToolButton self.toolBtn_DPolygon.setDefaultAction(self.actionDraw_Polygon) self.DrawToolBar.addWidget(self.toolBtn_DPolygon) # Draw Point QToolButton self.toolBtn_DPoint.setDefaultAction(self.actionDraw_Pinpoint) self.DrawToolBar.addWidget(self.toolBtn_DPoint) # Draw Point QToolButton self.toolBtn_DLine.setDefaultAction(self.actionDraw_Line) self.DrawToolBar.addWidget(self.toolBtn_DLine) self.DrawToolBar.addAction(self.actionRuler) self.DrawToolBar.addSeparator() # # Censure QToolButton # self.toolBtn_Cesure.setDefaultAction(self.actionCensure) # self.DrawToolBar.addWidget(self.toolBtn_Cesure) # self.DrawToolBar.addSeparator() # # # Object Tracking # self.DrawToolBar.addAction(self.actionObject_Tracking) self.toolBtn_Cesure.setVisible(False) # Hide Color Button self.btn_Color.hide() self.RecGIF = QMovie(":/imgFMV/images/record.gif") self.videoWidget.customContextMenuRequested[QPoint].connect( self.contextMenuRequested) self.menubarwidget.customContextMenuRequested[QPoint].connect( self.contextMenuBarRequested) self.duration = 0 self.playerMuted = False self.HasFileAudio = False self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.pass_time = pass_time self.player.setNotifyInterval(700) # Metadata Callback Interval self.playlist = QMediaPlaylist() self.player.setVideoOutput( self.videoWidget.videoSurface()) # Abstract Surface self.player.durationChanged.connect(self.durationChanged) self.player.positionChanged.connect(self.positionChanged) self.player.mediaStatusChanged.connect(self.statusChanged) self.player.stateChanged.connect(self.setCurrentState) self.playerState = QMediaPlayer.LoadingMedia self.playFile(path) self.sliderDuration.setRange(0, self.player.duration() / 1000) self.volumeSlider.setValue(self.player.volume()) self.volumeSlider.enterEvent = self.showVolumeTip self.metadataDlg = QgsFmvMetadata(parent=self, player=self) self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg) self.metadataDlg.setMinimumWidth(500) self.metadataDlg.hide() self.converter = Converter() self.BitratePlot = CreatePlotsBitrate() def HasAudio(self, videoPath): """ Check if video have Metadata or not """ try: p = _spawn([ '-i', videoPath, '-show_streams', '-select_streams', 'a', '-preset', 'ultrafast', '-loglevel', 'error' ], t="probe") stdout_data, _ = p.communicate() if stdout_data == b'': qgsu.showUserAndLogMessage( QCoreApplication.translate( "QgsFmvPlayer", "This video doesn't have Audio ! ")) self.actionAudio.setEnabled(False) self.actionSave_Audio.setEnabled(False) return False return True except Exception as e: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Audio check Failed! : "), str(e)) self.actionAudio.setEnabled(False) self.actionSave_Audio.setEnabled(False) def get_metadata_from_buffer(self, currentTime): """ Metadata CallBack """ try: # There is no way to spawn a thread and call after join() without blocking the video UI thread. # callBackMetadata can be as fast as possible, it will always create a small video lag every time meta are read. # To get rid of this, we fill a buffer (BufferedMetaReader) in the QManager with some Metadata in advance, # and hope they'll be ready to read here in a totaly non-blocking # way (increase the buffer size if needed in QManager). stdout_data = self.meta_reader.get(currentTime) # qgsu.showUserAndLogMessage( # "", "stdout_data: " + str(stdout_data) + " currentTime: " + str(currentTime), onlyLog=True) if stdout_data == 'NOT_READY': self.metadataDlg.menuSave.setEnabled(False) qgsu.showUserAndLogMessage( "", "Buffer value read but is not ready, increase buffer size. : ", onlyLog=True) return #Values need to be read, pause the video a short while elif stdout_data == 'BUFFERING': qgsu.showUserAndLogMessage("Buffering metadata...", "", duration=4, level=QGis.Info) self.player.pause() QTimer.singleShot(2500, lambda: self.player.play()) return elif stdout_data == b'' or len(stdout_data) == 0: self.metadataDlg.menuSave.setEnabled(False) qgsu.showUserAndLogMessage( "", "Buffer returned empty metadata, check pass_time. : ", onlyLog=True) return self.packetStreamParser(stdout_data) except Exception as inst: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Metadata Buffer Failed! : "), str(inst)) def packetStreamParser(self, stdout_data): ''' Common packet process''' for packet in StreamParser(stdout_data): try: if isinstance(packet, UnknownElement): qgsu.showUserAndLogMessage( "Error interpreting klv data, metadata cannot be read.", "the parser did not recognize KLV data", level=QGis.Warning, onlyLog=True) continue data = packet.MetadataList() self.data = data if self.metadataDlg.isVisible( ): # Only add metada to table if this QDockWidget is visible (speed plugin) self.metadataDlg.menuSave.setEnabled(True) self.addMetadata(data) UpdateLayers(packet, parent=self, mosaic=self.createingMosaic) QApplication.processEvents() return except Exception: None # qgsu.showUserAndLogMessage(QCoreApplication.translate( # "QgsFmvPlayer", "Meta update failed! "), " Packet:" + str(packet) + ", error:" + str(inst), level=QGis.Warning) def callBackMetadata(self, currentTime, nextTime): """ Metadata CallBack """ try: port = int(self.fileName.split(':')[2]) t = callBackMetadataThread(cmds=[ '-i', self.fileName.replace(str(port), str( port + 1)), '-ss', currentTime, '-to', nextTime, '-map', 'data-re', '-preset', 'ultrafast', '-f', 'data', '-' ]) t.start() t.join(1) if t.is_alive(): t.p.terminate() t.join() qgsu.showUserAndLogMessage("", "callBackMetadataThread self.stdout: " + str(t.stdout), onlyLog=True) if t.stdout == b'': return self.packetStreamParser(t.stdout) except Exception as e: qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Metadata Callback Failed! : "), str(e)) def GetPacketData(self): ''' Return Current Packet data ''' return self.data def addMetadata(self, packet): ''' Add Metadata to List ''' self.clearMetadata() row = 0 for key in sorted(packet.keys()): self.metadataDlg.VManager.insertRow(row) self.metadataDlg.VManager.setItem(row, 0, QTableWidgetItem(str(key))) self.metadataDlg.VManager.setItem( row, 1, QTableWidgetItem(str(packet[key][0]))) self.metadataDlg.VManager.setItem( row, 2, QTableWidgetItem(str(packet[key][1]))) row += 1 self.metadataDlg.VManager.setVisible(False) self.metadataDlg.VManager.resizeColumnsToContents() self.metadataDlg.VManager.setVisible(True) self.metadataDlg.VManager.verticalScrollBar().setSliderPosition( self.sliderPosition) def clearMetadata(self): ''' Clear Metadata List ''' try: self.sliderPosition = self.metadataDlg.VManager.verticalScrollBar( ).sliderPosition() self.metadataDlg.VManager.setRowCount(0) except Exception: None def saveInfoToJson(self): """ Save video Info to json """ out_json, _ = askForFiles(self, QCoreApplication.translate( "QgsFmvPlayer", "Save Json"), isSave=True, exts="json") if not out_json: return taskSaveInfoToJson = QgsTask.fromFunction( 'Save Video Info to Json Task', self.converter.probeToJson, fname=self.fileName, output=out_json, on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskSaveInfoToJson) return def showVideoInfo(self): ''' Show default probe info ''' taskSaveInfoToJson = QgsTask.fromFunction( 'Show Video Info Task', self.converter.probeShow, fname=self.fileName, on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskSaveInfoToJson) return def state(self): ''' Return Current State ''' return self.playerState def setCurrentState(self, state): ''' Set Current State ''' if state != self.playerState: self.playerState = state if state == QMediaPlayer.StoppedState: self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png")) return def showColorDialog(self): ''' Show Color dialog ''' self.ColorDialog = ColorDialog(parent=self) self.ColorDialog.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint) # Fail if not uncheked self.actionMagnifying_glass.setChecked(False) self.ColorDialog.exec_() QApplication.processEvents() self.ColorDialog.contrastSlider.setValue(80) self.ColorDialog.contrastSlider.triggerAction( QAbstractSlider.SliderMove) return def createMosaic(self, value): ''' Function for create Video Mosaic ''' home = os.path.expanduser("~") qgsu.createFolderByName(home, "QGIS_FMV") homefmv = os.path.join(home, "QGIS_FMV") root, _ = os.path.splitext(os.path.basename(self.fileName)) qgsu.createFolderByName(homefmv, root) self.createingMosaic = value # Create Group CreateGroupByName() return def contextMenuBarRequested(self, point): ''' Context Menu Menu Bar ''' menu = QMenu('ToolBars') toolbars = self.findChildren(QToolBar) for toolbar in toolbars: action = menu.addAction(toolbar.windowTitle()) action.setCheckable(True) action.setChecked(toolbar.isVisible()) action.setObjectName(toolbar.windowTitle()) action.triggered.connect(lambda _: self.ToggleQToolBar()) menu.exec_(self.mapToGlobal(point)) return def ToggleQToolBar(self): ''' Toggle ToolBar ''' toolbars = self.findChildren(QToolBar) for toolbar in toolbars: if self.sender().objectName() == toolbar.windowTitle(): toolbar.toggleViewAction().trigger() def contextMenuRequested(self, point): ''' Context Menu Video ''' menu = QMenu('Video') # actionColors = menu.addAction( # QCoreApplication.translate("QgsFmvPlayer", "Color Options")) # actionColors.setShortcut("Ctrl+May+C") # actionColors.triggered.connect(self.showColorDialog) actionMute = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Mute/Unmute")) actionMute.setShortcut("Ctrl+Shift+U") actionMute.triggered.connect(self.setMuted) menu.addSeparator() actionAllFrames = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Extract All Frames")) actionAllFrames.setShortcut("Ctrl+Shift+A") actionAllFrames.triggered.connect(self.ExtractAllFrames) actionCurrentFrames = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Extract Current Frame")) actionCurrentFrames.setShortcut("Ctrl+Shift+Q") actionCurrentFrames.triggered.connect(self.ExtractCurrentFrame) menu.addSeparator() actionShowMetadata = menu.addAction( QCoreApplication.translate("QgsFmvPlayer", "Show Metadata")) actionShowMetadata.setShortcut("Ctrl+Shift+M") actionShowMetadata.triggered.connect(self.OpenQgsFmvMetadata) menu.exec_(self.mapToGlobal(point)) # Start Snnipet FILTERS def grayFilter(self, value): ''' Gray Video Filter ''' self.UncheckFilters(self.sender(), value) self.videoWidget.SetGray(value) self.videoWidget.UpdateSurface() return def MirrorHorizontalFilter(self, value): ''' Mirror Horizontal Video Filter ''' self.UncheckFilters(self.sender(), value) self.videoWidget.SetMirrorH(value) self.videoWidget.UpdateSurface() return def edgeFilter(self, value): ''' Edge Detection Video Filter ''' self.UncheckFilters(self.sender(), value) self.videoWidget.SetEdgeDetection(value) self.videoWidget.UpdateSurface() return def invertColorFilter(self, value): ''' Invert Color Video Filter ''' self.UncheckFilters(self.sender(), value) self.videoWidget.SetInvertColor(value) self.videoWidget.UpdateSurface() return def autoContrastFilter(self, value): ''' Auto Contrast Video Filter ''' self.UncheckFilters(self.sender(), value) self.videoWidget.SetAutoContrastFilter(value) self.videoWidget.UpdateSurface() return def monoFilter(self, value): ''' Filter Mono Video ''' self.UncheckFilters(self.sender(), value) self.videoWidget.SetMonoFilter(value) self.videoWidget.UpdateSurface() return def magnifier(self, value): ''' Magnifier Glass Utils ''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetMagnifier(value) self.videoWidget.UpdateSurface() return def pointDrawer(self, value): ''' Draw Point ''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetPointDrawer(value) self.videoWidget.UpdateSurface() def lineDrawer(self, value): ''' Draw Line ''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetLineDrawer(value) self.videoWidget.UpdateSurface() def polygonDrawer(self, value): ''' Draw Polygon ''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetPolygonDrawer(value) self.videoWidget.UpdateSurface() def ojectTracking(self, value): ''' Object Tracking ''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetObjectTracking(value) self.videoWidget.UpdateSurface() def VideoRuler(self, value): ''' Video Ruler ''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetRuler(value) if value: self.player.pause() self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png")) else: self.videoWidget.ResetDrawRuler() self.player.play() self.btn_play.setIcon(QIcon(":/imgFMV/images/pause.png")) self.videoWidget.UpdateSurface() def VideoCensure(self, value): ''' Censure Video Parts''' self.UncheckUtils(self.sender(), value) self.videoWidget.SetCensure(value) self.videoWidget.UpdateSurface() return def UncheckUtils(self, sender, value): ''' Uncheck Utils Video ''' self.actionMagnifying_glass.setChecked(False) self.actionDraw_Pinpoint.setChecked(False) self.actionDraw_Line.setChecked(False) self.actionDraw_Polygon.setChecked(False) self.actionObject_Tracking.setChecked(False) self.actionRuler.setChecked(False) self.actionCensure.setChecked(False) self.videoWidget.RestoreDrawer() sender.setChecked(value) return def UncheckFilters(self, sender, value): ''' Uncheck Filters Video ''' self.actionGray.setChecked(False) self.actionInvert_Color.setChecked(False) self.actionMono_Filter.setChecked(False) self.actionCanny_edge_detection.setChecked(False) self.actionAuto_Contrast_Filter.setChecked(False) self.actionMirroredH.setChecked(False) self.videoWidget.RestoreFilters() sender.setChecked(value) return # End Snnipet FILTERS def isMuted(self): ''' Is muted video property''' return self.playerMuted def setMuted(self): ''' Muted video ''' if self.player.isMuted(): self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png")) self.player.setMuted(False) self.volumeSlider.setEnabled(True) else: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png")) self.player.setMuted(True) self.volumeSlider.setEnabled(False) return def stop(self): ''' Stop video''' # Prevent Error in a Video Utils.Disable Magnifier if self.actionMagnifying_glass.isChecked(): self.actionMagnifying_glass.trigger() # Stop Video self.fakeStop() return def volume(self): ''' Volume Slider ''' return self.volumeSlider.value() def setVolume(self, volume): ''' Tooltip and set Volume value and icon ''' self.player.setVolume(volume) self.showVolumeTip(volume) if 0 < volume <= 30: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_30.png")) elif 30 < volume <= 60: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_60.png")) elif 60 < volume <= 100: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_up.png")) elif volume == 0: self.btn_volume.setIcon(QIcon(":/imgFMV/images/volume_off.png")) def EndMedia(self): ''' Button end video position ''' if self.player.isVideoAvailable(): self.player.setPosition(self.player.duration()) self.videoWidget.update() return def StartMedia(self): ''' Button start video position ''' if self.player.isVideoAvailable(): self.player.setPosition(0) self.videoWidget.update() return def forwardMedia(self): ''' Button forward Video ''' forwardTime = int(self.player.position()) + 10 * 1000 if forwardTime > int(self.player.duration()): forwardTime = int(self.player.duration()) self.player.setPosition(forwardTime) def rewindMedia(self): ''' Button rewind Video ''' rewindTime = int(self.player.position()) - 10 * 1000 if rewindTime < 0: rewindTime = 0 self.player.setPosition(rewindTime) def AutoRepeat(self, checked): ''' Button AutoRepeat Video ''' if checked: self.playlist.setPlaybackMode(QMediaPlaylist.Loop) else: self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) return def showVolumeTip(self, _): ''' Volume Slider Tooltip Trick ''' self.style = self.volumeSlider.style() self.opt = QStyleOptionSlider() self.volumeSlider.initStyleOption(self.opt) rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt, self.style.SC_SliderHandle) self.tip_offset = QPoint(5, 15) pos_local = rectHandle.topLeft() + self.tip_offset pos_global = self.volumeSlider.mapToGlobal(pos_local) QToolTip.showText(pos_global, str(self.volumeSlider.value()) + " %", self) def showMoveTip(self, currentInfo): ''' Player Silder Move Tooptip Trick ''' self.style = self.sliderDuration.style() self.opt = QStyleOptionSlider() self.sliderDuration.initStyleOption(self.opt) rectHandle = self.style.subControlRect(self.style.CC_Slider, self.opt, self.style.SC_SliderHandle) self.tip_offset = QPoint(5, 15) pos_local = rectHandle.topLeft() + self.tip_offset pos_global = self.sliderDuration.mapToGlobal(pos_local) tStr = _seconds_to_time(currentInfo) QToolTip.showText(pos_global, tStr, self) def durationChanged(self, duration): ''' Duration video change signal ''' duration /= 1000 self.duration = duration self.sliderDuration.setMaximum(duration) def positionChanged(self, progress): ''' Current Video position change ''' progress /= 1000 if not self.sliderDuration.isSliderDown(): self.sliderDuration.setValue(progress) self.updateDurationInfo(progress) def updateDurationInfo(self, currentInfo): ''' Update labels duration Info and CallBack Metadata ''' duration = self.duration self.currentInfo = currentInfo if currentInfo or duration: totalTime = _seconds_to_time(duration) currentTime = _seconds_to_time(currentInfo) tStr = currentTime + " / " + totalTime currentTimeInfo = _seconds_to_time_frac(currentInfo) # Get Metadata from buffer if not self.isStreaming: self.get_metadata_from_buffer(currentTimeInfo) else: qgsu.showUserAndLogMessage("", "Streaming on ", onlyLog=True) nextTime = currentInfo + self.pass_time / 1000 nextTimeInfo = _seconds_to_time_frac(nextTime) self.callBackMetadata(currentTimeInfo, nextTimeInfo) else: tStr = "" self.labelDuration.setText(tStr) def handleCursor(self, status): ''' Change cursor ''' if status in (QMediaPlayer.LoadingMedia, QMediaPlayer.BufferingMedia, QMediaPlayer.StalledMedia): self.setCursor(Qt.BusyCursor) else: self.unsetCursor() def statusChanged(self, status): ''' Signal Status video change ''' self.handleCursor(status) if status is QMediaPlayer.LoadingMedia or status is QMediaPlayer.StalledMedia or status is QMediaPlayer.InvalidMedia: self.videoAvailableChanged(False) elif status == QMediaPlayer.InvalidMedia: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", self.player.errorString()), level=QGis.Warning) self.videoAvailableChanged(False) else: self.videoAvailableChanged(True) def playFile(self, videoPath): ''' Play file from path ''' try: RemoveVideoLayers() RemoveGroupByName() # if "udp://" in videoPath: # host, port = videoPath.split("://")[1].split(":") # receiver = UDPClient(host, int(port), type="udp") # receiver.show() # self.close() # return # if "tcp://" in videoPath: # host, port = videoPath.split("://")[1].split(":") # receiver = UDPClient(host, port, type="tcp") # receiver.show() # self.close() # return self.fileName = videoPath self.playlist = QMediaPlaylist() if self.isStreaming: url = QUrl(videoPath) else: url = QUrl.fromLocalFile(videoPath) qgsu.showUserAndLogMessage("", "Added: " + str(url), onlyLog=True) self.playlist.addMedia(QMediaContent(url)) self.player.setPlaylist(self.playlist) self.setWindowTitle( QCoreApplication.translate("QgsFmvPlayer", 'Playing : ') + os.path.basename(os.path.normpath(videoPath))) CreateVideoLayers() self.clearMetadata() self.HasFileAudio = True if not self.HasAudio(videoPath): self.actionAudio.setEnabled(False) self.actionSave_Audio.setEnabled(False) self.HasFileAudio = False # Recenter map on video initial point if self.initialPt: rect = QgsRectangle(self.initialPt[1], self.initialPt[0], self.initialPt[1], self.initialPt[0]) self.iface.mapCanvas().setExtent(rect) self.iface.mapCanvas().refresh() self.playClicked(True) except Exception as e: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", 'Open Video File : '), str(e), level=QGis.Warning) def ReciconUpdate(self, _): ''' Record Button Icon Effect ''' self.btn_Rec.setIcon(QIcon(self.RecGIF.currentPixmap())) def StopRecordAnimation(self): '''Stop record gif animation''' self.RecGIF.frameChanged.disconnect(self.ReciconUpdate) self.RecGIF.stop() self.btn_Rec.setIcon(QIcon(":/imgFMV/images/record.png")) # TODO: Make in other thread def RecordVideo(self, value): ''' Cut Video ''' currentTime = _seconds_to_time(self.currentInfo) if value is False: self.endRecord = currentTime _, file_extension = os.path.splitext(self.fileName) out, _ = askForFiles(self, QCoreApplication.translate( "QgsFmvPlayer", "Save video record"), isSave=True, exts=file_extension[1:]) if not out: self.StopRecordAnimation() return p = _spawn([ '-i', self.fileName, '-ss', self.startRecord, '-to', self.endRecord, '-preset', 'ultrafast', '-c', 'copy', out ]) p.communicate() qgsu.showUserAndLogMessage( QCoreApplication.translate("QgsFmvPlayer", "Save file succesfully!")) self.StopRecordAnimation() else: self.startRecord = currentTime self.RecGIF.frameChanged.connect(self.ReciconUpdate) self.RecGIF.start() return def videoAvailableChanged(self, available): ''' Buttons for video available ''' # self.btn_Color.setEnabled(available) self.btn_CaptureFrame.setEnabled(available) self.gb_PlayerControls.setEnabled(available) return def toggleGroup(self, state): ''' Toggle GroupBox ''' sender = self.sender() if state: sender.setFixedHeight(sender.sizeHint().height()) else: sender.setFixedHeight(15) def fakeStop(self): '''self.player.stop() make a black screen and not reproduce it again''' self.player.pause() self.StartMedia() self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png")) def playClicked(self, _): ''' Stop and Play video ''' if self.playerState in (QMediaPlayer.StoppedState, QMediaPlayer.PausedState): self.btn_play.setIcon(QIcon(":/imgFMV/images/pause.png")) # Uncheck Ruler self.videoWidget.ResetDrawRuler() self.actionRuler.setChecked(False) self.videoWidget.SetRuler(False) # Play Video self.player.play() elif self.playerState == QMediaPlayer.PlayingState: self.btn_play.setIcon(QIcon(":/imgFMV/images/play-arrow.png")) self.player.pause() def seek(self, seconds): '''Slider Move''' self.player.setPosition(seconds * 1000) self.showMoveTip(seconds) def convertVideo(self): '''Convert Video To Other Format ''' out, _ = askForFiles(self, QCoreApplication.translate( "QgsFmvPlayer", "Save Video as..."), isSave=True, exts=[ "mp4", "ogg", "avi", "mkv", "webm", "flv", "mov", "mpg", "mp3" ]) if not out: return # TODO : Make Correct format Conversion and embebed metadata info = self.converter.probeInfo(self.fileName) if info is not None: if self.HasFileAudio: audio_codec = info.audio.codec audio_samplerate = info.audio.audio_samplerate audio_channels = info.audio.audio_channels video_codec = info.video.codec video_width = info.video.video_width video_height = info.video.video_height video_fps = info.video.video_fps _, out_ext = os.path.splitext(out) if self.HasFileAudio: options = { 'format': out_ext[1:], 'audio': { 'codec': audio_codec, 'samplerate': audio_samplerate, 'channels': audio_channels }, 'video': { 'codec': video_codec, 'width': video_width, 'height': video_height, 'fps': video_fps } } else: options = { 'format': out_ext[1:], 'video': { 'codec': video_codec, 'width': video_width, 'height': video_height, 'fps': video_fps } } taskConvertVideo = QgsTask.fromFunction('Converting Video Task', self.converter.convert, infile=self.fileName, outfile=out, options=options, twopass=False, on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskConvertVideo) def CreateBitratePlot(self): ''' Create video Plot Bitrate Thread ''' sender = self.sender().objectName() if sender == "actionAudio": taskactionAudio = QgsTask.fromFunction( 'Show Audio Bitrate', self.BitratePlot.CreatePlot, fileName=self.fileName, output=None, t='audio', on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskactionAudio) elif sender == "actionVideo": taskactionVideo = QgsTask.fromFunction( 'Show Video Bitrate', self.BitratePlot.CreatePlot, fileName=self.fileName, output=None, t='video', on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskactionVideo) elif sender == "actionSave_Audio": fileaudio, _ = askForFiles(self, QCoreApplication.translate( "QgsFmvPlayer", "Save Audio Bitrate Plot"), isSave=True, exts=[ "png", "pdf", "pgf", "eps", "ps", "raw", "rgba", "svg", "svgz" ]) if not fileaudio: return taskactionSave_Audio = QgsTask.fromFunction( 'Save Action Audio Bitrate', self.BitratePlot.CreatePlot, fileName=self.fileName, output=fileaudio, t='audio', on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskactionSave_Audio) elif sender == "actionSave_Video": filevideo, _ = askForFiles(self, QCoreApplication.translate( "QgsFmvPlayer", "Save Video Bitrate Plot"), isSave=True, exts=[ "png", "pdf", "pgf", "eps", "ps", "raw", "rgba", "svg", "svgz" ]) if not filevideo: return taskactionSave_Video = QgsTask.fromFunction( 'Save Action Video Bitrate', self.BitratePlot.CreatePlot, fileName=self.fileName, output=filevideo, t='video', on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskactionSave_Video) def finishedTask(self, e, result=None): """ Common finish task function """ if e is None: if result is None: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", 'Completed with no exception and no result '\ '(probably manually canceled by the user)'), level=QGis.Warning) else: if "Georeferencing" in result['task']: return qgsu.showUserAndLogMessage( QCoreApplication.translate( "QgsFmvPlayer", "Succesfully " + result['task'] + "!")) if "Bitrate" in result['task']: self.matplot = ShowPlot(self.BitratePlot.bitrate_data, self.BitratePlot.frame_count, self.fileName, self.BitratePlot.output) if result['task'] == 'Show Video Info Task': self.showVideoInfoDialog(self.converter.bytes_value) else: qgsu.showUserAndLogMessage(QCoreApplication.translate( "QgsFmvPlayer", "Failed " + result['task'] + "!"), level=QGis.Warning) raise e def ExtractAllFrames(self): """ Extract All Video Frames Task """ directory = askForFolder( self, QCoreApplication.translate("QgsFmvPlayer", "Save all Frames"), options=QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly) if directory: taskExtractAllFrames = QgsTask.fromFunction( 'Save All Frames Task', self.SaveAllFrames, fileName=self.fileName, directory=directory, on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskExtractAllFrames) return def SaveAllFrames(self, task, fileName, directory): vidcap = cv2.VideoCapture(fileName) length = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT)) count = 0 while not task.isCanceled(): _, image = vidcap.read() cv2.imwrite(directory + "\\frame_%d.jpg" % count, image) # save frame as JPEG file task.setProgress(count * 100 / length) count += 1 vidcap.release() cv2.destroyAllWindows() if task.isCanceled(): return None return {'task': task.description()} def ExtractCurrentFrame(self): """ Extract Current Frame Task """ image = self.videoWidget.GetCurrentFrame() output, _ = askForFiles(self, QCoreApplication.translate( "QgsFmvPlayer", "Save Current Frame"), isSave=True, exts=["png", "jpg", "bmp", "tiff"]) if not output: return taskCurrentFrame = QgsTask.fromFunction('Save Current Frame Task', self.SaveCapture, image=image, output=output, on_finished=self.finishedTask, flags=QgsTask.CanCancel) QgsApplication.taskManager().addTask(taskCurrentFrame) return def SaveCapture(self, task, image, output): ''' Save Current Frame ''' image.save(output) if task.isCanceled(): return None return {'task': task.description()} def OpenQgsFmvMetadata(self): """ Open Metadata Dock """ if self.metadataDlg is None: self.metadataDlg = QgsFmvMetadata(parent=self, player=self) self.addDockWidget(Qt.RightDockWidgetArea, self.metadataDlg) self.metadataDlg.show() else: self.metadataDlg.show() return def showVideoInfoDialog(self, outjson): """ Show Video Information Dialog """ view = QTreeView() model = QJsonModel() view.setModel(model) model.loadJsonFromConsole(outjson) self.VideoInfoDialog = QDialog(self) self.VideoInfoDialog.setWindowTitle( QCoreApplication.translate("QgsFmvPlayer", "Video Information : ") + self.fileName) self.VideoInfoDialog.setWindowIcon( QIcon(":/imgFMV/images/video-info.png")) self.verticalLayout = QVBoxLayout(self.VideoInfoDialog) self.verticalLayout.addWidget(view) view.expandAll() view.header().setSectionResizeMode(QHeaderView.ResizeToContents) self.VideoInfoDialog.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint) self.VideoInfoDialog.setObjectName("VideoInfoDialog") self.VideoInfoDialog.resize(500, 400) self.VideoInfoDialog.show() def closeEvent(self, _): """ Close Event """ self.stop() self.parent._PlayerDlg = None self.parent.ToggleActiveFromTitle() RemoveVideoLayers() RemoveGroupByName() ResetData() try: self.metadataDlg.hide() except Exception: None try: self.matplot.close() except Exception: None # Restore Filters State self.videoWidget.RestoreFilters()
class 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 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